[openssl] master update

Richard Levitte levitte at openssl.org
Fri Sep 20 06:28:56 UTC 2019


The branch master has been updated
       via  6061cd541332b0917e7001814533c01f895200a8 (commit)
       via  d3386f770a360cd77078041e496d88f7f6ba76c6 (commit)
       via  4e8b8e47c85a45d1bda3241d7b2852d82db2a255 (commit)
      from  ca392b294359a8e9ca55e685b344b485d02bc93b (commit)


- Log -----------------------------------------------------------------
commit 6061cd541332b0917e7001814533c01f895200a8
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Sep 19 15:04:53 2019 +0200

    Remove name string from PROV_CIPHER and PROV_DIGEST
    
    It was short lived, as it's not necessary any more.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9946)

commit d3386f770a360cd77078041e496d88f7f6ba76c6
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Sep 19 11:51:22 2019 +0200

    Refactor SSKDF to create the MAC contexts early
    
    The SSKDF implementation fetched the digest(s) for the underlying MAC,
    just to get their names and pass those down to the MAC, which in turn
    would fetch those same digests again.
    
    This change circumvents this by fetching the MAC and create the MAC
    contexts for them directly when this PRF receives the relevant
    parameters, thus only having to pass EVP_MAC_CTX pointers around.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9946)

commit 4e8b8e47c85a45d1bda3241d7b2852d82db2a255
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Sep 19 11:47:46 2019 +0200

    Refactor TLS-PRF's kdf_tls1_prf_mkmacctx() to a provider utility
    
    ossl_prov_macctx_load_from_params() creates a EVP_MAC_CTX *, or sets
    new common parameters for an existing one.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9946)

-----------------------------------------------------------------------

Summary of changes:
 include/openssl/core_names.h                      |  5 +-
 providers/common/include/internal/provider_util.h | 32 ++++++--
 providers/common/kdfs/sskdf.c                     | 85 ++++++++------------
 providers/common/kdfs/tls1_prf.c                  | 62 +++-----------
 providers/common/provider_util.c                  | 98 ++++++++++++++++++++---
 5 files changed, 156 insertions(+), 126 deletions(-)

diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index e1bc43d8db..ad4cf50bb5 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -47,6 +47,7 @@ extern "C" {
  */
 #define OSSL_ALG_PARAM_DIGEST       "digest"    /* utf8_string */
 #define OSSL_ALG_PARAM_CIPHER       "cipher"    /* utf8_string */
+#define OSSL_ALG_PARAM_MAC          "mac"       /* utf8_string */
 #define OSSL_ALG_PARAM_ENGINE       "engine"    /* utf8_string */
 #define OSSL_ALG_PARAM_PROPERTIES   "properties"/* utf8_string */
 
@@ -108,8 +109,8 @@ extern "C" {
 #define OSSL_KDF_PARAM_KEY          "key"       /* octet string */
 #define OSSL_KDF_PARAM_SALT         "salt"      /* octet string */
 #define OSSL_KDF_PARAM_PASSWORD     "pass"      /* octet string */
-#define OSSL_KDF_PARAM_DIGEST       OSSL_ALG_PARAM_DIGEST    /* utf8 string */
-#define OSSL_KDF_PARAM_MAC          "mac"       /* utf8 string */
+#define OSSL_KDF_PARAM_DIGEST       OSSL_ALG_PARAM_DIGEST     /* utf8 string */
+#define OSSL_KDF_PARAM_MAC          OSSL_ALG_PARAM_MAC        /* utf8 string */
 #define OSSL_KDF_PARAM_MAC_SIZE     "maclen"    /* size_t */
 #define OSSL_KDF_PARAM_ENGINE       OSSL_ALG_PARAM_ENGINE     /* utf8 string */
 #define OSSL_KDF_PARAM_PROPERTIES   OSSL_ALG_PARAM_PROPERTIES /* utf8 string */
diff --git a/providers/common/include/internal/provider_util.h b/providers/common/include/internal/provider_util.h
index 9fe21c5ef6..9925ac2b09 100644
--- a/providers/common/include/internal/provider_util.h
+++ b/providers/common/include/internal/provider_util.h
@@ -21,9 +21,6 @@ typedef struct {
 
     /* Conditions for legacy EVP_CIPHER uses */
     ENGINE *engine;             /* cipher engine */
-
-    /* Name this was fetched by */
-    char name[51];               /* A longer name would be unexpected */
 } PROV_CIPHER;
 
 typedef struct {
@@ -37,9 +34,6 @@ typedef struct {
 
     /* Conditions for legacy EVP_MD uses */
     ENGINE *engine;             /* digest engine */
-
-    /* Name this was fetched by */
-    char name[51];               /* A longer name would be unexpected */
 } PROV_DIGEST;
 
 /* Cipher functions */
@@ -62,7 +56,6 @@ int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src);
 /* Query the cipher and associated engine (if any) */
 const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc);
 ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc);
