Back to home page

LXR

 
 

    


0001 /*
0002  * PRNG: Pseudo Random Number Generator
0003  *       Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using
0004  *       AES 128 cipher
0005  *
0006  *  (C) Neil Horman <nhorman@tuxdriver.com>
0007  *
0008  *  This program is free software; you can redistribute it and/or modify it
0009  *  under the terms of the GNU General Public License as published by the
0010  *  Free Software Foundation; either version 2 of the License, or (at your
0011  *  any later version.
0012  *
0013  *
0014  */
0015 
0016 #include <crypto/internal/rng.h>
0017 #include <linux/err.h>
0018 #include <linux/init.h>
0019 #include <linux/module.h>
0020 #include <linux/moduleparam.h>
0021 #include <linux/string.h>
0022 
0023 #define DEFAULT_PRNG_KEY "0123456789abcdef"
0024 #define DEFAULT_PRNG_KSZ 16
0025 #define DEFAULT_BLK_SZ 16
0026 #define DEFAULT_V_SEED "zaybxcwdveuftgsh"
0027 
0028 /*
0029  * Flags for the prng_context flags field
0030  */
0031 
0032 #define PRNG_FIXED_SIZE 0x1
0033 #define PRNG_NEED_RESET 0x2
0034 
0035 /*
0036  * Note: DT is our counter value
0037  *   I is our intermediate value
0038  *   V is our seed vector
0039  * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
0040  * for implementation details
0041  */
0042 
0043 
0044 struct prng_context {
0045     spinlock_t prng_lock;
0046     unsigned char rand_data[DEFAULT_BLK_SZ];
0047     unsigned char last_rand_data[DEFAULT_BLK_SZ];
0048     unsigned char DT[DEFAULT_BLK_SZ];
0049     unsigned char I[DEFAULT_BLK_SZ];
0050     unsigned char V[DEFAULT_BLK_SZ];
0051     u32 rand_data_valid;
0052     struct crypto_cipher *tfm;
0053     u32 flags;
0054 };
0055 
0056 static int dbg;
0057 
0058 static void hexdump(char *note, unsigned char *buf, unsigned int len)
0059 {
0060     if (dbg) {
0061         printk(KERN_CRIT "%s", note);
0062         print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
0063                 16, 1,
0064                 buf, len, false);
0065     }
0066 }
0067 
0068 #define dbgprint(format, args...) do {\
0069 if (dbg)\
0070     printk(format, ##args);\
0071 } while (0)
0072 
0073 static void xor_vectors(unsigned char *in1, unsigned char *in2,
0074             unsigned char *out, unsigned int size)
0075 {
0076     int i;
0077 
0078     for (i = 0; i < size; i++)
0079         out[i] = in1[i] ^ in2[i];
0080 
0081 }
0082 /*
0083  * Returns DEFAULT_BLK_SZ bytes of random data per call
0084  * returns 0 if generation succeeded, <0 if something went wrong
0085  */
0086 static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
0087 {
0088     int i;
0089     unsigned char tmp[DEFAULT_BLK_SZ];
0090     unsigned char *output = NULL;
0091 
0092 
0093     dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
0094         ctx);
0095 
0096     hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ);
0097     hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ);
0098     hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ);
0099 
0100     /*
0101      * This algorithm is a 3 stage state machine
0102      */
0103     for (i = 0; i < 3; i++) {
0104 
0105         switch (i) {
0106         case 0:
0107             /*
0108              * Start by encrypting the counter value
0109              * This gives us an intermediate value I
0110              */
0111             memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ);
0112             output = ctx->I;
0113             hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ);
0114             break;
0115         case 1:
0116 
0117             /*
0118              * Next xor I with our secret vector V
0119              * encrypt that result to obtain our
0120              * pseudo random data which we output
0121              */
0122             xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ);
0123             hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ);
0124             output = ctx->rand_data;
0125             break;
0126         case 2:
0127             /*
0128              * First check that we didn't produce the same
0129              * random data that we did last time around through this
0130              */
0131             if (!memcmp(ctx->rand_data, ctx->last_rand_data,
0132                     DEFAULT_BLK_SZ)) {
0133                 if (cont_test) {
0134                     panic("cprng %p Failed repetition check!\n",
0135                         ctx);
0136                 }
0137 
0138                 printk(KERN_ERR
0139                     "ctx %p Failed repetition check!\n",
0140                     ctx);
0141 
0142                 ctx->flags |= PRNG_NEED_RESET;
0143                 return -EINVAL;
0144             }
0145             memcpy(ctx->last_rand_data, ctx->rand_data,
0146                 DEFAULT_BLK_SZ);
0147 
0148             /*
0149              * Lastly xor the random data with I
0150              * and encrypt that to obtain a new secret vector V
0151              */
0152             xor_vectors(ctx->rand_data, ctx->I, tmp,
0153                 DEFAULT_BLK_SZ);
0154             output = ctx->V;
0155             hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ);
0156             break;
0157         }
0158 
0159 
0160         /* do the encryption */
0161         crypto_cipher_encrypt_one(ctx->tfm, output, tmp);
0162 
0163     }
0164 
0165     /*
0166      * Now update our DT value
0167      */
0168     for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
0169         ctx->DT[i] += 1;
0170         if (ctx->DT[i] != 0)
0171             break;
0172     }
0173 
0174     dbgprint("Returning new block for context %p\n", ctx);
0175     ctx->rand_data_valid = 0;
0176 
0177     hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ);
0178     hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ);
0179     hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ);
0180     hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ);
0181 
0182     return 0;
0183 }
0184 
0185 /* Our exported functions */
0186 static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
0187                 int do_cont_test)
0188 {
0189     unsigned char *ptr = buf;
0190     unsigned int byte_count = (unsigned int)nbytes;
0191     int err;
0192 
0193 
0194     spin_lock_bh(&ctx->prng_lock);
0195 
0196     err = -EINVAL;
0197     if (ctx->flags & PRNG_NEED_RESET)
0198         goto done;
0199 
0200     /*
0201      * If the FIXED_SIZE flag is on, only return whole blocks of
0202      * pseudo random data
0203      */
0204     err = -EINVAL;
0205     if (ctx->flags & PRNG_FIXED_SIZE) {
0206         if (nbytes < DEFAULT_BLK_SZ)
0207             goto done;
0208         byte_count = DEFAULT_BLK_SZ;
0209     }
0210 
0211     /*
0212      * Return 0 in case of success as mandated by the kernel
0213      * crypto API interface definition.
0214      */
0215     err = 0;
0216 
0217     dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",
0218         byte_count, ctx);
0219 
0220 
0221 remainder:
0222     if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
0223         if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
0224             memset(buf, 0, nbytes);
0225             err = -EINVAL;
0226             goto done;
0227         }
0228     }
0229 
0230     /*
0231      * Copy any data less than an entire block
0232      */
0233     if (byte_count < DEFAULT_BLK_SZ) {
0234 empty_rbuf:
0235         while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
0236             *ptr = ctx->rand_data[ctx->rand_data_valid];
0237             ptr++;
0238             byte_count--;
0239             ctx->rand_data_valid++;
0240             if (byte_count == 0)
0241                 goto done;
0242         }
0243     }
0244 
0245     /*
0246      * Now copy whole blocks
0247      */
0248     for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
0249         if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
0250             if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
0251                 memset(buf, 0, nbytes);
0252                 err = -EINVAL;
0253                 goto done;
0254             }
0255         }
0256         if (ctx->rand_data_valid > 0)
0257             goto empty_rbuf;
0258         memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
0259         ctx->rand_data_valid += DEFAULT_BLK_SZ;
0260         ptr += DEFAULT_BLK_SZ;
0261     }
0262 
0263     /*
0264      * Now go back and get any remaining partial block
0265      */
0266     if (byte_count)
0267         goto remainder;
0268 
0269 done:
0270     spin_unlock_bh(&ctx->prng_lock);
0271     dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
0272         err, ctx);
0273     return err;
0274 }
0275 
0276 static void free_prng_context(struct prng_context *ctx)
0277 {
0278     crypto_free_cipher(ctx->tfm);
0279 }
0280 
0281 static int reset_prng_context(struct prng_context *ctx,
0282                   const unsigned char *key, size_t klen,
0283                   const unsigned char *V, const unsigned char *DT)
0284 {
0285     int ret;
0286     const unsigned char *prng_key;
0287 
0288     spin_lock_bh(&ctx->prng_lock);
0289     ctx->flags |= PRNG_NEED_RESET;
0290 
0291     prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
0292 
0293     if (!key)
0294         klen = DEFAULT_PRNG_KSZ;
0295 
0296     if (V)
0297         memcpy(ctx->V, V, DEFAULT_BLK_SZ);
0298     else
0299         memcpy(ctx->V, DEFAULT_V_SEED, DEFAULT_BLK_SZ);
0300 
0301     if (DT)
0302         memcpy(ctx->DT, DT, DEFAULT_BLK_SZ);
0303     else
0304         memset(ctx->DT, 0, DEFAULT_BLK_SZ);
0305 
0306     memset(ctx->rand_data, 0, DEFAULT_BLK_SZ);
0307     memset(ctx->last_rand_data, 0, DEFAULT_BLK_SZ);
0308 
0309     ctx->rand_data_valid = DEFAULT_BLK_SZ;
0310 
0311     ret = crypto_cipher_setkey(ctx->tfm, prng_key, klen);
0312     if (ret) {
0313         dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n",
0314             crypto_cipher_get_flags(ctx->tfm));
0315         goto out;
0316     }
0317 
0318     ret = 0;
0319     ctx->flags &= ~PRNG_NEED_RESET;
0320 out:
0321     spin_unlock_bh(&ctx->prng_lock);
0322     return ret;
0323 }
0324 
0325 static int cprng_init(struct crypto_tfm *tfm)
0326 {
0327     struct prng_context *ctx = crypto_tfm_ctx(tfm);
0328 
0329     spin_lock_init(&ctx->prng_lock);
0330     ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
0331     if (IS_ERR(ctx->tfm)) {
0332         dbgprint(KERN_CRIT "Failed to alloc tfm for context %p\n",
0333                 ctx);
0334         return PTR_ERR(ctx->tfm);
0335     }
0336 
0337     if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0)
0338         return -EINVAL;
0339 
0340     /*
0341      * after allocation, we should always force the user to reset
0342      * so they don't inadvertently use the insecure default values
0343      * without specifying them intentially
0344      */
0345     ctx->flags |= PRNG_NEED_RESET;
0346     return 0;
0347 }
0348 
0349 static void cprng_exit(struct crypto_tfm *tfm)
0350 {
0351     free_prng_context(crypto_tfm_ctx(tfm));
0352 }
0353 
0354 static int cprng_get_random(struct crypto_rng *tfm,
0355                 const u8 *src, unsigned int slen,
0356                 u8 *rdata, unsigned int dlen)
0357 {
0358     struct prng_context *prng = crypto_rng_ctx(tfm);
0359 
0360     return get_prng_bytes(rdata, dlen, prng, 0);
0361 }
0362 
0363 /*
0364  *  This is the cprng_registered reset method the seed value is
0365  *  interpreted as the tuple { V KEY DT}
0366  *  V and KEY are required during reset, and DT is optional, detected
0367  *  as being present by testing the length of the seed
0368  */
0369 static int cprng_reset(struct crypto_rng *tfm,
0370                const u8 *seed, unsigned int slen)
0371 {
0372     struct prng_context *prng = crypto_rng_ctx(tfm);
0373     const u8 *key = seed + DEFAULT_BLK_SZ;
0374     const u8 *dt = NULL;
0375 
0376     if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
0377         return -EINVAL;
0378 
0379     if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ))
0380         dt = key + DEFAULT_PRNG_KSZ;
0381 
0382     reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, dt);
0383 
0384     if (prng->flags & PRNG_NEED_RESET)
0385         return -EINVAL;
0386     return 0;
0387 }
0388 
0389 #ifdef CONFIG_CRYPTO_FIPS
0390 static int fips_cprng_get_random(struct crypto_rng *tfm,
0391                  const u8 *src, unsigned int slen,
0392                  u8 *rdata, unsigned int dlen)
0393 {
0394     struct prng_context *prng = crypto_rng_ctx(tfm);
0395 
0396     return get_prng_bytes(rdata, dlen, prng, 1);
0397 }
0398 
0399 static int fips_cprng_reset(struct crypto_rng *tfm,
0400                 const u8 *seed, unsigned int slen)
0401 {
0402     u8 rdata[DEFAULT_BLK_SZ];
0403     const u8 *key = seed + DEFAULT_BLK_SZ;
0404     int rc;
0405 
0406     struct prng_context *prng = crypto_rng_ctx(tfm);
0407 
0408     if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
0409         return -EINVAL;
0410 
0411     /* fips strictly requires seed != key */
0412     if (!memcmp(seed, key, DEFAULT_PRNG_KSZ))
0413         return -EINVAL;
0414 
0415     rc = cprng_reset(tfm, seed, slen);
0416 
0417     if (!rc)
0418         goto out;
0419 
0420     /* this primes our continuity test */
0421     rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
0422     prng->rand_data_valid = DEFAULT_BLK_SZ;
0423 
0424 out:
0425     return rc;
0426 }
0427 #endif
0428 
0429 static struct rng_alg rng_algs[] = { {
0430     .generate       = cprng_get_random,
0431     .seed           = cprng_reset,
0432     .seedsize       = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
0433     .base           =   {
0434         .cra_name       = "stdrng",
0435         .cra_driver_name    = "ansi_cprng",
0436         .cra_priority       = 100,
0437         .cra_ctxsize        = sizeof(struct prng_context),
0438         .cra_module     = THIS_MODULE,
0439         .cra_init       = cprng_init,
0440         .cra_exit       = cprng_exit,
0441     }
0442 #ifdef CONFIG_CRYPTO_FIPS
0443 }, {
0444     .generate       = fips_cprng_get_random,
0445     .seed           = fips_cprng_reset,
0446     .seedsize       = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ,
0447     .base           =   {
0448         .cra_name       = "fips(ansi_cprng)",
0449         .cra_driver_name    = "fips_ansi_cprng",
0450         .cra_priority       = 300,
0451         .cra_ctxsize        = sizeof(struct prng_context),
0452         .cra_module     = THIS_MODULE,
0453         .cra_init       = cprng_init,
0454         .cra_exit       = cprng_exit,
0455     }
0456 #endif
0457 } };
0458 
0459 /* Module initalization */
0460 static int __init prng_mod_init(void)
0461 {
0462     return crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs));
0463 }
0464 
0465 static void __exit prng_mod_fini(void)
0466 {
0467     crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs));
0468 }
0469 
0470 MODULE_LICENSE("GPL");
0471 MODULE_DESCRIPTION("Software Pseudo Random Number Generator");
0472 MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
0473 module_param(dbg, int, 0);
0474 MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)");
0475 module_init(prng_mod_init);
0476 module_exit(prng_mod_fini);
0477 MODULE_ALIAS_CRYPTO("stdrng");
0478 MODULE_ALIAS_CRYPTO("ansi_cprng");