aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/ansi_cprng.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/ansi_cprng.c')
-rw-r--r--crypto/ansi_cprng.c79
1 files changed, 70 insertions, 9 deletions
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 3aa6e3834bf..027176a0e88 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -85,7 +85,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2,
85 * Returns DEFAULT_BLK_SZ bytes of random data per call 85 * Returns DEFAULT_BLK_SZ bytes of random data per call
86 * returns 0 if generation succeded, <0 if something went wrong 86 * returns 0 if generation succeded, <0 if something went wrong
87 */ 87 */
88static int _get_more_prng_bytes(struct prng_context *ctx) 88static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
89{ 89{
90 int i; 90 int i;
91 unsigned char tmp[DEFAULT_BLK_SZ]; 91 unsigned char tmp[DEFAULT_BLK_SZ];
@@ -132,7 +132,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
132 */ 132 */
133 if (!memcmp(ctx->rand_data, ctx->last_rand_data, 133 if (!memcmp(ctx->rand_data, ctx->last_rand_data,
134 DEFAULT_BLK_SZ)) { 134 DEFAULT_BLK_SZ)) {
135 if (fips_enabled) { 135 if (cont_test) {
136 panic("cprng %p Failed repetition check!\n", 136 panic("cprng %p Failed repetition check!\n",
137 ctx); 137 ctx);
138 } 138 }
@@ -185,7 +185,8 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
185} 185}
186 186
187/* Our exported functions */ 187/* Our exported functions */
188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) 188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
189 int do_cont_test)
189{ 190{
190 unsigned char *ptr = buf; 191 unsigned char *ptr = buf;
191 unsigned int byte_count = (unsigned int)nbytes; 192 unsigned int byte_count = (unsigned int)nbytes;
@@ -220,7 +221,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
220 221
221remainder: 222remainder:
222 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { 223 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
223 if (_get_more_prng_bytes(ctx) < 0) { 224 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
224 memset(buf, 0, nbytes); 225 memset(buf, 0, nbytes);
225 err = -EINVAL; 226 err = -EINVAL;
226 goto done; 227 goto done;
@@ -247,7 +248,7 @@ empty_rbuf:
247 */ 248 */
248 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { 249 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
249 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { 250 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
250 if (_get_more_prng_bytes(ctx) < 0) { 251 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
251 memset(buf, 0, nbytes); 252 memset(buf, 0, nbytes);
252 err = -EINVAL; 253 err = -EINVAL;
253 goto done; 254 goto done;
@@ -356,7 +357,15 @@ static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
356{ 357{
357 struct prng_context *prng = crypto_rng_ctx(tfm); 358 struct prng_context *prng = crypto_rng_ctx(tfm);
358 359
359 return get_prng_bytes(rdata, dlen, prng); 360 return get_prng_bytes(rdata, dlen, prng, 0);
361}
362
363static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
364 unsigned int dlen)
365{
366 struct prng_context *prng = crypto_rng_ctx(tfm);
367
368 return get_prng_bytes(rdata, dlen, prng, 1);
360} 369}
361 370
362/* 371/*
@@ -384,6 +393,26 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
384 return 0; 393 return 0;
385} 394}
386 395
396static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
397{
398 u8 rdata[DEFAULT_BLK_SZ];
399 int rc;
400
401 struct prng_context *prng = crypto_rng_ctx(tfm);
402
403 rc = cprng_reset(tfm, seed, slen);
404
405 if (!rc)
406 goto out;
407
408 /* this primes our continuity test */
409 rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
410 prng->rand_data_valid = DEFAULT_BLK_SZ;
411
412out:
413 return rc;
414}
415
387static struct crypto_alg rng_alg = { 416static struct crypto_alg rng_alg = {
388 .cra_name = "stdrng", 417 .cra_name = "stdrng",
389 .cra_driver_name = "ansi_cprng", 418 .cra_driver_name = "ansi_cprng",
@@ -404,19 +433,51 @@ static struct crypto_alg rng_alg = {
404 } 433 }
405}; 434};
406 435
436#ifdef CONFIG_CRYPTO_FIPS
437static struct crypto_alg fips_rng_alg = {
438 .cra_name = "fips(ansi_cprng)",
439 .cra_driver_name = "fips_ansi_cprng",
440 .cra_priority = 300,
441 .cra_flags = CRYPTO_ALG_TYPE_RNG,
442 .cra_ctxsize = sizeof(struct prng_context),
443 .cra_type = &crypto_rng_type,
444 .cra_module = THIS_MODULE,
445 .cra_list = LIST_HEAD_INIT(rng_alg.cra_list),
446 .cra_init = cprng_init,
447 .cra_exit = cprng_exit,
448 .cra_u = {
449 .rng = {
450 .rng_make_random = fips_cprng_get_random,
451 .rng_reset = fips_cprng_reset,
452 .seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
453 }
454 }
455};
456#endif
407 457
408/* Module initalization */ 458/* Module initalization */
409static int __init prng_mod_init(void) 459static int __init prng_mod_init(void)
410{ 460{
411 if (fips_enabled) 461 int rc = 0;
412 rng_alg.cra_priority += 200;
413 462
414 return crypto_register_alg(&rng_alg); 463 rc = crypto_register_alg(&rng_alg);
464#ifdef CONFIG_CRYPTO_FIPS
465 if (rc)
466 goto out;
467
468 rc = crypto_register_alg(&fips_rng_alg);
469
470out:
471#endif
472 return rc;
415} 473}
416 474
417static void __exit prng_mod_fini(void) 475static void __exit prng_mod_fini(void)
418{ 476{
419 crypto_unregister_alg(&rng_alg); 477 crypto_unregister_alg(&rng_alg);
478#ifdef CONFIG_CRYPTO_FIPS
479 crypto_unregister_alg(&fips_rng_alg);
480#endif
420 return; 481 return;
421} 482}
422 483