-const char *ossl_prov_cipher_name(const PROV_CIPHER *pc);
 
 /* Digest functions */
 /*
@@ -84,4 +77,27 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
 /* Query the digest and associated engine (if any) */
 const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
 ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
-const char *ossl_prov_digest_name(const PROV_DIGEST *pd);
+
+/* MAC functions */
+/*
+ * Load an EVP_MAC_CTX* from the specified parameters with the specified
+ * library context.
+ * The params "mac" and "properties" are used to determine the implementation
+ * used, and the parameters "digest", "cipher", "engine" and "properties" are
+ * passed to the MAC via the created MAC context if they are given.
+ * If there is already a created MAC context, it will be replaced if the "mac"
+ * parameter is found, otherwise it will simply be used as is, and passed the
+ * parameters to pilfer as it sees fit.
+ *
+ * As an option, a MAC name may be explicitly given, and if it is, the "mac"
+ * parameter will be ignored.
+ * Similarly, as an option, a cipher name or a digest name may be explicitly
+ * given, and if any of them is, the "digest" and "cipher" parameters are
+ * ignored.
+ */
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+                                      const OSSL_PARAM params[],
+                                      const char *macname,
+                                      const char *ciphername,
+                                      const char *mdname,
+                                      OPENSSL_CTX *ctx);
diff --git a/providers/common/kdfs/sskdf.c b/providers/common/kdfs/sskdf.c
index 49da1a690f..d74da436a2 100644
--- a/providers/common/kdfs/sskdf.c
+++ b/providers/common/kdfs/sskdf.c
@@ -52,8 +52,8 @@
 
 typedef struct {
     void *provctx;
-    EVP_MAC *mac;       /* H(x) = HMAC_hash OR H(x) = KMAC */
-    PROV_DIGEST digest;
+    EVP_MAC_CTX *macctx;         /* H(x) = HMAC_hash OR H(x) = KMAC */
+    PROV_DIGEST digest;          /* H(x) = hash(x) */
     unsigned char *secret;
     size_t secret_len;
     unsigned char *info;
@@ -207,7 +207,7 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
  *     H(x) = HMAC-hash(salt, x) OR
  *     H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
  */
-static int SSKDF_mac_kdm(EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
+static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init,
                          const unsigned char *kmac_custom,
                          size_t kmac_custom_len, size_t kmac_out_len,
                          const unsigned char *salt, size_t salt_len,
@@ -220,30 +220,18 @@ static int SSKDF_mac_kdm(EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
     unsigned char c[4];
     unsigned char mac_buf[EVP_MAX_MD_SIZE];
     unsigned char *out = derived_key;
-    EVP_MAC_CTX *ctx = NULL, *ctx_init = NULL;
+    EVP_MAC_CTX *ctx = NULL;
     unsigned char *mac = mac_buf, *kmac_buffer = NULL;
-    OSSL_PARAM params[3];
-    size_t params_n = 0;
+    OSSL_PARAM params[2], *p = params;
 
     if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
             || derived_key_len > SSKDF_MAX_INLEN
             || derived_key_len == 0)
         return 0;
 
-    ctx_init = EVP_MAC_CTX_new(kdf_mac);
-    if (ctx_init == NULL)
-        goto end;
-
-    if (hmac_md != NULL) {
-        const char *mdname = EVP_MD_name(hmac_md);
-        params[params_n++] =
-            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
-                                             (char *)mdname, 0);
-    }
-    params[params_n++] =
-        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (void *)salt,
-                                          salt_len);
-    params[params_n] = OSSL_PARAM_construct_end();
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                             (void *)salt, salt_len);
+    *p = OSSL_PARAM_construct_end();
 
     if (!EVP_MAC_CTX_set_params(ctx_init, params))
         goto end;
