0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <crypto/internal/cipher.h>
0011 #include <crypto/internal/rng.h>
0012 #include <linux/err.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/moduleparam.h>
0016 #include <linux/string.h>
0017
0018 #define DEFAULT_PRNG_KEY "0123456789abcdef"
0019 #define DEFAULT_PRNG_KSZ 16
0020 #define DEFAULT_BLK_SZ 16
0021 #define DEFAULT_V_SEED "zaybxcwdveuftgsh"
0022
0023
0024
0025
0026
0027 #define PRNG_FIXED_SIZE 0x1
0028 #define PRNG_NEED_RESET 0x2
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 struct prng_context {
0040 spinlock_t prng_lock;
0041 unsigned char rand_data[DEFAULT_BLK_SZ];
0042 unsigned char last_rand_data[DEFAULT_BLK_SZ];
0043 unsigned char DT[DEFAULT_BLK_SZ];
0044 unsigned char I[DEFAULT_BLK_SZ];
0045 unsigned char V[DEFAULT_BLK_SZ];
0046 u32 rand_data_valid;
0047 struct crypto_cipher *tfm;
0048 u32 flags;
0049 };
0050
0051 static int dbg;
0052
0053 static void hexdump(char *note, unsigned char *buf, unsigned int len)
0054 {
0055 if (dbg) {
0056 printk(KERN_CRIT "%s", note);
0057 print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
0058 16, 1,
0059 buf, len, false);
0060 }
0061 }
0062
0063 #define dbgprint(format, args...) do {\
0064 if (dbg)\
0065 printk(format, ##args);\
0066 } while (0)
0067
0068 static void xor_vectors(unsigned char *in1, unsigned char *in2,
0069 unsigned char *out, unsigned int size)
0070 {
0071 int i;
0072
0073 for (i = 0; i < size; i++)
0074 out[i] = in1[i] ^ in2[i];
0075
0076 }
0077
0078
0079
0080
0081 static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
0082 {
0083 int i;
0084 unsigned char tmp[DEFAULT_BLK_SZ];
0085 unsigned char *output = NULL;
0086
0087
0088 dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
0089 ctx);
0090
0091 hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ);
0092 hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ);
0093 hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ);
0094
0095
0096
0097
0098 for (i = 0; i < 3; i++) {
0099
0100 switch (i) {
0101 case 0:
0102
0103
0104
0105
0106 memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ);
0107 output = ctx->I;
0108 hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ);
0109 break;
0110 case 1:
0111
0112
0113
0114
0115
0116
0117 xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ);
0118 hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ);
0119 output = ctx->rand_data;
0120 break;
0121 case 2:
0122
0123
0124
0125
0126 if (!memcmp(ctx->rand_data, ctx->last_rand_data,
0127 DEFAULT_BLK_SZ)) {
0128 if (cont_test) {
0129 panic("cprng %p Failed repetition check!\n",
0130 ctx);
0131 }
0132
0133 printk(KERN_ERR
0134 "ctx %p Failed repetition check!\n",
0135 ctx);
0136
0137 ctx->flags |= PRNG_NEED_RESET;
0138 return -EINVAL;
0139 }
0140 memcpy(ctx->last_rand_data, ctx->rand_data,
0141 DEFAULT_BLK_SZ);
0142
0143
0144
0145
0146
0147 xor_vectors(ctx->rand_data, ctx->I, tmp,
0148 DEFAULT_BLK_SZ);
0149 output = ctx->V;
0150 hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ);
0151 break;
0152 }
0153
0154
0155
0156 crypto_cipher_encrypt_one(ctx->tfm, output, tmp);
0157
0158 }
0159
0160
0161
0162
0163 for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
0164 ctx->DT[i] += 1;
0165 if (ctx->DT[i] != 0)
0166 break;
0167 }
0168
0169 dbgprint("Returning new block for context %p\n", ctx);
0170 ctx->rand_data_valid = 0;
0171
0172 hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ);
0173 hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ);
0174 hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ);
0175 hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ);
0176
0177 return 0;
0178 }
0179
0180
0181 static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
0182 int do_cont_test)
0183 {
0184 unsigned char *ptr = buf;
0185 unsigned int byte_count = (unsigned int)nbytes;
0186 int err;
0187
0188
0189 spin_lock_bh(&ctx->prng_lock);
0190
0191 err = -EINVAL;
0192 if (ctx->flags & PRNG_NEED_RESET)
0193 goto done;
0194
0195
0196
0197
0198
0199 err = -EINVAL;
0200 if (ctx->flags & PRNG_FIXED_SIZE) {
0201 if (nbytes < DEFAULT_BLK_SZ)
0202 goto done;
0203 byte_count = DEFAULT_BLK_SZ;
0204 }
0205
0206
0207
0208
0209
0210 err = 0;
0211
0212 dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",
0213 byte_count, ctx);
0214
0215
0216 remainder:
0217 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
0218 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
0219 memset(buf, 0, nbytes);
0220 err = -EINVAL;
0221 goto done;
0222 }
0223 }
0224
0225
0226
0227
0228 if (byte_count < DEFAULT_BLK_SZ) {
0229 empty_rbuf:
0230 while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
0231 *ptr = ctx->rand_data[ctx->rand_data_valid];
0232 ptr++;
0233 byte_count--;
0234 ctx->rand_data_valid++;
0235 if (byte_count == 0)
0236 goto done;
0237 }
0238 }
0239
0240
0241
0242
0243 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
0244 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
0245 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
0246 memset(buf, 0, nbytes);
0247 err = -EINVAL;
0248 goto done;
0249 }
0250 }
0251 if (ctx->rand_data_valid > 0)
0252 goto empty_rbuf;
0253 memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
0254 ctx->rand_data_valid += DEFAULT_BLK_SZ;
0255 ptr += DEFAULT_BLK_SZ;
0256 }
0257
0258
0259
0260
0261 if (byte_count)
0262 goto remainder;
0263
0264 done:
0265 spin_unlock_bh(&ctx->prng_lock);
0266 dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
0267 err, ctx);
0268 return err;
0269 }
0270
0271 static void free_prng_context(struct prng_context *ctx)
0272 {
0273 crypto_free_cipher(ctx->tfm);
0274 }
0275
0276 static int reset_prng_context(struct prng_context *ctx,
0277 const unsigned char *key, size_t klen,
0278 const unsigned char *V, const unsigned char *DT)
0279 {
0280 int ret;
0281 const unsigned char *prng_key;
0282
0283 spin_lock_bh(&ctx->prng_lock);
0284 ctx->flags |= PRNG_NEED_RESET;
0285
0286 prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
0287
0288 if (!key)
0289 klen = DEFAULT_PRNG_KSZ;
0290
0291 if (V)
0292 memcpy(ctx->V, V, DEFAULT_BLK_SZ);
0293 else
0294 memcpy(ctx->V, DEFAULT_V_SEED, DEFAULT_BLK_SZ);
0295
0296 if (DT)
0297 memcpy(ctx->DT, DT, DEFAULT_BLK_SZ);
0298 else
0299 memset(ctx->DT, 0, DEFAULT_BLK_SZ);
0300
0301 memset(ctx->rand_data, 0, DEFAULT_BLK_SZ);
0302 memset(ctx->last_rand_data, 0, DEFAULT_BLK_SZ);
0303
0304 ctx->rand_data_valid = DEFAULT_BLK_SZ;
0305
0306 ret = crypto_cipher_setkey(ctx->tfm, prng_key, klen);
0307 if (ret) {
0308 dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n",
0309 crypto_cipher_get_flags(ctx->tfm));
0310 goto out;
0311 }
0312
0313 ret = 0;
0314 ctx->flags &= ~PRNG_NEED_RESET;
0315 out:
0316 spin_unlock_bh(&ctx->prng_lock);
0317 return ret;
0318 }
0319
0320 static int cprng_init(struct crypto_tfm *tfm)
0321 {
0322 struct prng_context *ctx = crypto_tfm_ctx(tfm);
0323
0324 spin_lock_init(&ctx->prng_lock);
0325 ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
0326 if (IS_ERR(ctx->tfm)) {
0327 dbgprint(KERN_CRIT "Failed to alloc tfm for context %p\n",
0328 ctx);
0329 return PTR_ERR(ctx->tfm);
0330 }
0331
0332 if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0)
0333 return -EINVAL;
0334
0335
0336
0337
0338
0339
0340 ctx->flags |= PRNG_NEED_RESET;
0341 return 0;
0342 }
0343
0344 static void cprng_exit(struct crypto_tfm *tfm)
0345 {
0346 free_prng_context(crypto_tfm_ctx(tfm));
0347 }
0348
0349 static int cprng_get_random(struct crypto_rng *tfm,
0350 const u8 *src, unsigned int slen,
0351 u8 *rdata, unsigned int dlen)
0352 {
0353 struct prng_context *prng = crypto_rng_ctx(tfm);
0354
0355 return get_prng_bytes(rdata, dlen, prng, 0);
0356 }
0357
0358
0359
0360
0361
0362
0363
0364 static int cprng_reset(struct crypto_rng *tfm,
0365 const u8 *seed, unsigned int slen)
0366 {
0367 struct prng_context *prng = crypto_rng_ctx(tfm);
0368 const u8 *key = seed + DEFAULT_BLK_SZ;
0369 const u8 *dt = NULL;
0370
0371 if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
0372 return -EINVAL;
0373
0374 if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ))
0375 dt = key + DEFAULT_PRNG_KSZ;
0376
0377 reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, dt);
0378
0379 if (prng->flags & PRNG_NEED_RESET)
0380 return -EINVAL;
0381 return 0;
0382 }
0383
0384 #ifdef CONFIG_CRYPTO_FIPS
0385 static int fips_cprng_get_random(struct crypto_rng *tfm,
0386 const u8 *src, unsigned int slen,
0387 u8 *rdata, unsigned int dlen)
0388 {
0389 struct prng_context *prng = crypto_rng_ctx(tfm);
0390
0391 return get_prng_bytes(rdata, dlen, prng, 1);
0392 }
0393
0394 static int fips_cprng_reset(struct crypto_rng *tfm,
0395 const u8 *seed, unsigned int slen)
0396 {
0397 u8 rdata[DEFAULT_BLK_SZ];
0398 const u8 *key = seed + DEFAULT_BLK_SZ;
0399 int rc;
0400
0401 struct prng_context *prng = crypto_rng_ctx(tfm);
0402
0403 if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
0404 return -EINVAL;
0405
0406
0407 if (!memcmp(seed, key, DEFAULT_PRNG_KSZ))
0408 return -EINVAL;
0409
0410 rc = cprng_reset(tfm, seed, slen);
0411
0412 if (!rc)
0413 goto out;
0414
0415
0416 rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
0417 prng->rand_data_valid = DEFAULT_BLK_SZ;
0418
0419 out:
0420 return rc;
0421 }
0422 #endif
0423
0424 static struct rng_alg rng_algs[] = { {
0425 .generate = cprng_get_random,
0426 .seed = cprng_reset,
0427 .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
0428 .base = {
0429 .cra_name = "stdrng",
0430 .cra_driver_name = "ansi_cprng",
0431 .cra_priority = 100,
0432 .cra_ctxsize = sizeof(struct prng_context),
0433 .cra_module = THIS_MODULE,
0434 .cra_init = cprng_init,
0435 .cra_exit = cprng_exit,
0436 }
0437 #ifdef CONFIG_CRYPTO_FIPS
0438 }, {
0439 .generate = fips_cprng_get_random,
0440 .seed = fips_cprng_reset,
0441 .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
0442 .base = {
0443 .cra_name = "fips(ansi_cprng)",
0444 .cra_driver_name = "fips_ansi_cprng",
0445 .cra_priority = 300,
0446 .cra_ctxsize = sizeof(struct prng_context),
0447 .cra_module = THIS_MODULE,
0448 .cra_init = cprng_init,
0449 .cra_exit = cprng_exit,
0450 }
0451 #endif
0452 } };
0453
0454
0455 static int __init prng_mod_init(void)
0456 {
0457 return crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs));
0458 }
0459
0460 static void __exit prng_mod_fini(void)
0461 {
0462 crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs));
0463 }
0464
0465 MODULE_LICENSE("GPL");
0466 MODULE_DESCRIPTION("Software Pseudo Random Number Generator");
0467 MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
0468 module_param(dbg, int, 0);
0469 MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)");
0470 subsys_initcall(prng_mod_init);
0471 module_exit(prng_mod_fini);
0472 MODULE_ALIAS_CRYPTO("stdrng");
0473 MODULE_ALIAS_CRYPTO("ansi_cprng");
0474 MODULE_IMPORT_NS(CRYPTO_INTERNAL);