diff options
author | Werner Koch <wk@gnupg.org> | 2016-02-19 15:35:03 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2016-02-19 15:35:03 +0100 |
commit | 934ba2ae5a95a96fdbb3b935b51ba43df66f11df (patch) | |
tree | fbf9e6190ef0825e132eefaf26e3fe5bf2ad1c5b | |
parent | 7cdbd6e6a3cf1ee366b981e148d41b1187a6fdcf (diff) | |
download | libgcrypt-934ba2ae5a95a96fdbb3b935b51ba43df66f11df.tar.gz |
random: Add a test case for DRBG_REINIT.
* src/global.c (_gcry_vcontrol) <DRBG_REINIT>: Test for FIPS RNG.
* tests/random.c (check_drbg_reinit): New.
(main): Call new test.
Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r-- | src/global.c | 2 | ||||
-rw-r--r-- | tests/random.c | 85 |
2 files changed, 87 insertions, 0 deletions
diff --git a/src/global.c b/src/global.c index 4bd928b9..4d69b27b 100644 --- a/src/global.c +++ b/src/global.c @@ -663,6 +663,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) int npers = va_arg (arg_ptr, int); if (va_arg (arg_ptr, void *) || npers < 0) rc = GPG_ERR_INV_ARG; + else if (_gcry_get_rng_type (!any_init_done) != GCRY_RNG_TYPE_FIPS) + rc = GPG_ERR_NOT_SUPPORTED; else rc = _gcry_rngdrbg_reinit (flagstr, pers, npers); } diff --git a/tests/random.c b/tests/random.c index d7a624ad..8aa730b2 100644 --- a/tests/random.c +++ b/tests/random.c @@ -34,6 +34,10 @@ #define PGM "random" +#ifndef DIM +# define DIM(v) (sizeof(v)/sizeof((v)[0])) +#endif + static int verbose; static int debug; @@ -430,6 +434,86 @@ check_early_rng_type_switching (void) } +static void +check_drbg_reinit (void) +{ + static struct { const char *flags; } tv[] = { + { NULL }, + { "" }, + { "sha1" }, + { "sha1 pr" }, + { "sha256" }, + { "sha256 pr" }, + { "sha512" }, + { "sha512 pr" }, + { "hmac sha1" }, + { "hmac sha1 pr" }, + { "hmac sha256" }, + { "hmac sha256 pr" }, + { "hmac sha512" }, + { "hmac sha512 pr" }, + { "aes sym128" }, + { "aes sym128 pr" }, + { "aes sym192" }, + { "aes sym192 pr" }, + { "aes sym256" }, + { "aes sym256 pr" } + }; + int tidx; + gpg_error_t err; + char pers_string[] = "I'm a doctor, not an engineer."; + gcry_buffer_t pers[1]; + + if (verbose) + inf ("checking DRBG_REINIT\n"); + + memset (pers, 0, sizeof pers); + pers[0].data = pers_string; + pers[0].len = strlen (pers_string); + + err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, &err); + if (gpg_err_code (err) != GPG_ERR_INV_ARG) + die ("gcry_control(DRBG_REINIT) guard value did not work\n"); + + err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, -1, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_ARG) + die ("gcry_control(DRBG_REINIT) npers negative detection failed\n"); + + if (rng_type () != GCRY_RNG_TYPE_FIPS) + { + err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, NULL); + if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) + die ("DRBG_REINIT worked despite that DRBG is not active\n"); + return; + } + + err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 1, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_ARG) + die ("_gcry_rngdrbg_reinit failed to detact: (!pers && npers)\n"); + err = gcry_control (GCRYCTL_DRBG_REINIT, "", pers, 2, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_ARG) + die ("_gcry_rngdrbg_reinit failed to detect: (pers && npers != 1)\n"); + + err = gcry_control (GCRYCTL_DRBG_REINIT, "aes sym128 bad pr ", pers, 1, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_FLAG) + die ("_gcry_rngdrbg_reinit failed to detect a bad flag\n"); + + for (tidx=0; tidx < DIM(tv); tidx++) + { + err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, NULL, 0, NULL); + if (err) + die ("_gcry_rngdrbg_reinit failed for \"%s\" w/o pers: %s\n", + + tv[tidx].flags, gpg_strerror (err)); + err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, pers, 1, NULL); + if (err) + die ("_gcry_rngdrbg_reinit failed for \"%s\" with pers: %s\n", + tv[tidx].flags, gpg_strerror (err)); + /* fixme: We should extract some random after each test. */ + } +} + + /* Because we want to check initialization behaviour, we need to fork/exec this program with several command line arguments. We use system, so that these tests work also on Windows. */ @@ -582,6 +666,7 @@ main (int argc, char **argv) check_nonce_forking (); check_close_random_device (); } + check_drbg_reinit (); check_rng_type_switching (); if (!in_recursion) |