@@ -298,7 +286,6 @@ end:
         OPENSSL_cleanse(mac_buf, sizeof(mac_buf));
 
     EVP_MAC_CTX_free(ctx);
-    EVP_MAC_CTX_free(ctx_init);
     return ret;
 }
 
@@ -316,8 +303,8 @@ static void sskdf_reset(void *vctx)
 {
     KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
 
+    EVP_MAC_CTX_free(ctx->macctx);
     ossl_prov_digest_reset(&ctx->digest);
-    EVP_MAC_free(ctx->mac);
     OPENSSL_clear_free(ctx->secret, ctx->secret_len);
     OPENSSL_clear_free(ctx->info, ctx->info_len);
     OPENSSL_clear_free(ctx->salt, ctx->salt_len);
@@ -365,33 +352,34 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
         return 0;
     }
 
-    if (ctx->mac != NULL) {
+    if (ctx->macctx != NULL) {
         /* H(x) = KMAC or H(x) = HMAC */
         int ret;
         const unsigned char *custom = NULL;
         size_t custom_len = 0;
         int default_salt_len;
+        EVP_MAC *mac = EVP_MAC_CTX_mac(ctx->macctx);
 
         /*
          * TODO(3.0) investigate the necessity to have all these controls.
          * Why does KMAC require a salt length that's shorter than the MD
          * block size?
          */
-        if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_HMAC)) {
+        if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_HMAC)) {
             /* H(x) = HMAC(x, salt, hash) */
             if (md == NULL) {
                 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
                 return 0;
             }
-            default_salt_len = EVP_MD_block_size(md);
+            default_salt_len = EVP_MD_size(md);
             if (default_salt_len <= 0)
                 return 0;
-        } else if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC128)
-                   || EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC256)) {
+        } else if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128)
+                   || EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC256)) {
             /* H(x) = KMACzzz(x, salt, custom) */
             custom = kmac_custom_str;
             custom_len = sizeof(kmac_custom_str);
-            if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC128))
+            if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128))
                 default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
             else
                 default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
@@ -408,7 +396,7 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
             }
             ctx->salt_len = default_salt_len;
         }
-        ret = SSKDF_mac_kdm(ctx->mac, md,
+        ret = SSKDF_mac_kdm(ctx->macctx,
                             custom, custom_len, ctx->out_len,
                             ctx->salt, ctx->salt_len,
                             ctx->secret, ctx->secret_len,
@@ -435,43 +423,34 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen)
         return 0;
     }
 
-    if (ctx->mac != NULL) {
+    if (ctx->macctx != NULL) {
         ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
         return 0;
-    } else {
-        /* H(x) = hash */
-        if (md == NULL) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
-            return 0;
-        }
-        return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
-                              ctx->info, ctx->info_len, 1, key, keylen);
     }
+
+    /* H(x) = hash */
+    if (md == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
+        return 0;
+    }
+
+    return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
+                          ctx->info, ctx->info_len, 1, key, keylen);
 }
 
 static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     const OSSL_PARAM *p;
     KDF_SSKDF *ctx = vctx;
-    OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
-    EVP_MAC *mac;
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
     size_t sz;
-    const char *properties = NULL;
 
