From 58b91cf9cc72e7a7247f88279e3fbeba71619237 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Sep 2008 19:22:10 +0000 Subject: Another tweak for the RNG test code. --- random/ChangeLog | 5 +++++ random/rand-internal.h | 3 ++- random/random-fips.c | 50 ++++++++++++++++++++++++++++++++++---------------- random/random.c | 2 +- 4 files changed, 42 insertions(+), 18 deletions(-) (limited to 'random') diff --git a/random/ChangeLog b/random/ChangeLog index c22ea2ea..1b6c4688 100644 --- a/random/ChangeLog +++ b/random/ChangeLog @@ -2,6 +2,11 @@ * random-fips.c (x931_aes_driver): No re-seeding with test contexts. (_gcry_rngfips_init_external_test): Fix setting of test_dt_ptr. + (struct rng_context): Add flag TEST_NO_DUP_CHECK. + (x931_aes_driver): Use that flag. + (_gcry_rngfips_init_external_test): Add arg FLAGS and use it to + modify the test. + * random.c (_gcry_random_init_external_test): Pass FLAGS. 2008-09-15 Werner Koch diff --git a/random/rand-internal.h b/random/rand-internal.h index 269fad95..534d8284 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -79,7 +79,8 @@ void _gcry_rngfips_create_nonce (void *buffer, size_t length); gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); -gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, +gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, + unsigned int flags, const void *key, size_t keylen, const void *seed, diff --git a/random/random-fips.c b/random/random-fips.c index 2fc9596e..2667e71f 100644 --- a/random/random-fips.c +++ b/random/random-fips.c @@ -141,13 +141,16 @@ struct rng_context unsigned char guard_3[1]; + /* The external test may want to suppress the duplicate bock check. + This is done if the this flag is set. */ + unsigned char test_no_dup_check; /* To implement a KAT we need to provide a know DT value. To accomplish this the x931_get_dt function checks whether this field is not NULL and then uses the 16 bytes at this address for the DT value. However the last 4 bytes are replaced by the value of field TEST_DT_COUNTER which will be incremented after each invocation of x931_get_dt. We use a pointer and not a buffer - because there is no need to put this value into secure memory. */ + because there is no need to put this value into secure memory. */ const unsigned char *test_dt_ptr; u32 test_dt_counter; @@ -476,24 +479,36 @@ x931_aes_driver (unsigned char *output, size_t length, rng_context_t rng_ctx) intermediate_I, temp_buffer); rng_ctx->use_counter++; - /* Do a basic check on the output to avoid a stuck generator. */ - if (!rng_ctx->compare_value_valid) + if (rng_ctx->test_no_dup_check + && rng_ctx->test_dt_ptr + && rng_ctx != nonce_context + && rng_ctx != std_rng_context + && rng_ctx != strong_rng_context) { - /* First time used, only save the result. */ - memcpy (rng_ctx->compare_value, result_buffer, 16); - rng_ctx->compare_value_valid = 1; - continue; + /* This is a test context which does not want the duplicate + block check. */ } - if (!memcmp (rng_ctx->compare_value, result_buffer, 16)) + else { - /* Ooops, we received the same 128 bit block - that should - in theory never happen. The FIPS requirement says that - we need to put ourself into the error state in such - case. */ - fips_signal_error ("duplicate 128 bit block returned by RNG"); - return -1; + /* Do a basic check on the output to avoid a stuck generator. */ + if (!rng_ctx->compare_value_valid) + { + /* First time used, only save the result. */ + memcpy (rng_ctx->compare_value, result_buffer, 16); + rng_ctx->compare_value_valid = 1; + continue; + } + if (!memcmp (rng_ctx->compare_value, result_buffer, 16)) + { + /* Ooops, we received the same 128 bit block - that should + in theory never happen. The FIPS requirement says that + we need to put ourself into the error state in such + case. */ + fips_signal_error ("duplicate 128 bit block returned by RNG"); + return -1; + } + memcpy (rng_ctx->compare_value, result_buffer, 16); } - memcpy (rng_ctx->compare_value, result_buffer, 16); /* Append to outbut. */ memcpy (output, result_buffer, nbytes); @@ -1002,7 +1017,7 @@ _gcry_rngfips_selftest (selftest_report_func_t report) success the test context is stored at R_CONTEXT; on failure NULL is stored at R_CONTEXT and an error code is returned. */ gcry_err_code_t -_gcry_rngfips_init_external_test (void **r_context, +_gcry_rngfips_init_external_test (void **r_context, unsigned int flags, const void *key, size_t keylen, const void *seed, size_t seedlen, const void *dt, size_t dtlen) @@ -1051,6 +1066,9 @@ _gcry_rngfips_init_external_test (void **r_context, |(test_ctx->test_dt_ptr[14] << 8) |(test_ctx->test_dt_ptr[15]) ); + if ( (flags & 1) ) + test_ctx->test_no_dup_check = 1; + check_guards (test_ctx); /* All fine. */ err = 0; diff --git a/random/random.c b/random/random.c index 9da83cf0..85d5fa97 100644 --- a/random/random.c +++ b/random/random.c @@ -296,7 +296,7 @@ _gcry_random_init_external_test (void **r_context, { (void)flags; if (fips_mode ()) - return _gcry_rngfips_init_external_test (r_context, key, keylen, + return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, seed, seedlen, dt, dtlen); else -- cgit v1.2.1