Add FIPS selftests for ECDH algorithm.
[openssl.git] / fips / rand / fips_drbg_ec.c
index 0b674199bbb032e37d0827f0daa8a16d30a720bd..6be6534ce75daae1e65b5fc10e97e4b3c6c44073 100644 (file)
@@ -218,7 +218,7 @@ static int drbg_ec_mul(DRBG_EC_CTX *ectx, BIGNUM *r, const BIGNUM *s, int use_q)
        if (!EC_POINT_get_affine_coordinates_GFp(ectx->curve, ectx->ptmp, r,
                                                        NULL, ectx->bctx))
                return 0;
-       return 0;
+       return 1;
        }
 
 static int drbg_ec_instantiate(DRBG_CTX *dctx,
@@ -241,13 +241,6 @@ static int drbg_ec_reseed(DRBG_CTX *dctx,
                                const unsigned char *adin, size_t adin_len)
        {
        DRBG_EC_CTX *ectx = &dctx->d.ec;
-       /* Check if we have a deferred s = s * P */
-       if (ectx->sp_defer)
-               {
-               if (drbg_ec_mul(ectx, ectx->s, ectx->s, 0))
-                       return 0;
-               ectx->sp_defer = 0;
-               }
        /* Convert s value to a binary buffer. Save it to tbuf as we are
         * about to overwrite it.
         */
@@ -278,26 +271,21 @@ static int drbg_ec_generate(DRBG_CTX *dctx,
                        dctx->status = DRBG_STATUS_RESEED;
                return 1;
                }
-       /* Check if we have a deferred s = s * P */
-       if (ectx->sp_defer)
-               {
-               if (drbg_ec_mul(ectx, s, s, 0))
-                       goto err;
-               ectx->sp_defer = 0;
-               }
 
        BN_CTX_start(ectx->bctx);
-       t = BN_CTX_get(ectx->bctx);
        r = BN_CTX_get(ectx->bctx);
        if (!r)
                goto err;
        if (adin && adin_len)
                {
                size_t i;
+               t = BN_CTX_get(ectx->bctx);
+               if (!t)
+                       goto err;
                /* Convert s to buffer */
                if (ectx->exbits)
-                       BN_lshift(ectx->s, ectx->s, ectx->exbits);
-               bn2binpad(ectx->sbuf, dctx->seedlen, ectx->s);
+                       BN_lshift(s, s, ectx->exbits);
+               bn2binpad(ectx->sbuf, dctx->seedlen, s);
                /* Step 2 */
                if (!hash_df(dctx, ectx->tbuf, adin, adin_len,
                                NULL, 0, NULL, 0))
@@ -309,23 +297,25 @@ static int drbg_ec_generate(DRBG_CTX *dctx,
                        return 0;
                }
        else
-               if (!BN_copy(t, ectx->s))
-                       goto err;
+               /* Note if no additional input the algorithm never
+                * needs separate values for t and s.
+                */
+               t = s;
 
 #ifdef EC_DRBG_TRACE
-       bnprint(stderr, "s at start of generate: ", ectx->s);
+       bnprint(stderr, "s at start of generate: ", s);
 #endif
 
        for (;;)
                {
                /* Step #6, calculate s = t * P */
-               if (drbg_ec_mul(ectx, s, t, 0))
+               if (!drbg_ec_mul(ectx, s, t, 0))
                        goto err;
 #ifdef EC_DRBG_TRACE
                bnprint(stderr, "s in generate: ", ectx->s);
 #endif
                /* Step #7, calculate r = s * Q */
-               if (drbg_ec_mul(ectx, r, s, 1))
+               if (!drbg_ec_mul(ectx, r, s, 1))
                        goto err;
 #ifdef EC_DRBG_TRACE
        bnprint(stderr, "r in generate is: ", r);
@@ -333,7 +323,7 @@ static int drbg_ec_generate(DRBG_CTX *dctx,
                dctx->reseed_counter++;
                /* Get rightmost bits of r to output buffer */
 
-               if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid)
+               if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid)
                        {
                        if (!bn2binpad(dctx->lb, dctx->blocklength, r))
                                goto err;
@@ -360,13 +350,15 @@ static int drbg_ec_generate(DRBG_CTX *dctx,
                if (!outlen)
                        break;
                out += dctx->blocklength;
+               /* Step #5 after first pass */
+               t = s;
 #ifdef EC_DRBG_TRACE
                fprintf(stderr, "Random bits written:\n");
                hexprint(stderr, out, dctx->blocklength);
 #endif
                }
-       /* Defer s = s * P until we need it */
-       ectx->sp_defer = 1;
+       if (!drbg_ec_mul(ectx, ectx->s, ectx->s, 0))
+               return 0;
 #ifdef EC_DRBG_TRACE
        bnprint(stderr, "s after generate is: ", s);
 #endif
@@ -493,7 +485,7 @@ int fips_drbg_ec_init(DRBG_CTX *dctx)
                return -2;
                }
 
-       dctx->flags |= DRBG_CUSTOM_RESEED;
+       dctx->iflags |= DRBG_CUSTOM_RESEED;
        dctx->reseed_counter = 0;
        dctx->instantiate = drbg_ec_instantiate;
        dctx->reseed = drbg_ec_reseed;
@@ -528,8 +520,6 @@ int fips_drbg_ec_init(DRBG_CTX *dctx)
        ectx->Q = EC_POINT_new(ectx->curve);
        ectx->ptmp = EC_POINT_new(ectx->curve);
 
-       ectx->sp_defer = 0;
-
        x = BN_CTX_get(ectx->bctx);
        y = BN_CTX_get(ectx->bctx);