-    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+    if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
         return 0;
 
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MAC)) != NULL) {
-        EVP_MAC_free(ctx->mac);
-        ctx->mac = NULL;
-
-        mac = EVP_MAC_fetch(PROV_LIBRARY_CONTEXT_OF(ctx->provctx), p->data,
-                            properties);
-        if (mac == NULL)
-            return 0;
-        EVP_MAC_free(ctx->mac);
-        ctx->mac = mac;
-    }
+    if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params,
+                                           NULL, NULL, NULL, libctx))
+        return 0;
 
     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL
         || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
diff --git a/providers/common/kdfs/tls1_prf.c b/providers/common/kdfs/tls1_prf.c
index 0acdcdf3b8..3053b756dc 100644
--- a/providers/common/kdfs/tls1_prf.c
+++ b/providers/common/kdfs/tls1_prf.c
@@ -145,51 +145,6 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key,
                         key, keylen);
 }
 
-static EVP_MAC_CTX *kdf_tls1_prf_mkmacctx(OPENSSL_CTX *libctx,
-                                          const char *mdname,
-                                          const OSSL_PARAM params[])
-{
-    const OSSL_PARAM *p;
-    OSSL_PARAM mac_params[5], *mp = mac_params;
-    const char *properties = NULL;
-    /* TODO(3.0) rethink "flags", also see hmac.c in providers */
-    int mac_flags = EVP_MD_CTX_FLAG_NON_FIPS_ALLOW;
-    EVP_MAC_CTX *macctx = NULL;
-
-    *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
-                                             (char *)mdname, 0);
-#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ENGINE)) != NULL)
-        *mp++ = *p;
-#endif
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_KDF_PARAM_PROPERTIES)) != NULL) {
-        properties = p->data;
-        *mp++ = *p;
-    }
-    *mp++ = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &mac_flags);
-    *mp = OSSL_PARAM_construct_end();
-
-    /* Implicit fetch */
-    {
-        EVP_MAC *mac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_HMAC, properties);
-
-        macctx = EVP_MAC_CTX_new(mac);
-        /* The context holds on to the MAC */
-        EVP_MAC_free(mac);
-        if (macctx == NULL)
-            goto err;
-    }
-
-    if (EVP_MAC_CTX_set_params(macctx, mac_params))
-        goto done;
- err:
-    EVP_MAC_CTX_free(macctx);
-    macctx = NULL;
- done:
-    return macctx;
-}
-
 static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     const OSSL_PARAM *p;
@@ -197,13 +152,20 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
 
     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
-        EVP_MAC_CTX_free(ctx->P_hash);
-        EVP_MAC_CTX_free(ctx->P_sha1);
         if (strcasecmp(p->data, SN_md5_sha1) == 0) {
-            ctx->P_hash = kdf_tls1_prf_mkmacctx(libctx, SN_md5, params);
-            ctx->P_sha1 = kdf_tls1_prf_mkmacctx(libctx, SN_sha1, params);
+            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+                                                   OSSL_MAC_NAME_HMAC,
+                                                   NULL, SN_md5, libctx)
+                || !ossl_prov_macctx_load_from_params(&ctx->P_sha1, params,
+                                                      OSSL_MAC_NAME_HMAC,
+                                                      NULL, SN_sha1, libctx))
+                return 0;
         } else {
-            ctx->P_hash = kdf_tls1_prf_mkmacctx(libctx, p->data, params);
+            EVP_MAC_CTX_free(ctx->P_sha1);
+            if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+                                                   OSSL_MAC_NAME_HMAC,
+                                                   NULL, NULL, libctx))
+                return 0;
         }
     }
 
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
index 199544730a..796d00d376 100644
--- a/providers/common/provider_util.c
+++ b/providers/common/provider_util.c
@@ -17,7 +17,6 @@ void ossl_prov_cipher_reset(PROV_CIPHER *pc)
     pc->alloc_cipher = NULL;
     pc->cipher = NULL;
     pc->engine = NULL;
-    pc->name[0] = '\0';
 }
 
 int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
