diff options
| author | Neil Horman <nhorman@tuxdriver.com> | 2009-10-18 22:57:02 -0400 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-10-18 22:57:02 -0400 |
| commit | 667b6294bf088445996c8395b723ae9c9467e72b (patch) | |
| tree | a1a78547fc3e6ab1fe88b5d13a10d0f9fbceab3b | |
| parent | 0e1227d356e9b2fe0500d6cc7084f752040a1e0e (diff) | |
crypto: ansi_cprng - Add FIPS wrapper
Patch to add fips(ansi_cprng) alg, which is ansi_cprng plus a continuous test
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
| -rw-r--r-- | crypto/ansi_cprng.c | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 3aa6e3834bfe..027176a0e889 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 | */ |
| 88 | static int _get_more_prng_bytes(struct prng_context *ctx) | 88 | static 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 */ |
| 188 | static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) | 188 | static 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 | ||
| 221 | remainder: | 222 | remainder: |
| 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 | |||
| 363 | static 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 | ||
| 396 | static 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 | |||
| 412 | out: | ||
| 413 | return rc; | ||
| 414 | } | ||
| 415 | |||
| 387 | static struct crypto_alg rng_alg = { | 416 | static 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 | ||
| 437 | static 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 */ |
| 409 | static int __init prng_mod_init(void) | 459 | static 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 | |||
| 470 | out: | ||
| 471 | #endif | ||
| 472 | return rc; | ||
| 415 | } | 473 | } |
| 416 | 474 | ||
| 417 | static void __exit prng_mod_fini(void) | 475 | static 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 | ||
