From 52b6ee8245c06042fd4f1bfea32f652ebe1774f3 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 31 Mar 2011 17:15:54 +0000 Subject: [PATCH] Reorganise DRBG API so the entropy and nonce callbacks can return a pointer to a buffer instead of copying to a fixed length buffer. This removes the entropy and nonce length restrictions. --- fips/rand/fips_drbg_ctr.c | 4 ++-- fips/rand/fips_drbg_hash.c | 4 ++-- fips/rand/fips_drbg_lib.c | 40 ++++++++++++++++++++-------------- fips/rand/fips_drbg_selftest.c | 16 +++++++------- fips/rand/fips_drbgvs.c | 11 +++++----- fips/rand/fips_rand.h | 8 ++++--- fips/rand/fips_rand_lcl.h | 10 +++++---- 7 files changed, 53 insertions(+), 40 deletions(-) diff --git a/fips/rand/fips_drbg_ctr.c b/fips/rand/fips_drbg_ctr.c index 7e6d497ad1..0a5270dcef 100644 --- a/fips/rand/fips_drbg_ctr.c +++ b/fips/rand/fips_drbg_ctr.c @@ -404,9 +404,9 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx) AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks); dctx->min_entropy = cctx->keylen; - dctx->max_entropy = DRBG_MAX_ENTROPY; + dctx->max_entropy = DRBG_MAX_LENGTH; dctx->min_nonce = dctx->min_entropy / 2; - dctx->max_nonce = DRBG_MAX_NONCE; + dctx->max_nonce = DRBG_MAX_LENGTH; dctx->max_pers = DRBG_MAX_LENGTH; dctx->max_adin = DRBG_MAX_LENGTH; } diff --git a/fips/rand/fips_drbg_hash.c b/fips/rand/fips_drbg_hash.c index f6135c031f..b20d072646 100644 --- a/fips/rand/fips_drbg_hash.c +++ b/fips/rand/fips_drbg_hash.c @@ -368,10 +368,10 @@ int fips_drbg_hash_init(DRBG_CTX *dctx) dctx->min_entropy = dctx->strength / 8; - dctx->max_entropy = DRBG_MAX_ENTROPY; + dctx->max_entropy = DRBG_MAX_LENGTH; dctx->min_nonce = dctx->min_entropy / 2; - dctx->max_nonce = DRBG_MAX_NONCE; + dctx->max_nonce = DRBG_MAX_LENGTH; dctx->max_pers = DRBG_MAX_LENGTH; dctx->max_adin = DRBG_MAX_LENGTH; diff --git a/fips/rand/fips_drbg_lib.c b/fips/rand/fips_drbg_lib.c index a848ef2dd1..761b0fcc2b 100644 --- a/fips/rand/fips_drbg_lib.c +++ b/fips/rand/fips_drbg_lib.c @@ -121,7 +121,8 @@ void FIPS_drbg_free(DRBG_CTX *dctx) int FIPS_drbg_instantiate(DRBG_CTX *dctx, const unsigned char *pers, size_t perslen) { - size_t entlen, noncelen; + size_t entlen = 0, noncelen = 0; + unsigned char *nonce = NULL, *entropy = NULL; #if 0 /* Put here so error script picks them up */ @@ -153,7 +154,7 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, dctx->status = DRBG_STATUS_ERROR; - entlen = dctx->get_entropy(dctx, dctx->entropy, dctx->strength, + entlen = dctx->get_entropy(dctx, &entropy, dctx->strength, dctx->min_entropy, dctx->max_entropy); if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) @@ -164,8 +165,7 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, if (dctx->max_nonce > 0) { - - noncelen = dctx->get_nonce(dctx, dctx->nonce, + noncelen = dctx->get_nonce(dctx, &nonce, dctx->strength / 2, dctx->min_nonce, dctx->max_nonce); @@ -176,12 +176,10 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, } } - else - noncelen = 0; if (!dctx->instantiate(dctx, - dctx->entropy, entlen, - dctx->nonce, noncelen, + entropy, entlen, + nonce, noncelen, pers, perslen)) { r = FIPS_R_ERROR_INSTANTIATING_DRBG; @@ -194,8 +192,11 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, end: - OPENSSL_cleanse(dctx->entropy, sizeof(dctx->entropy)); - OPENSSL_cleanse(dctx->nonce, sizeof(dctx->nonce)); + if (entropy && dctx->cleanup_entropy) + dctx->cleanup_entropy(dctx, entropy, entlen); + + if (nonce && dctx->cleanup_nonce) + dctx->cleanup_nonce(dctx, nonce, noncelen); if (dctx->status == DRBG_STATUS_READY) return 1; @@ -210,6 +211,7 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin, size_t adinlen) { + unsigned char *entropy = NULL; size_t entlen; int r = 0; @@ -237,7 +239,7 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, dctx->status = DRBG_STATUS_ERROR; - entlen = dctx->get_entropy(dctx, dctx->entropy, dctx->strength, + entlen = dctx->get_entropy(dctx, &entropy, dctx->strength, dctx->min_entropy, dctx->max_entropy); if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) @@ -246,13 +248,15 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, goto end; } - if (!dctx->reseed(dctx, dctx->entropy, entlen, adin, adinlen)) + if (!dctx->reseed(dctx, entropy, entlen, adin, adinlen)) goto end; dctx->status = DRBG_STATUS_READY; dctx->reseed_counter = 1; end: - OPENSSL_cleanse(dctx->entropy, sizeof(dctx->entropy)); + + if (entropy && dctx->cleanup_entropy) + dctx->cleanup_entropy(dctx, entropy, entlen); if (dctx->status == DRBG_STATUS_READY) return 1; @@ -401,15 +405,19 @@ int FIPS_drbg_uninstantiate(DRBG_CTX *dctx) } int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, - size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len), - size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out, - int entropy, size_t min_len, size_t max_len)) + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen)) { if (dctx->status != DRBG_STATUS_UNINITIALISED) return 0; dctx->get_entropy = get_entropy; + dctx->cleanup_entropy = cleanup_entropy; dctx->get_nonce = get_nonce; + dctx->cleanup_nonce = cleanup_nonce; return 1; } diff --git a/fips/rand/fips_drbg_selftest.c b/fips/rand/fips_drbg_selftest.c index 31b7a0be58..a3732c1a4a 100644 --- a/fips/rand/fips_drbg_selftest.c +++ b/fips/rand/fips_drbg_selftest.c @@ -732,20 +732,20 @@ typedef struct int noncecnt; } TEST_ENT; -static size_t test_entropy(DRBG_CTX *dctx, unsigned char *out, +static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { TEST_ENT *t = FIPS_drbg_get_app_data(dctx); - memcpy(out, t->ent, t->entlen); + *pout = (unsigned char *)t->ent; t->entcnt++; return t->entlen; } -static size_t test_nonce(DRBG_CTX *dctx, unsigned char *out, +static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { TEST_ENT *t = FIPS_drbg_get_app_data(dctx); - memcpy(out, t->nonce, t->noncelen); + *pout = (unsigned char *)t->nonce; t->noncecnt++; return t->noncelen; } @@ -762,7 +762,7 @@ static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) unsigned char randout[1024]; if (!FIPS_drbg_init(dctx, td->nid, td->flags)) return 0; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, test_nonce)) + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, test_nonce, 0)) return 0; FIPS_drbg_set_app_data(dctx, &t); @@ -818,7 +818,7 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) if (!FIPS_drbg_init(dctx, td->nid, td->flags)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, test_nonce)) + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, test_nonce, 0)) goto err; FIPS_drbg_set_app_data(dctx, &t); @@ -860,7 +860,7 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) /* Instantiate with valid data. NB: errors now reported again */ if (!FIPS_drbg_init(dctx, td->nid, td->flags)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, test_nonce)) + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, test_nonce, 0)) goto err; FIPS_drbg_set_app_data(dctx, &t); @@ -914,7 +914,7 @@ static int fips_drbg_health_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA *td) if (!FIPS_drbg_init(dctx, td->nid, td->flags)) goto err; - if (!FIPS_drbg_set_callbacks(dctx, test_entropy, test_nonce)) + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, test_nonce, 0)) goto err; FIPS_drbg_set_app_data(dctx, &t); diff --git a/fips/rand/fips_drbgvs.c b/fips/rand/fips_drbgvs.c index d3b47a0954..890732e132 100644 --- a/fips/rand/fips_drbgvs.c +++ b/fips/rand/fips_drbgvs.c @@ -135,19 +135,19 @@ typedef struct size_t noncelen; } TEST_ENT; -static size_t test_entropy(DRBG_CTX *dctx, unsigned char *out, +static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { TEST_ENT *t = FIPS_drbg_get_app_data(dctx); - memcpy(out, t->ent, t->entlen); + *pout = (unsigned char *)t->ent; return t->entlen; } -static size_t test_nonce(DRBG_CTX *dctx, unsigned char *out, +static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { TEST_ENT *t = FIPS_drbg_get_app_data(dctx); - memcpy(out, t->nonce, t->noncelen); + *pout = (unsigned char *)t->nonce; return t->noncelen; } @@ -248,7 +248,8 @@ int main(int argc,char **argv) dctx = FIPS_drbg_new(nid, df | DRBG_FLAG_TEST); if (!dctx) exit (1); - FIPS_drbg_set_callbacks(dctx, test_entropy, test_nonce); + FIPS_drbg_set_callbacks(dctx, test_entropy, 0, + test_nonce, 0); FIPS_drbg_set_app_data(dctx, &t); randoutlen = (int)FIPS_drbg_get_blocklength(dctx); r = FIPS_drbg_instantiate(dctx, pers, perslen); diff --git a/fips/rand/fips_rand.h b/fips/rand/fips_rand.h index b332549ff2..f1e813680e 100644 --- a/fips/rand/fips_rand.h +++ b/fips/rand/fips_rand.h @@ -90,10 +90,12 @@ int FIPS_drbg_uninstantiate(DRBG_CTX *dctx); void FIPS_drbg_free(DRBG_CTX *dctx); int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, - size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len), - size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out, - int entropy, size_t min_len, size_t max_len)); + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen), + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len), + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen)); void *FIPS_drbg_get_app_data(DRBG_CTX *ctx); void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data); diff --git a/fips/rand/fips_rand_lcl.h b/fips/rand/fips_rand_lcl.h index 4ec4ef85f5..b3962260ed 100644 --- a/fips/rand/fips_rand_lcl.h +++ b/fips/rand/fips_rand_lcl.h @@ -153,17 +153,19 @@ struct drbg_ctx_st /* uninstantiate */ int (*uninstantiate)(DRBG_CTX *ctx); - unsigned char entropy[DRBG_MAX_ENTROPY]; - /* entropy gathering function */ - size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with entropy buffer */ + void (*cleanup_entropy)(DRBG_CTX *ctx, unsigned char *out, size_t olen); unsigned char nonce[DRBG_MAX_NONCE]; /* nonce gathering function */ - size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out, + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with nonce buffer */ + void (*cleanup_nonce)(DRBG_CTX *ctx, unsigned char *out, size_t olen); /* Continuous random number test temporary area */ /* Last block */ -- 2.25.1