Commit 667b6294 authored by Neil Horman's avatar Neil Horman Committed by Herbert Xu

crypto: ansi_cprng - Add FIPS wrapper

Patch to add fips(ansi_cprng) alg, which is ansi_cprng plus a continuous test
Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Acked-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 0e1227d3
...@@ -85,7 +85,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2, ...@@ -85,7 +85,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2,
* Returns DEFAULT_BLK_SZ bytes of random data per call * Returns DEFAULT_BLK_SZ bytes of random data per call
* returns 0 if generation succeded, <0 if something went wrong * returns 0 if generation succeded, <0 if something went wrong
*/ */
static int _get_more_prng_bytes(struct prng_context *ctx) static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
{ {
int i; int i;
unsigned char tmp[DEFAULT_BLK_SZ]; unsigned char tmp[DEFAULT_BLK_SZ];
...@@ -132,7 +132,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx) ...@@ -132,7 +132,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
*/ */
if (!memcmp(ctx->rand_data, ctx->last_rand_data, if (!memcmp(ctx->rand_data, ctx->last_rand_data,
DEFAULT_BLK_SZ)) { DEFAULT_BLK_SZ)) {
if (fips_enabled) { if (cont_test) {
panic("cprng %p Failed repetition check!\n", panic("cprng %p Failed repetition check!\n",
ctx); ctx);
} }
...@@ -185,7 +185,8 @@ static int _get_more_prng_bytes(struct prng_context *ctx) ...@@ -185,7 +185,8 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
} }
/* Our exported functions */ /* Our exported functions */
static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
int do_cont_test)
{ {
unsigned char *ptr = buf; unsigned char *ptr = buf;
unsigned int byte_count = (unsigned int)nbytes; 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,7 +221,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
remainder: remainder:
if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
if (_get_more_prng_bytes(ctx) < 0) { if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
memset(buf, 0, nbytes); memset(buf, 0, nbytes);
err = -EINVAL; err = -EINVAL;
goto done; goto done;
...@@ -247,7 +248,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) ...@@ -247,7 +248,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
*/ */
for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
if (_get_more_prng_bytes(ctx) < 0) { if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
memset(buf, 0, nbytes); memset(buf, 0, nbytes);
err = -EINVAL; err = -EINVAL;
goto done; goto done;
...@@ -356,7 +357,15 @@ static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata, ...@@ -356,7 +357,15 @@ static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
{ {
struct prng_context *prng = crypto_rng_ctx(tfm); struct prng_context *prng = crypto_rng_ctx(tfm);
return get_prng_bytes(rdata, dlen, prng); return get_prng_bytes(rdata, dlen, prng, 0);
}
static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
unsigned int dlen)
{
struct prng_context *prng = crypto_rng_ctx(tfm);
return get_prng_bytes(rdata, dlen, prng, 1);
} }
/* /*
...@@ -384,6 +393,26 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) ...@@ -384,6 +393,26 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
return 0; return 0;
} }
static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
{
u8 rdata[DEFAULT_BLK_SZ];
int rc;
struct prng_context *prng = crypto_rng_ctx(tfm);
rc = cprng_reset(tfm, seed, slen);
if (!rc)
goto out;
/* this primes our continuity test */
rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
prng->rand_data_valid = DEFAULT_BLK_SZ;
out:
return rc;
}
static struct crypto_alg rng_alg = { static struct crypto_alg rng_alg = {
.cra_name = "stdrng", .cra_name = "stdrng",
.cra_driver_name = "ansi_cprng", .cra_driver_name = "ansi_cprng",
...@@ -404,19 +433,51 @@ static struct crypto_alg rng_alg = { ...@@ -404,19 +433,51 @@ static struct crypto_alg rng_alg = {
} }
}; };
#ifdef CONFIG_CRYPTO_FIPS
static struct crypto_alg fips_rng_alg = {
.cra_name = "fips(ansi_cprng)",
.cra_driver_name = "fips_ansi_cprng",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_RNG,
.cra_ctxsize = sizeof(struct prng_context),
.cra_type = &crypto_rng_type,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(rng_alg.cra_list),
.cra_init = cprng_init,
.cra_exit = cprng_exit,
.cra_u = {
.rng = {
.rng_make_random = fips_cprng_get_random,
.rng_reset = fips_cprng_reset,
.seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
}
}
};
#endif
/* Module initalization */ /* Module initalization */
static int __init prng_mod_init(void) static int __init prng_mod_init(void)
{ {
if (fips_enabled) int rc = 0;
rng_alg.cra_priority += 200;
return crypto_register_alg(&rng_alg); rc = crypto_register_alg(&rng_alg);
#ifdef CONFIG_CRYPTO_FIPS
if (rc)
goto out;
rc = crypto_register_alg(&fips_rng_alg);
out:
#endif
return rc;
} }
static void __exit prng_mod_fini(void) static void __exit prng_mod_fini(void)
{ {
crypto_unregister_alg(&rng_alg); crypto_unregister_alg(&rng_alg);
#ifdef CONFIG_CRYPTO_FIPS
crypto_unregister_alg(&fips_rng_alg);
#endif
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment