]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - providers/implementations/rands/drbg_hmac.c
Implement deterministic ECDSA sign (RFC6979)
[thirdparty/openssl.git] / providers / implementations / rands / drbg_hmac.c
index 5f193fa57c8c02d166e237fbe96ee25321badd04..44241223a6264b1fea4bbd08aee877a72b1d930f 100644 (file)
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include <openssl/proverr.h>
-#include "prov/provider_util.h"
 #include "internal/thread_once.h"
 #include "prov/providercommon.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
+#include "prov/hmac_drbg.h"
 #include "drbg_local.h"
 
 static OSSL_FUNC_rand_newctx_fn drbg_hmac_new_wrapper;
@@ -32,14 +32,6 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hmac_gettable_ctx_params;
 static OSSL_FUNC_rand_get_ctx_params_fn drbg_hmac_get_ctx_params;
 static OSSL_FUNC_rand_verify_zeroization_fn drbg_hmac_verify_zeroization;
 
-typedef struct rand_drbg_hmac_st {
-    EVP_MAC_CTX *ctx;            /* H(x) = HMAC_hash OR H(x) = KMAC */
-    PROV_DIGEST digest;          /* H(x) = hash(x) */
-    size_t blocklen;
-    unsigned char K[EVP_MAX_MD_SIZE];
-    unsigned char V[EVP_MAX_MD_SIZE];
-} PROV_DRBG_HMAC;
-
 /*
  * Called twice by SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process.
  *
@@ -60,12 +52,8 @@ static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte,
                    const unsigned char *in3, size_t in3len)
 {
     EVP_MAC_CTX *ctx = hmac->ctx;
-    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
-    *params = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, hmac->K,
-                                                hmac->blocklen);
-    if (!EVP_MAC_CTX_set_params(ctx, params)
-            || !EVP_MAC_init(ctx)
+    if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
             /* K = HMAC(K, V || inbyte || [in1] || [in2] || [in3]) */
             || !EVP_MAC_update(ctx, hmac->V, hmac->blocklen)
             || !EVP_MAC_update(ctx, &inbyte, 1)
@@ -76,10 +64,7 @@ static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte,
         return 0;
 
    /* V = HMAC(K, V) */
-    *params = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, hmac->K,
-                                                hmac->blocklen);
-    return EVP_MAC_CTX_set_params(ctx, params)
-           && EVP_MAC_init(ctx)
+    return EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
            && EVP_MAC_update(ctx, hmac->V, hmac->blocklen)
            && EVP_MAC_final(ctx, hmac->V, NULL, sizeof(hmac->V));
 }
@@ -98,13 +83,11 @@ static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte,
  *
  * Returns zero if an error occurs otherwise it returns 1.
  */
