Revise DRBG to split between internal and external flags.
[openssl.git] / fips / rand / fips_drbg_ctr.c
index 212bcf8..4483681 100644 (file)
@@ -54,8 +54,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/fips.h>
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
@@ -265,7 +263,7 @@ static void ctr_Update(DRBG_CTX *dctx,
                memcpy(cctx->V, cctx->K + 24, 8);
                }
 
-       if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
+       if (dctx->xflags & DRBG_FLAG_CTR_USE_DF)
                {
                /* If no input reuse existing derived value */
                if (in1 || nonce || in2)
@@ -318,7 +316,7 @@ static int drbg_ctr_generate(DRBG_CTX *dctx,
                {
                ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0);
                /* This means we reuse derived value */
-               if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
+               if (dctx->xflags & DRBG_FLAG_CTR_USE_DF)
                        {
                        adin = NULL;
                        adinlen = 1;
@@ -330,14 +328,24 @@ static int drbg_ctr_generate(DRBG_CTX *dctx,
        for (;;)
                {
                inc_128(cctx);
+               if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid)
+                       {
+                       AES_encrypt(cctx->V, dctx->lb, &cctx->ks);
+                       dctx->lb_valid = 1;
+                       continue;
+                       }
                if (outlen < 16)
                        {
                        /* Use K as temp space as it will be updated */
                        AES_encrypt(cctx->V, cctx->K, &cctx->ks);
+                       if (!fips_drbg_cprng_test(dctx, cctx->K))
+                               return 0;
                        memcpy(out, cctx->K, outlen);
                        break;
                        }
                AES_encrypt(cctx->V, out, &cctx->ks);
+               if (!fips_drbg_cprng_test(dctx, out))
+                       return 0;
                out += 16;
                outlen -= 16;
                if (outlen == 0)
@@ -350,6 +358,12 @@ static int drbg_ctr_generate(DRBG_CTX *dctx,
 
        }
 
+static int drbg_ctr_uninstantiate(DRBG_CTX *dctx)
+       {
+       memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX));
+       return 1;
+       }
+
 int fips_drbg_ctr_init(DRBG_CTX *dctx)
        {
        DRBG_CTR_CTX *cctx = &dctx->d.ctr;
@@ -360,12 +374,15 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx)
                {
                case NID_aes_128_ctr:
                keylen = 16;
+               break;
 
                case NID_aes_192_ctr:
                keylen = 24;
+               break;
 
                case NID_aes_256_ctr:
                keylen = 32;
+               break;
 
                default:
                return -2;
@@ -374,14 +391,14 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx)
        dctx->instantiate = drbg_ctr_instantiate;
        dctx->reseed = drbg_ctr_reseed;
        dctx->generate = drbg_ctr_generate;
-
+       dctx->uninstantiate = drbg_ctr_uninstantiate;
 
        cctx->keylen = keylen;
        dctx->strength = keylen * 8;
        dctx->blocklength = 16;
        dctx->seedlen = keylen + 16;
 
-       if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
+       if (dctx->xflags & DRBG_FLAG_CTR_USE_DF)
                {
                /* df initialisation */
                static unsigned char df_key[32] =
@@ -394,6 +411,15 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx)
                /* Set key schedule for df_key */
                AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks);
 
+               dctx->min_entropy = cctx->keylen;
+               dctx->max_entropy = DRBG_MAX_LENGTH;
+               dctx->min_nonce = dctx->min_entropy / 2;
+               dctx->max_nonce = DRBG_MAX_LENGTH;
+               dctx->max_pers = DRBG_MAX_LENGTH;
+               dctx->max_adin = DRBG_MAX_LENGTH;
+               }
+       else
+               {
                dctx->min_entropy = dctx->seedlen;
                dctx->max_entropy = dctx->seedlen;
                /* Nonce not used */
@@ -402,18 +428,9 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx)
                dctx->max_pers = dctx->seedlen;
                dctx->max_adin = dctx->seedlen;
                }
-       else
-               {
-               dctx->min_entropy = cctx->keylen;
-               dctx->max_entropy = DRBG_MAX_ENTROPY;
-               dctx->min_nonce = dctx->min_entropy / 2;
-               dctx->max_nonce = DRBG_MAX_NONCE;
-               dctx->max_pers = DRBG_MAX_LENGTH;
-               dctx->max_adin = DRBG_MAX_LENGTH;
-               }
 
-       dctx->max_request = 1<<19;
-       dctx->reseed_counter = DRBG_MAX_LENGTH;
+       dctx->max_request = 1<<16;
+       dctx->reseed_interval = 1<<24;
 
        return 1;
        }