@@ -27,7 +26,6 @@ int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
     dst->engine = src->engine;
     dst->cipher = src->cipher;
     dst->alloc_cipher = src->alloc_cipher;
-    OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
     return 1;
 }
 
@@ -79,7 +77,6 @@ int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
 
     EVP_CIPHER_free(pc->alloc_cipher);
     pc->cipher = pc->alloc_cipher = EVP_CIPHER_fetch(ctx, p->data, propquery);
-    OPENSSL_strlcpy(pc->name, p->data, sizeof(pc->name));
     /* TODO legacy stuff, to be removed */
 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy ciphers */
     if (pc->cipher == NULL)
@@ -98,18 +95,12 @@ ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc)
     return pc->engine;
 }
 
-const char *ossl_prov_cipher_name(const PROV_CIPHER *pc)
-{
-    return pc->name;
-}
-
 void ossl_prov_digest_reset(PROV_DIGEST *pd)
 {
     EVP_MD_free(pd->alloc_md);
     pd->alloc_md = NULL;
     pd->md = NULL;
     pd->engine = NULL;
-    pd->name[0] = '\0';
 }
 
 int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
@@ -119,7 +110,6 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
     dst->engine = src->engine;
     dst->md = src->md;
     dst->alloc_md = src->alloc_md;
-    OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
     return 1;
 }
 
@@ -142,7 +132,6 @@ int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
 
     EVP_MD_free(pd->alloc_md);
     pd->md = pd->alloc_md = EVP_MD_fetch(ctx, p->data, propquery);
-    OPENSSL_strlcpy(pd->name, p->data, sizeof(pd->name));
     /* TODO legacy stuff, to be removed */
 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
     if (pd->md == NULL)
@@ -161,7 +150,90 @@ ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
     return pd->engine;
 }
 
-const char *ossl_prov_digest_name(const PROV_DIGEST *pd)
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+                                      const OSSL_PARAM params[],
+                                      const char *macname,
+                                      const char *ciphername,
+                                      const char *mdname,
+                                      OPENSSL_CTX *libctx)
 {
-    return pd->name;
+    const OSSL_PARAM *p;
+    OSSL_PARAM mac_params[5], *mp = mac_params;
+    const char *properties = NULL;
+
+    if (macname == NULL
+        && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        macname = p->data;
+    }
+    if ((p = OSSL_PARAM_locate_const(params,
+                                     OSSL_ALG_PARAM_PROPERTIES)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        properties = p->data;
+    }
+
+    /* If we got a new mac name, we make a new EVP_MAC_CTX */
+    if (macname != NULL) {
+        EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties);
+
+        EVP_MAC_CTX_free(*macctx);
+        *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac);
+        /* The context holds on to the MAC */
+        EVP_MAC_free(mac);
+        if (*macctx == NULL)
+            return 0;
+    }
+
+    /*
+     * If there is no MAC yet (and therefore, no MAC context), we ignore
+     * all other parameters.
+     */
+    if (*macctx == NULL)
+        return 1;
+
+    if (mdname == NULL) {
+        if ((p = OSSL_PARAM_locate_const(params,
+                                         OSSL_ALG_PARAM_DIGEST)) != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                return 0;
+            mdname = p->data;
+        }
+    }
+    if (ciphername == NULL) {
+        if ((p = OSSL_PARAM_locate_const(params,
+                                         OSSL_ALG_PARAM_CIPHER)) != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                return 0;
+            ciphername = p->data;
+        }
+    }
+
+    if (mdname != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+                                                 (char *)mdname, 0);
+    if (ciphername != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+                                                 (char *)ciphername, 0);
+    if (properties != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
+                                                 (char *)properties, 0);
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
+                                                 p->data, p->data_size);
+    }
+#endif
+    *mp = OSSL_PARAM_construct_end();
+
+    if (EVP_MAC_CTX_set_params(*macctx, mac_params))
+        return 1;
+
+    EVP_MAC_CTX_free(*macctx);
+    *macctx = NULL;
+    return 0;
 }


More information about the openssl-commits mailing list