-static int drbg_hmac_update(PROV_DRBG *drbg,
+static int drbg_hmac_update(PROV_DRBG_HMAC *hmac,
                             const unsigned char *in1, size_t in1len,
                             const unsigned char *in2, size_t in2len,
                             const unsigned char *in3, size_t in3len)
 {
-    PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
-
     /* (Steps 1-2) K = HMAC(K, V||0x00||provided_data). V = HMAC(K,V) */
     if (!do_hmac(hmac, 0x00, in1, in1len, in2, in2len, in3, in3len))
         return 0;
@@ -126,13 +109,11 @@ static int drbg_hmac_update(PROV_DRBG *drbg,
  *
  * Returns zero if an error occurs otherwise it returns 1.
  */
-static int drbg_hmac_instantiate(PROV_DRBG *drbg,
-                                 const unsigned char *ent, size_t ent_len,
-                                 const unsigned char *nonce, size_t nonce_len,
-                                 const unsigned char *pstr, size_t pstr_len)
+int ossl_drbg_hmac_init(PROV_DRBG_HMAC *hmac,
+                        const unsigned char *ent, size_t ent_len,
+                        const unsigned char *nonce, size_t nonce_len,
+                        const unsigned char *pstr, size_t pstr_len)
 {
-    PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
-
     if (hmac->ctx == NULL) {
         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);
         return 0;
@@ -143,17 +124,28 @@ static int drbg_hmac_instantiate(PROV_DRBG *drbg,
     /* (Step 3) V = 0x01 01...01 */
     memset(hmac->V, 0x01, hmac->blocklen);
     /* (Step 4) (K,V) = HMAC_DRBG_Update(entropy||nonce||pers string, K, V) */
-    return drbg_hmac_update(drbg, ent, ent_len, nonce, nonce_len, pstr,
+    return drbg_hmac_update(hmac, ent, ent_len, nonce, nonce_len, pstr,
                             pstr_len);
 }
+static int drbg_hmac_instantiate(PROV_DRBG *drbg,
+                                 const unsigned char *ent, size_t ent_len,
+                                 const unsigned char *nonce, size_t nonce_len,
+                                 const unsigned char *pstr, size_t pstr_len)
+{
+    return ossl_drbg_hmac_init((PROV_DRBG_HMAC *)drbg->data, ent, ent_len,
+                               nonce, nonce_len, pstr, pstr_len);
+}
 
 static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength,
                                          int prediction_resistance,
                                          const unsigned char *pstr,
-                                         size_t pstr_len)
+                                         size_t pstr_len,
+                                         const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
 
+    if (!ossl_prov_is_running() || !drbg_hmac_set_ctx_params(drbg, params))
+        return 0;
     return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
                                       pstr, pstr_len);
 }
@@ -172,8 +164,10 @@ static int drbg_hmac_reseed(PROV_DRBG *drbg,
                             const unsigned char *ent, size_t ent_len,
                             const unsigned char *adin, size_t adin_len)
 {
+    PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
+
     /* (Step 2) (K,V) = HMAC_DRBG_Update(entropy||additional_input, K, V) */
-    return drbg_hmac_update(drbg, ent, ent_len, adin, adin_len, NULL, 0);
+    return drbg_hmac_update(hmac, ent, ent_len, adin, adin_len, NULL, 0);
 }
 
 static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance,
@@ -195,19 +189,17 @@ static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance,
  *
  * Returns zero if an error occurs otherwise it returns 1.
  */
-static int drbg_hmac_generate(PROV_DRBG *drbg,
-                              unsigned char *out, size_t outlen,
-                              const unsigned char *adin, size_t adin_len)
+int ossl_drbg_hmac_generate(PROV_DRBG_HMAC *hmac,
+                            unsigned char *out, size_t outlen,
+                            const unsigned char *adin, size_t adin_len)
 {
-    PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
     EVP_MAC_CTX *ctx = hmac->ctx;
     const unsigned char *temp = hmac->V;
-    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
     /* (Step 2) if adin != NULL then (K,V) = HMAC_DRBG_Update(adin, K, V) */
     if (adin != NULL
             && adin_len > 0
-            && !drbg_hmac_update(drbg, adin, adin_len, NULL, 0, NULL, 0))
+            && !drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))
         return 0;
 
     /*
@@ -218,10 +210,7 @@ static int drbg_hmac_generate(PROV_DRBG *drbg,
      *             }
      */
     for (;;) {
-        *params = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                                    hmac->K, hmac->blocklen);
-        if (!EVP_MAC_CTX_set_params(ctx, params)
-            || !EVP_MAC_init(ctx)
+        if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
             || !EVP_MAC_update(ctx, temp, hmac->blocklen))
             return 0;
 
@@ -239,14 +228,22 @@ static int drbg_hmac_generate(PROV_DRBG *drbg,
         outlen -= hmac->blocklen;
     }
     /* (Step 6) (K,V) = HMAC_DRBG_Update(adin, K, V) */
-    if (!drbg_hmac_update(drbg, adin, adin_len, NULL, 0, NULL, 0))
+    if (!drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))
         return 0;
 
     return 1;
 }
 
-static int drbg_hmac_generate_wrapper
-    (void *vdrbg, unsigned char *out, size_t outlen, unsigned int strength,
+static int drbg_hmac_generate(PROV_DRBG *drbg,
+                              unsigned char *out, size_t outlen,
+                              const unsigned char *adin, size_t adin_len)
+{
+    return ossl_drbg_hmac_generate((PROV_DRBG_HMAC *)drbg->data, out, outlen,
+                                    adin, adin_len);
+}
+
+static int drbg_hmac_generate_wrapper(void *vdrbg,
+     unsigned char *out, size_t outlen, unsigned int strength,
      int prediction_resistance, const unsigned char *adin, size_t adin_len)
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
@@ -284,10 +281,8 @@ static int drbg_hmac_new(PROV_DRBG *drbg)
     PROV_DRBG_HMAC *hmac;
 
     hmac = OPENSSL_secure_zalloc(sizeof(*hmac));
-    if (hmac == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+    if (hmac == NULL)
         return 0;
-    }
 
     drbg->data = hmac;
     /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
@@ -334,7 +329,7 @@ static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
     if (p != NULL) {
         if (hmac->ctx == NULL)
             return 0;
-        name = EVP_MAC_name(EVP_MAC_CTX_mac(hmac->ctx));
+        name = EVP_MAC_get0_name(EVP_MAC_CTX_get0_mac(hmac->ctx));
         if (!OSSL_PARAM_set_utf8_string(p, name))
             return 0;
     }
@@ -342,7 +337,7 @@ static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST);
     if (p != NULL) {
         md = ossl_prov_digest_md(&hmac->digest);
-        if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_name(md)))
+        if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md)))
             return 0;
     }
 
@@ -377,7 +372,7 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])
      * digests.
      */
     md = ossl_prov_digest_md(&hmac->digest);
-    if (md != NULL && (EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0) {
+    if (md != NULL && (EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) {
         ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
         return 0;
     }
@@ -388,7 +383,7 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 
     if (hmac->ctx != NULL) {
         /* These are taken from SP 800-90 10.1 Table 2 */
-        hmac->blocklen = EVP_MD_size(md);
+        hmac->blocklen = EVP_MD_get_size(md);
         /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
         ctx->strength = 64 * (int)(hmac->blocklen >> 3);
         if (ctx->strength > 256)