mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Add selftest callback to CRNG output test
Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12795)
This commit is contained in:
parent
4b51903d86
commit
7f9e744036
@ -157,12 +157,15 @@ void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret)
|
||||
* is modified (corrupted). This is used to modify output signatures or
|
||||
* ciphertext before they are verified or decrypted.
|
||||
*/
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
|
||||
int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
|
||||
self_test_setparams(st);
|
||||
if (!st->cb(st->params, st->cb_arg))
|
||||
if (!st->cb(st->params, st->cb_arg)) {
|
||||
bytes[0] ^= 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ OSSL_SELF_TEST_onend - functionality to trigger a callback during a self test
|
||||
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc);
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -104,6 +104,9 @@ This allows the callback to identify the sub category of the test being run.
|
||||
OSSL_SELF_TEST_new() returns the allocated B<OSSL_SELF_TEST> object, or NULL if
|
||||
it fails.
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte() returns 1 if corruption occurs, otherwise it
|
||||
returns 0.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
A single self test could be set up in the following way:
|
||||
|
@ -212,6 +212,10 @@ Known answer test for a Deterministic Random Bit Generator.
|
||||
|
||||
Conditional test that is run during the generation of key pairs.
|
||||
|
||||
=item "Continuous_RNG_Test" (B<OSSL_SELF_TEST_TYPE_CRNG>)
|
||||
|
||||
Continuous random number generator test.
|
||||
|
||||
=back
|
||||
|
||||
The "Module_Integrity" self test is always run at startup.
|
||||
@ -289,6 +293,10 @@ Key Derivation Function tests used with the "KAT_KDF" type.
|
||||
|
||||
DRBG tests used with the "DRBG" type.
|
||||
|
||||
= item "RNG" (B<OSSL_SELF_TEST_DESC_RNG>)
|
||||
|
||||
"Continuous_RNG_Test" uses this.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
@ -60,6 +60,7 @@ extern "C" {
|
||||
# define OSSL_SELF_TEST_DESC_KA_ECDH "ECDH"
|
||||
# define OSSL_SELF_TEST_DESC_KDF_HKDF "HKDF"
|
||||
# define OSSL_SELF_TEST_DESC_KDF_SSKDF "SSKDF"
|
||||
# define OSSL_SELF_TEST_DESC_RNG "RNG"
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
@ -75,7 +76,7 @@ void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st);
|
||||
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc);
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
|
||||
|
||||
#endif /* OPENSSL_SELF_TEST_H */
|
||||
|
@ -94,8 +94,8 @@ static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
|
||||
};
|
||||
|
||||
static int prov_crngt_compare_previous(const unsigned char *prev,
|
||||
const unsigned char *cur,
|
||||
size_t sz)
|
||||
const unsigned char *cur,
|
||||
size_t sz)
|
||||
{
|
||||
const int res = memcmp(prev, cur, sz) != 0;
|
||||
|
||||
@ -113,11 +113,14 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg,
|
||||
unsigned int sz;
|
||||
RAND_POOL *pool;
|
||||
size_t q, r = 0, s, t = 0;
|
||||
int attempts = 3;
|
||||
int attempts = 3, crng_test_pass = 1;
|
||||
OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(drbg->provctx);
|
||||
CRNG_TEST_GLOBAL *crngt_glob
|
||||
= openssl_ctx_get_data(libctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
|
||||
&rand_crng_ossl_ctx_method);
|
||||
OSSL_CALLBACK *stcb = NULL;
|
||||
void *stcbarg = NULL;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
if (crngt_glob == NULL)
|
||||
return 0;
|
||||
@ -125,12 +128,27 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg,
|
||||
if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL)
|
||||
return 0;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
|
||||
if (stcb != NULL) {
|
||||
st = OSSL_SELF_TEST_new(stcb, stcbarg);
|
||||
if (st == NULL)
|
||||
goto err;
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_CRNG,
|
||||
OSSL_SELF_TEST_DESC_RNG);
|
||||
}
|
||||
|
||||
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
|
||||
s = q > sizeof(buf) ? sizeof(buf) : q;
|
||||
if (!crngt_get_entropy(libctx, crngt_glob->crngt_pool, buf, md,
|
||||
&sz)
|
||||
|| !prov_crngt_compare_previous(crngt_glob->crngt_prev, md, sz)
|
||||
|| !rand_pool_add(pool, buf, s, s * 8))
|
||||
if (!crngt_get_entropy(libctx, crngt_glob->crngt_pool, buf, md, &sz))
|
||||
goto err;
|
||||
/* Force a failure here if the callback returns 1 */
|
||||
if (OSSL_SELF_TEST_oncorrupt_byte(st, md))
|
||||
memcpy(md, crngt_glob->crngt_prev, sz);
|
||||
if (!prov_crngt_compare_previous(crngt_glob->crngt_prev, md, sz)) {
|
||||
crng_test_pass = 0;
|
||||
goto err;
|
||||
}
|
||||
if (!rand_pool_add(pool, buf, s, s * 8))
|
||||
goto err;
|
||||
memcpy(crngt_glob->crngt_prev, md, sz);
|
||||
t += s;
|
||||
@ -139,6 +157,8 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg,
|
||||
r = t;
|
||||
*pout = rand_pool_detach(pool);
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, crng_test_pass);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
OPENSSL_cleanse(buf, sizeof(buf));
|
||||
rand_pool_free(pool);
|
||||
return r;
|
||||
|
Loading…
x
Reference in New Issue
Block a user