Commit b3614763 authored by Stephan Mueller's avatar Stephan Mueller Committed by Herbert Xu

crypto: drbg - remove FIPS 140-2 continuous test

The newly released FIPS 140-2 IG 9.8 specifies that for SP800-90A
compliant DRBGs, the FIPS 140-2 continuous random number generator test
is not required any more.

This patch removes the test and all associated data structures.
Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 973fb3fb
...@@ -219,48 +219,6 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t flags) ...@@ -219,48 +219,6 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t flags)
} }
} }
/*
* FIPS 140-2 continuous self test
* The test is performed on the result of one round of the output
* function. Thus, the function implicitly knows the size of the
* buffer.
*
* @drbg DRBG handle
* @buf output buffer of random data to be checked
*
* return:
* true on success
* false on error
*/
static bool drbg_fips_continuous_test(struct drbg_state *drbg,
const unsigned char *buf)
{
#ifdef CONFIG_CRYPTO_FIPS
int ret = 0;
/* skip test if we test the overall system */
if (list_empty(&drbg->test_data.list))
return true;
/* only perform test in FIPS mode */
if (0 == fips_enabled)
return true;
if (!drbg->fips_primed) {
/* Priming of FIPS test */
memcpy(drbg->prev, buf, drbg_blocklen(drbg));
drbg->fips_primed = true;
/* return false due to priming, i.e. another round is needed */
return false;
}
ret = memcmp(drbg->prev, buf, drbg_blocklen(drbg));
if (!ret)
panic("DRBG continuous self test failed\n");
memcpy(drbg->prev, buf, drbg_blocklen(drbg));
/* the test shall pass when the two compared values are not equal */
return ret != 0;
#else
return true;
#endif /* CONFIG_CRYPTO_FIPS */
}
/* /*
* Convert an integer into a byte representation of this integer. * Convert an integer into a byte representation of this integer.
* The byte representation is big-endian * The byte representation is big-endian
...@@ -603,11 +561,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg, ...@@ -603,11 +561,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
} }
outlen = (drbg_blocklen(drbg) < (buflen - len)) ? outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
drbg_blocklen(drbg) : (buflen - len); drbg_blocklen(drbg) : (buflen - len);
if (!drbg_fips_continuous_test(drbg, drbg->scratchpad)) {
/* 10.2.1.5.2 step 6 */
crypto_inc(drbg->V, drbg_blocklen(drbg));
continue;
}
/* 10.2.1.5.2 step 4.3 */ /* 10.2.1.5.2 step 4.3 */
memcpy(buf + len, drbg->scratchpad, outlen); memcpy(buf + len, drbg->scratchpad, outlen);
len += outlen; len += outlen;
...@@ -733,8 +686,6 @@ static int drbg_hmac_generate(struct drbg_state *drbg, ...@@ -733,8 +686,6 @@ static int drbg_hmac_generate(struct drbg_state *drbg,
return ret; return ret;
outlen = (drbg_blocklen(drbg) < (buflen - len)) ? outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
drbg_blocklen(drbg) : (buflen - len); drbg_blocklen(drbg) : (buflen - len);
if (!drbg_fips_continuous_test(drbg, drbg->V))
continue;
/* 10.1.2.5 step 4.2 */ /* 10.1.2.5 step 4.2 */
memcpy(buf + len, drbg->V, outlen); memcpy(buf + len, drbg->V, outlen);
...@@ -963,10 +914,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, ...@@ -963,10 +914,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,
} }
outlen = (drbg_blocklen(drbg) < (buflen - len)) ? outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
drbg_blocklen(drbg) : (buflen - len); drbg_blocklen(drbg) : (buflen - len);
if (!drbg_fips_continuous_test(drbg, dst)) {
crypto_inc(src, drbg_statelen(drbg));
continue;
}
/* 10.1.1.4 step hashgen 4.2 */ /* 10.1.1.4 step hashgen 4.2 */
memcpy(buf + len, dst, outlen); memcpy(buf + len, dst, outlen);
len += outlen; len += outlen;
...@@ -1201,11 +1148,6 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg) ...@@ -1201,11 +1148,6 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
drbg->reseed_ctr = 0; drbg->reseed_ctr = 0;
drbg->d_ops = NULL; drbg->d_ops = NULL;
drbg->core = NULL; drbg->core = NULL;
#ifdef CONFIG_CRYPTO_FIPS
kzfree(drbg->prev);
drbg->prev = NULL;
drbg->fips_primed = false;
#endif
} }
/* /*
...@@ -1244,12 +1186,6 @@ static inline int drbg_alloc_state(struct drbg_state *drbg) ...@@ -1244,12 +1186,6 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL); drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
if (!drbg->C) if (!drbg->C)
goto err; goto err;
#ifdef CONFIG_CRYPTO_FIPS
drbg->prev = kmalloc(drbg_blocklen(drbg), GFP_KERNEL);
if (!drbg->prev)
goto err;
drbg->fips_primed = false;
#endif
/* scratchpad is only generated for CTR and Hash */ /* scratchpad is only generated for CTR and Hash */
if (drbg->core->flags & DRBG_HMAC) if (drbg->core->flags & DRBG_HMAC)
sb_size = 0; sb_size = 0;
......
...@@ -117,10 +117,6 @@ struct drbg_state { ...@@ -117,10 +117,6 @@ struct drbg_state {
void *priv_data; /* Cipher handle */ void *priv_data; /* Cipher handle */
bool seeded; /* DRBG fully seeded? */ bool seeded; /* DRBG fully seeded? */
bool pr; /* Prediction resistance enabled? */ bool pr; /* Prediction resistance enabled? */
#ifdef CONFIG_CRYPTO_FIPS
bool fips_primed; /* Continuous test primed? */
unsigned char *prev; /* FIPS 140-2 continuous test value */
#endif
struct work_struct seed_work; /* asynchronous seeding support */ struct work_struct seed_work; /* asynchronous seeding support */
struct crypto_rng *jent; struct crypto_rng *jent;
const struct drbg_state_ops *d_ops; const struct drbg_state_ops *d_ops;
......
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