summaryrefslogtreecommitdiff
path: root/random
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2008-09-16 19:22:10 +0000
committerWerner Koch <wk@gnupg.org>2008-09-16 19:22:10 +0000
commit58b91cf9cc72e7a7247f88279e3fbeba71619237 (patch)
treec6eb3d0028a8e937e918fb423f177e5388b22209 /random
parentad1181839f2db1afbe0af6945355de30b7e2d7f4 (diff)
downloadlibgcrypt-58b91cf9cc72e7a7247f88279e3fbeba71619237.tar.gz
Another tweak for the RNG test code.
Diffstat (limited to 'random')
-rw-r--r--random/ChangeLog5
-rw-r--r--random/rand-internal.h3
-rw-r--r--random/random-fips.c50
-rw-r--r--random/random.c2
4 files changed, 42 insertions, 18 deletions
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 <wk@g10code.com>
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