diff options
author | Rich Salz <rsalz@openssl.org> | 2017-08-03 09:23:28 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2017-08-03 09:23:28 -0400 |
commit | 75e2c877650444fb829547bdb58d46eb1297bc1a (patch) | |
tree | 67ad6280bccdca4ae95cc269b1994ea4c1557aa7 /test/drbgtest.c | |
parent | 67dc995eaf538ea309c6292a1a5073465201f55b (diff) | |
download | openssl-75e2c877650444fb829547bdb58d46eb1297bc1a.tar.gz |
Switch from ossl_rand to DRBG rand
If RAND_add wraps around, XOR with existing. Add test to drbgtest that
does the wrap-around.
Re-order seeding and stop after first success.
Add RAND_poll_ex()
Use the DF and therefore lower RANDOMNESS_NEEDED. Also, for child DRBG's,
mix in the address as the personalization bits.
Centralize the entropy callbacks, from drbg_lib to rand_lib.
(Conceptually, entropy is part of the enclosing application.)
Thanks to Dr. Matthias St Pierre for the suggestion.
Various code cleanups:
-Make state an enum; inline RANDerr calls.
-Add RAND_POLL_RETRIES (thanks Pauli for the idea)
-Remove most RAND_seed calls from rest of library
-Rename DRBG_CTX to RAND_DRBG, etc.
-Move some code from drbg_lib to drbg_rand; drbg_lib is now only the
implementation of NIST DRBG.
-Remove blocklength
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/4019)
Diffstat (limited to 'test/drbgtest.c')
-rw-r--r-- | test/drbgtest.c | 206 |
1 files changed, 110 insertions, 96 deletions
diff --git a/test/drbgtest.c b/test/drbgtest.c index 90ed2ef1d1..f28cd48dd1 100644 --- a/test/drbgtest.c +++ b/test/drbgtest.c @@ -92,18 +92,18 @@ typedef struct drbg_selftest_data_st { make_drbg_test_data(nid, RAND_DRBG_FLAG_CTR_USE_DF, pr, p) static DRBG_SELFTEST_DATA drbg_test[] = { - make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), - make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), - make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1), make_drbg_test_data (NID_aes_128_ctr, 0, aes_128_no_df, 0), make_drbg_test_data (NID_aes_192_ctr, 0, aes_192_no_df, 0), make_drbg_test_data (NID_aes_256_ctr, 0, aes_256_no_df, 1), + make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), + make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), + make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1), }; static int app_data_index; /* - * Test context data, attached as appdata to the DRBG_CTX + * Test context data, attached as EXDATA to the RAND_DRBG */ typedef struct test_ctx_st { const unsigned char *ent; @@ -114,29 +114,29 @@ typedef struct test_ctx_st { int noncecnt; } TEST_CTX; -static size_t kat_entropy(DRBG_CTX *dctx, unsigned char **pout, +static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { - TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(dctx, app_data_index); + TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index); t->entcnt++; *pout = (unsigned char *)t->ent; return t->entlen; } -static size_t kat_nonce(DRBG_CTX *dctx, unsigned char **pout, +static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { - TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(dctx, app_data_index); + TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index); t->noncecnt++; *pout = (unsigned char *)t->nonce; return t->noncelen; } -static int uninstantiate(DRBG_CTX *dctx) +static int uninstantiate(RAND_DRBG *drbg) { - int ret = dctx == NULL ? 1 : RAND_DRBG_uninstantiate(dctx); + int ret = drbg == NULL ? 1 : RAND_DRBG_uninstantiate(drbg); ERR_clear_error(); return ret; @@ -147,7 +147,7 @@ static int uninstantiate(DRBG_CTX *dctx) */ static int single_kat(DRBG_SELFTEST_DATA *td) { - DRBG_CTX *dctx = NULL; + RAND_DRBG *drbg = NULL; TEST_CTX t; int failures = 0; unsigned char buff[1024]; @@ -156,9 +156,9 @@ static int single_kat(DRBG_SELFTEST_DATA *td) * Test without PR: Instantiate DRBG with test entropy, nonce and * personalisation string. */ - if (!TEST_ptr(dctx = RAND_DRBG_new(td->nid, td->flags, NULL))) + if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, td->flags, NULL))) return 0; - if (!TEST_true(RAND_DRBG_set_callbacks(dctx, kat_entropy, NULL, + if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, kat_nonce, NULL))) { failures++; goto err; @@ -168,10 +168,10 @@ static int single_kat(DRBG_SELFTEST_DATA *td) t.entlen = td->entlen; t.nonce = td->nonce; t.noncelen = td->noncelen; - RAND_DRBG_set_ex_data(dctx, app_data_index, &t); + RAND_DRBG_set_ex_data(drbg, app_data_index, &t); - if (!TEST_true(RAND_DRBG_instantiate(dctx, td->pers, td->perslen)) - || !TEST_true(RAND_DRBG_generate(dctx, buff, td->exlen, 0, + if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen)) + || !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, td->adin, td->adinlen)) || !TEST_mem_eq(td->expected, td->exlen, buff, td->exlen)) failures++; @@ -179,29 +179,29 @@ static int single_kat(DRBG_SELFTEST_DATA *td) /* Reseed DRBG with test entropy and additional input */ t.ent = td->entreseed; t.entlen = td->entreseedlen; - if (!TEST_true(RAND_DRBG_reseed(dctx, td->adinreseed, td->adinreseedlen) - || !TEST_true(RAND_DRBG_generate(dctx, buff, td->kat2len, 0, + if (!TEST_true(RAND_DRBG_reseed(drbg, td->adinreseed, td->adinreseedlen) + || !TEST_true(RAND_DRBG_generate(drbg, buff, td->kat2len, 0, td->adin2, td->adin2len)) || !TEST_mem_eq(td->kat2, td->kat2len, buff, td->kat2len))) failures++; - uninstantiate(dctx); + uninstantiate(drbg); /* * Now test with PR: Instantiate DRBG with test entropy, nonce and * personalisation string. */ - if (!TEST_true(RAND_DRBG_set(dctx, td->nid, td->flags)) - || !TEST_true(RAND_DRBG_set_callbacks(dctx, kat_entropy, NULL, + if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags)) + || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, kat_nonce, NULL))) failures++; - RAND_DRBG_set_ex_data(dctx, app_data_index, &t); + RAND_DRBG_set_ex_data(drbg, app_data_index, &t); t.ent = td->ent_pr; t.entlen = td->entlen_pr; t.nonce = td->nonce_pr; t.noncelen = td->noncelen_pr; t.entcnt = 0; t.noncecnt = 0; - if (!TEST_true(RAND_DRBG_instantiate(dctx, td->pers_pr, td->perslen_pr))) + if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers_pr, td->perslen_pr))) failures++; /* @@ -210,7 +210,7 @@ static int single_kat(DRBG_SELFTEST_DATA *td) */ t.ent = td->entpr_pr; t.entlen = td->entprlen_pr; - if (!TEST_true(RAND_DRBG_generate(dctx, buff, td->katlen_pr, 1, + if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->katlen_pr, 1, td->adin_pr, td->adinlen_pr)) || !TEST_mem_eq(td->kat_pr, td->katlen_pr, buff, td->katlen_pr)) failures++; @@ -221,28 +221,28 @@ static int single_kat(DRBG_SELFTEST_DATA *td) t.ent = td->entg_pr; t.entlen = td->entglen_pr; - if (!TEST_true(RAND_DRBG_generate(dctx, buff, td->kat2len_pr, 1, + if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->kat2len_pr, 1, td->ading_pr, td->adinglen_pr)) || !TEST_mem_eq(td->kat2_pr, td->kat2len_pr, buff, td->kat2len_pr)) failures++; err: - uninstantiate(dctx); - RAND_DRBG_free(dctx); + uninstantiate(drbg); + RAND_DRBG_free(drbg); return failures == 0; } /* * Initialise a DRBG based on selftest data */ -static int init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_CTX *t) +static int init(RAND_DRBG *drbg, DRBG_SELFTEST_DATA *td, TEST_CTX *t) { - if (!TEST_true(RAND_DRBG_set(dctx, td->nid, td->flags)) - || !TEST_true(RAND_DRBG_set_callbacks(dctx, kat_entropy, NULL, + if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags)) + || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, kat_nonce, NULL))) return 0; - RAND_DRBG_set_ex_data(dctx, app_data_index, t); + RAND_DRBG_set_ex_data(drbg, app_data_index, t); t->ent = td->ent; t->entlen = td->entlen; t->nonce = td->nonce; @@ -255,11 +255,11 @@ static int init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, TEST_CTX *t) /* * Initialise and instantiate DRBG based on selftest data */ -static int instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, +static int instantiate(RAND_DRBG *drbg, DRBG_SELFTEST_DATA *td, TEST_CTX *t) { - if (!TEST_true(init(dctx, td, t)) - || !TEST_true(RAND_DRBG_instantiate(dctx, td->pers, td->perslen))) + if (!TEST_true(init(drbg, td, t)) + || !TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen))) return 0; return 1; } @@ -270,14 +270,14 @@ static int instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td, */ static int error_check(DRBG_SELFTEST_DATA *td) { - static char zero[sizeof(DRBG_CTX)]; - DRBG_CTX *dctx = NULL; + static char zero[sizeof(RAND_DRBG)]; + RAND_DRBG *drbg = NULL; TEST_CTX t; unsigned char buff[1024]; unsigned int reseed_counter_tmp; int ret = 0; - if (!TEST_ptr(dctx = RAND_DRBG_new(0, 0, NULL))) + if (!TEST_ptr(drbg = RAND_DRBG_new(0, 0, NULL))) goto err; /* @@ -285,8 +285,8 @@ static int error_check(DRBG_SELFTEST_DATA *td) */ /* Test detection of too large personlisation string */ - if (!init(dctx, td, &t) - || RAND_DRBG_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) + if (!init(drbg, td, &t) + || RAND_DRBG_instantiate(drbg, td->pers, drbg->max_pers + 1) > 0) goto err; /* @@ -295,27 +295,27 @@ static int error_check(DRBG_SELFTEST_DATA *td) /* Test entropy source failure detecion: i.e. returns no data */ t.entlen = 0; - if (TEST_int_le(RAND_DRBG_instantiate(dctx, td->pers, td->perslen), 0)) + if (TEST_int_le(RAND_DRBG_instantiate(drbg, td->pers, td->perslen), 0)) goto err; /* Try to generate output from uninstantiated DRBG */ - if (!TEST_false(RAND_DRBG_generate(dctx, buff, td->exlen, 0, + if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 0, td->adin, td->adinlen)) - || !uninstantiate(dctx)) + || !uninstantiate(drbg)) goto err; /* Test insufficient entropy */ - t.entlen = dctx->min_entropy - 1; - if (!init(dctx, td, &t) - || RAND_DRBG_instantiate(dctx, td->pers, td->perslen) > 0 - || !uninstantiate(dctx)) + t.entlen = drbg->min_entropy - 1; + if (!init(drbg, td, &t) + || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 + || !uninstantiate(drbg)) goto err; /* Test too much entropy */ - t.entlen = dctx->max_entropy + 1; - if (!init(dctx, td, &t) - || RAND_DRBG_instantiate(dctx, td->pers, td->perslen) > 0 - || !uninstantiate(dctx)) + t.entlen = drbg->max_entropy + 1; + if (!init(drbg, td, &t) + || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 + || !uninstantiate(drbg)) goto err; /* @@ -323,37 +323,37 @@ static int error_check(DRBG_SELFTEST_DATA *td) */ /* Test too small nonce */ - if (dctx->min_nonce) { - t.noncelen = dctx->min_nonce - 1; - if (!init(dctx, td, &t) - || RAND_DRBG_instantiate(dctx, td->pers, td->perslen) > 0 - || !uninstantiate(dctx)) + if (drbg->min_nonce) { + t.noncelen = drbg->min_nonce - 1; + if (!init(drbg, td, &t) + || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 + || !uninstantiate(drbg)) goto err; } /* Test too large nonce */ - if (dctx->max_nonce) { - t.noncelen = dctx->max_nonce + 1; - if (!init(dctx, td, &t) - || RAND_DRBG_instantiate(dctx, td->pers, td->perslen) > 0 - || !uninstantiate(dctx)) + if (drbg->max_nonce) { + t.noncelen = drbg->max_nonce + 1; + if (!init(drbg, td, &t) + || RAND_DRBG_instantiate(drbg, td->pers, td->perslen) > 0 + || !uninstantiate(drbg)) goto err; } /* Instantiate with valid data, Check generation is now OK */ - if (!instantiate(dctx, td, &t) - || !TEST_true(RAND_DRBG_generate(dctx, buff, td->exlen, 0, + if (!instantiate(drbg, td, &t) + || !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, td->adin, td->adinlen))) goto err; /* Request too much data for one request */ - if (!TEST_false(RAND_DRBG_generate(dctx, buff, dctx->max_request + 1, 0, + if (!TEST_false(RAND_DRBG_generate(drbg, buff, drbg->max_request + 1, 0, td->adin, td->adinlen))) goto err; /* Try too large additional input */ - if (!TEST_false(RAND_DRBG_generate(dctx, buff, td->exlen, 0, - td->adin, dctx->max_adin + 1))) + if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 0, + td->adin, drbg->max_adin + 1))) goto err; /* @@ -361,24 +361,24 @@ static int error_check(DRBG_SELFTEST_DATA *td) * failure. */ t.entlen = 0; - if (TEST_false(RAND_DRBG_generate(dctx, buff, td->exlen, 1, + if (TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 1, td->adin, td->adinlen)) - || !uninstantiate(dctx)) + || !uninstantiate(drbg)) goto err; /* Instantiate again with valid data */ - if (!instantiate(dctx, td, &t)) + if (!instantiate(drbg, td, &t)) goto err; - reseed_counter_tmp = dctx->reseed_counter; - dctx->reseed_counter = dctx->reseed_interval; + reseed_counter_tmp = drbg->reseed_counter; + drbg->reseed_counter = drbg->reseed_interval; /* Generate output and check entropy has been requested for reseed */ t.entcnt = 0; - if (!TEST_true(RAND_DRBG_generate(dctx, buff, td->exlen, 0, + if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, td->adin, td->adinlen)) || !TEST_int_eq(t.entcnt, 1) - || !TEST_int_eq(dctx->reseed_counter, reseed_counter_tmp + 1) - || !uninstantiate(dctx)) + || !TEST_int_eq(drbg->reseed_counter, reseed_counter_tmp + 1) + || !uninstantiate(drbg)) goto err; /* @@ -386,24 +386,24 @@ static int error_check(DRBG_SELFTEST_DATA *td) * failure. */ t.entlen = 0; - if (!TEST_false(RAND_DRBG_generate(dctx, buff, td->exlen, 1, + if (!TEST_false(RAND_DRBG_generate(drbg, buff, td->exlen, 1, td->adin, td->adinlen)) - || !uninstantiate(dctx)) + || !uninstantiate(drbg)) goto err; /* Test reseed counter works */ - if (!instantiate(dctx, td, &t)) + if (!instantiate(drbg, td, &t)) goto err; - reseed_counter_tmp = dctx->reseed_counter; - dctx->reseed_counter = dctx->reseed_interval; + reseed_counter_tmp = drbg->reseed_counter; + drbg->reseed_counter = drbg->reseed_interval; /* Generate output and check entropy has been requested for reseed */ t.entcnt = 0; - if (!TEST_true(RAND_DRBG_generate(dctx, buff, td->exlen, 0, + if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0, td->adin, td->adinlen)) || !TEST_int_eq(t.entcnt, 1) - || !TEST_int_eq(dctx->reseed_counter, reseed_counter_tmp + 1) - || !uninstantiate(dctx)) + || !TEST_int_eq(drbg->reseed_counter, reseed_counter_tmp + 1) + || !uninstantiate(drbg)) goto err; /* @@ -411,41 +411,41 @@ static int error_check(DRBG_SELFTEST_DATA *td) */ /* Test explicit reseed with too large additional input */ - if (!init(dctx, td, &t) - || RAND_DRBG_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) + if (!init(drbg, td, &t) + || RAND_DRBG_reseed(drbg, td->adin, drbg->max_adin + 1) > 0) goto err; /* Test explicit reseed with entropy source failure */ t.entlen = 0; - if (!TEST_int_le(RAND_DRBG_reseed(dctx, td->adin, td->adinlen), 0) - || !uninstantiate(dctx)) + if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0) + || !uninstantiate(drbg)) goto err; /* Test explicit reseed with too much entropy */ - if (!init(dctx, td, &t)) + if (!init(drbg, td, &t)) goto err; - t.entlen = dctx->max_entropy + 1; - if (!TEST_int_le(RAND_DRBG_reseed(dctx, td->adin, td->adinlen), 0) - || !uninstantiate(dctx)) + t.entlen = drbg->max_entropy + 1; + if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0) + || !uninstantiate(drbg)) goto err; /* Test explicit reseed with too little entropy */ - if (!init(dctx, td, &t)) + if (!init(drbg, td, &t)) goto err; - t.entlen = dctx->min_entropy - 1; - if (!TEST_int_le(RAND_DRBG_reseed(dctx, td->adin, td->adinlen), 0) - || !uninstantiate(dctx)) + t.entlen = drbg->min_entropy - 1; + if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0) + || !uninstantiate(drbg)) goto err; /* Standard says we have to check uninstantiate really zeroes */ - if (!TEST_mem_eq(zero, sizeof(dctx->ctr), &dctx->ctr, sizeof(dctx->ctr))) + if (!TEST_mem_eq(zero, sizeof(drbg->ctr), &drbg->ctr, sizeof(drbg->ctr))) goto err; ret = 1; err: - uninstantiate(dctx); - RAND_DRBG_free(dctx); + uninstantiate(drbg); + RAND_DRBG_free(drbg); return ret; } @@ -475,6 +475,19 @@ err: return rv; } +#define RAND_ADD_SIZE 500 + +static int test_rand_add() +{ + char *p; + + if (!TEST_ptr(p = malloc(RAND_ADD_SIZE))) + return 0; + RAND_add(p, RAND_ADD_SIZE, RAND_ADD_SIZE); + free(p); + return 1; +} + int setup_tests(void) { @@ -482,5 +495,6 @@ int setup_tests(void) ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test)); ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test)); + ADD_TEST(test_rand_add); return 1; } |