Reorganise DRBG API so the entropy and nonce callbacks can return a
authorDr. Stephen Henson <steve@openssl.org>
Thu, 31 Mar 2011 17:15:54 +0000 (17:15 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 31 Mar 2011 17:15:54 +0000 (17:15 +0000)
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
fips/rand/fips_drbg_hash.c
fips/rand/fips_drbg_lib.c
fips/rand/fips_drbg_selftest.c
fips/rand/fips_drbgvs.c
fips/rand/fips_rand.h
fips/rand/fips_rand_lcl.h

index 7e6d497ad1f9c94abd7c196a5a0783844900048a..0a5270dcefaf12cdd74feda359bda488279ca9f8 100644 (file)
@@ -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;
                }
index f6135c031f8f35ebd7192eb673235f96fac019ed..b20d0726466af0f405fb89e4668a977882fdc5b0 100644 (file)
@@ -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;
index a848ef2dd16fd3822697fe819537ead2c2f11566..761b0fcc2ba4e91ff3425ea3a0fd5d3fce43605f 100644 (file)
@@ -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;
        }
 
index 31b7a0be58529f0a34ab3f9bbac7aa7e44c3e256..a3732c1a4abf0aaeefe279b4ff68ab95449621c2 100644 (file)
@@ -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);
 
index d3b47a0954ea15d63e3adc740ed265444c1926cf..890732e132643850b09d0b0da55f1bf6b27ea40d 100644 (file)
@@ -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);
index b332549ff271a046075bf9852702dc62d9ecc8bc..f1e813680e1c405a877f4b1b43dab74141793096 100644 (file)
@@ -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);
index 4ec4ef85f50811794a109a91c67e238debe13bd3..b3962260ed0df49c2d3fdab3890fe94d5e474665 100644 (file)
@@ -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 */