^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PRNG: Pseudo Random Number Generator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * AES 128 cipher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (C) Neil Horman <nhorman@tuxdriver.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <crypto/internal/cipher.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <crypto/internal/rng.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define DEFAULT_PRNG_KEY "0123456789abcdef"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define DEFAULT_PRNG_KSZ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DEFAULT_BLK_SZ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DEFAULT_V_SEED "zaybxcwdveuftgsh"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Flags for the prng_context flags field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PRNG_FIXED_SIZE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PRNG_NEED_RESET 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Note: DT is our counter value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * I is our intermediate value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * V is our seed vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * for implementation details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct prng_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) spinlock_t prng_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned char rand_data[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned char last_rand_data[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned char DT[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned char I[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char V[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u32 rand_data_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct crypto_cipher *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int dbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void hexdump(char *note, unsigned char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (dbg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) printk(KERN_CRIT "%s", note);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) buf, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define dbgprint(format, args...) do {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (dbg)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) printk(format, ##args);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void xor_vectors(unsigned char *in1, unsigned char *in2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned char *out, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) out[i] = in1[i] ^ in2[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Returns DEFAULT_BLK_SZ bytes of random data per call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * returns 0 if generation succeeded, <0 if something went wrong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned char tmp[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned char *output = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * This algorithm is a 3 stage state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Start by encrypting the counter value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * This gives us an intermediate value I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) output = ctx->I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Next xor I with our secret vector V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * encrypt that result to obtain our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * pseudo random data which we output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) output = ctx->rand_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * First check that we didn't produce the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * random data that we did last time around through this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!memcmp(ctx->rand_data, ctx->last_rand_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) DEFAULT_BLK_SZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (cont_test) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) panic("cprng %p Failed repetition check!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "ctx %p Failed repetition check!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ctx->flags |= PRNG_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) memcpy(ctx->last_rand_data, ctx->rand_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Lastly xor the random data with I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * and encrypt that to obtain a new secret vector V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) xor_vectors(ctx->rand_data, ctx->I, tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) output = ctx->V;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* do the encryption */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) crypto_cipher_encrypt_one(ctx->tfm, output, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Now update our DT value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ctx->DT[i] += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ctx->DT[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dbgprint("Returning new block for context %p\n", ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ctx->rand_data_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Our exported functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int do_cont_test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned char *ptr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int byte_count = (unsigned int)nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) spin_lock_bh(&ctx->prng_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (ctx->flags & PRNG_NEED_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * If the FIXED_SIZE flag is on, only return whole blocks of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * pseudo random data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (ctx->flags & PRNG_FIXED_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (nbytes < DEFAULT_BLK_SZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) byte_count = DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Return 0 in case of success as mandated by the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * crypto API interface definition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) byte_count, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) remainder:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) memset(buf, 0, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Copy any data less than an entire block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (byte_count < DEFAULT_BLK_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) empty_rbuf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *ptr = ctx->rand_data[ctx->rand_data_valid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) byte_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ctx->rand_data_valid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (byte_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Now copy whole blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) memset(buf, 0, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ctx->rand_data_valid > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) goto empty_rbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ctx->rand_data_valid += DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ptr += DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Now go back and get any remaining partial block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (byte_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) spin_unlock_bh(&ctx->prng_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) err, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void free_prng_context(struct prng_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) crypto_free_cipher(ctx->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int reset_prng_context(struct prng_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) const unsigned char *key, size_t klen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) const unsigned char *V, const unsigned char *DT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) const unsigned char *prng_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) spin_lock_bh(&ctx->prng_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ctx->flags |= PRNG_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) klen = DEFAULT_PRNG_KSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) memcpy(ctx->V, V, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) memcpy(ctx->V, DEFAULT_V_SEED, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (DT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) memcpy(ctx->DT, DT, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) memset(ctx->DT, 0, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) memset(ctx->rand_data, 0, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) memset(ctx->last_rand_data, 0, DEFAULT_BLK_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ctx->rand_data_valid = DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = crypto_cipher_setkey(ctx->tfm, prng_key, klen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) crypto_cipher_get_flags(ctx->tfm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ctx->flags &= ~PRNG_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) spin_unlock_bh(&ctx->prng_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int cprng_init(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct prng_context *ctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) spin_lock_init(&ctx->prng_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (IS_ERR(ctx->tfm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dbgprint(KERN_CRIT "Failed to alloc tfm for context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return PTR_ERR(ctx->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * after allocation, we should always force the user to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * so they don't inadvertently use the insecure default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * without specifying them intentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ctx->flags |= PRNG_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void cprng_exit(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) free_prng_context(crypto_tfm_ctx(tfm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int cprng_get_random(struct crypto_rng *tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) const u8 *src, unsigned int slen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) u8 *rdata, unsigned int dlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct prng_context *prng = crypto_rng_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return get_prng_bytes(rdata, dlen, prng, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * This is the cprng_registered reset method the seed value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * interpreted as the tuple { V KEY DT}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * V and KEY are required during reset, and DT is optional, detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * as being present by testing the length of the seed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int cprng_reset(struct crypto_rng *tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) const u8 *seed, unsigned int slen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct prng_context *prng = crypto_rng_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) const u8 *key = seed + DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) const u8 *dt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dt = key + DEFAULT_PRNG_KSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (prng->flags & PRNG_NEED_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #ifdef CONFIG_CRYPTO_FIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int fips_cprng_get_random(struct crypto_rng *tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) const u8 *src, unsigned int slen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u8 *rdata, unsigned int dlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct prng_context *prng = crypto_rng_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return get_prng_bytes(rdata, dlen, prng, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int fips_cprng_reset(struct crypto_rng *tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) const u8 *seed, unsigned int slen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u8 rdata[DEFAULT_BLK_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) const u8 *key = seed + DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct prng_context *prng = crypto_rng_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* fips strictly requires seed != key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!memcmp(seed, key, DEFAULT_PRNG_KSZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) rc = cprng_reset(tfm, seed, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* this primes our continuity test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) prng->rand_data_valid = DEFAULT_BLK_SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static struct rng_alg rng_algs[] = { {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .generate = cprng_get_random,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .seed = cprng_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .cra_name = "stdrng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .cra_driver_name = "ansi_cprng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .cra_ctxsize = sizeof(struct prng_context),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .cra_init = cprng_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .cra_exit = cprng_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #ifdef CONFIG_CRYPTO_FIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .generate = fips_cprng_get_random,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .seed = fips_cprng_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .cra_name = "fips(ansi_cprng)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .cra_driver_name = "fips_ansi_cprng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .cra_priority = 300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .cra_ctxsize = sizeof(struct prng_context),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .cra_init = cprng_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .cra_exit = cprng_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Module initalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int __init prng_mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void __exit prng_mod_fini(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) MODULE_DESCRIPTION("Software Pseudo Random Number Generator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) module_param(dbg, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) subsys_initcall(prng_mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) module_exit(prng_mod_fini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) MODULE_ALIAS_CRYPTO("stdrng");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) MODULE_ALIAS_CRYPTO("ansi_cprng");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MODULE_IMPORT_NS(CRYPTO_INTERNAL);