[openssl] master update

dev at ddvo.net dev at ddvo.net
Sat May 8 12:36:58 UTC 2021


The branch master has been updated
       via  0a8a6afdfb71e42962921980b51942cea8632697 (commit)
       via  bea31afef013aaf5638e96e9bed1b633c510d50d (commit)
      from  0f4fb64785dbdb074b6a0e7f415697ad74596c0c (commit)


- Log -----------------------------------------------------------------
commit 0a8a6afdfb71e42962921980b51942cea8632697
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Mar 29 19:42:33 2021 +0200

    Add quick one-shot EVP_Q_mac() and deprecation compensation decls for MAC functions
    
    This helps compensating for deprecated functions such as HMAC()
    and reduces clutter in the crypto lib, apps, and tests.
    Also fixes memory leaks in generate_cookie_callback() of apps/lib/s_cb.c.
    and replaces 'B<...>' by 'I<...>' where appropriate in HMAC.pod
    
    Partially fixes #14628.
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14664)

commit bea31afef013aaf5638e96e9bed1b633c510d50d
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Mar 24 09:11:13 2021 +0100

    DOC: Fix all wrong occurrences of '<propq>' to 'I<propq>'
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14664)

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

Summary of changes:
 CHANGES.md                             |  8 ++---
 apps/lib/s_cb.c                        | 35 ++++---------------
 crypto/crmf/crmf_pbm.c                 | 24 +++++--------
 crypto/evp/mac_lib.c                   | 62 ++++++++++++++++++++++++++++++++++
 crypto/hmac/hmac.c                     | 42 ++++++-----------------
 doc/man3/EVP_MAC.pod                   | 30 +++++++++++++---
 doc/man3/HMAC.pod                      | 59 ++++++++++++++++----------------
 doc/man3/PEM_X509_INFO_read_bio_ex.pod |  3 +-
 doc/man3/SSL_load_client_CA_file.pod   |  4 +--
 doc/man3/X509_LOOKUP.pod               | 16 ++++-----
 doc/man3/X509_STORE_add_cert.pod       | 14 ++++----
 doc/man3/X509_new.pod                  |  2 +-
 include/openssl/evp.h                  |  5 +++
 include/openssl/hmac.h                 |  9 ++---
 providers/fips-sources.checksums       |  6 ++--
 providers/fips.checksum                |  2 +-
 providers/implementations/kdfs/hkdf.c  | 30 +++++++++-------
 ssl/tls13_enc.c                        | 26 ++++----------
 test/hmactest.c                        | 23 ++++++-------
 util/libcrypto.num                     |  3 +-
 20 files changed, 217 insertions(+), 186 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 29d28f91ab..a2ef2f6b3f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1033,18 +1033,18 @@ OpenSSL 3.0
 
    *Paul Dale*
 
- * All of the low level HMAC functions have been deprecated including:
+ * All low level HMAC functions except for HMAC have been deprecated including:
 
-   HMAC, HMAC_size, HMAC_CTX_new, HMAC_CTX_reset, HMAC_CTX_free,
+   HMAC_size, HMAC_CTX_new, HMAC_CTX_reset, HMAC_CTX_free,
    HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_copy, HMAC_CTX_set_flags
    and HMAC_CTX_get_md.
 
    Use of these low level functions has been informally discouraged for a long
    time.  Instead applications should use L<EVP_MAC_CTX_new(3)>,
    L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
-   and L<EVP_MAC_final(3)>.
+   and L<EVP_MAC_final(3)> or the single-shot MAC function L<EVP_Q_mac(3)>.
 
-   *Paul Dale*
+   *Paul Dale and David von Oheimb*
 
  * Over two thousand fixes were made to the documentation, including:
    - Common options (such as -rand/-writerand, TLS version control, etc)
diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c
index 0bb4b6c436..bdd5051ee6 100644
--- a/apps/lib/s_cb.c
+++ b/apps/lib/s_cb.c
@@ -739,10 +739,6 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
     unsigned short port;
     BIO_ADDR *lpeer = NULL, *peer = NULL;
     int res = 0;
-    EVP_MAC *hmac = NULL;
-    EVP_MAC_CTX *ctx = NULL;
-    OSSL_PARAM params[2], *p = params;
-    size_t mac_len;
 
     /* Initialize a random secret */
     if (!cookie_initialized) {
@@ -780,32 +776,13 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
     memcpy(buffer, &port, sizeof(port));
     BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL);
 
-    /* Calculate HMAC of buffer using the secret */
-    hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
-    if (hmac == NULL) {
-            BIO_printf(bio_err, "HMAC not found\n");
-            goto end;
-    }
-    ctx = EVP_MAC_CTX_new(hmac);
-    if (ctx == NULL) {
-            BIO_printf(bio_err, "HMAC context allocation failed\n");
-            goto end;
-    }
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA1", 0);
-    *p = OSSL_PARAM_construct_end();
-    if (!EVP_MAC_init(ctx, cookie_secret, COOKIE_SECRET_LENGTH, params)) {
-            BIO_printf(bio_err, "HMAC context initialisation failed\n");
-            goto end;
-    }
-    if (!EVP_MAC_update(ctx, buffer, length)) {
-            BIO_printf(bio_err, "HMAC context update failed\n");
-            goto end;
-    }
-    if (!EVP_MAC_final(ctx, cookie, &mac_len, DTLS1_COOKIE_LENGTH)) {
-            BIO_printf(bio_err, "HMAC context final failed\n");
-            goto end;
+    if (EVP_Q_mac(NULL, "HMAC", NULL, "SHA1", NULL,
+                  cookie_secret, COOKIE_SECRET_LENGTH, buffer, length,
+                  cookie, DTLS1_COOKIE_LENGTH, cookie_len) == NULL) {
+        BIO_printf(bio_err,
+                   "Error calculating HMAC-SHA1 of buffer with secret\n");
+        goto end;
     }
-    *cookie_len = (int)mac_len;
     res = 1;
 end:
     OPENSSL_free(buffer);
diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c
index 40a41c28b2..cf483dcb9a 100644
--- a/crypto/crmf/crmf_pbm.c
+++ b/crypto/crmf/crmf_pbm.c
@@ -16,6 +16,7 @@
 
 #include <openssl/rand.h>
 #include <openssl/evp.h>
+#include <openssl/hmac.h>
 
 /* explicit #includes not strictly needed since implied by the above: */
 #include <openssl/asn1t.h>
@@ -120,8 +121,8 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen,
  * |msglen| length of the message
  * |sec| key to use
  * |seclen| length of the key
- * |mac| pointer to the computed mac, will be set on success
- * |maclen| if not NULL, will set variable to the length of the mac on success
+ * |out| pointer to the computed mac, will be set on success
+ * |outlen| if not NULL, will set variable to the length of the mac on success
  * returns 1 on success, 0 on error
  */
 /* TODO try to combine with other MAC calculations in the libray */
@@ -140,10 +141,8 @@ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq,
     unsigned int bklen = EVP_MAX_MD_SIZE;
     int64_t iterations;
     unsigned char *mac_res = 0;
+    unsigned int maclen;
     int ok = 0;
-    EVP_MAC *mac = NULL;
-    EVP_MAC_CTX *mctx = NULL;
-    OSSL_PARAM macparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
     if (out == NULL || pbmp == NULL || pbmp->mac == NULL
             || pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
@@ -208,23 +207,16 @@ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq,
         ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM);
         goto err;
     }
-
-    macparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
-                                                    (char *)hmac_mdname, 0);
-    if ((mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL
-            || (mctx = EVP_MAC_CTX_new(mac)) == NULL
-            || !EVP_MAC_CTX_set_params(mctx, macparams)
-            || !EVP_MAC_init(mctx, basekey, bklen, macparams)
-            || !EVP_MAC_update(mctx, msg, msglen)
-            || !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
+    /* TODO generalize to non-HMAC: */
+    if (EVP_Q_mac(libctx, "HMAC", propq, hmac_mdname, NULL, basekey, bklen,
+                  msg, msglen, mac_res, EVP_MAX_MD_SIZE, &maclen) == NULL)
         goto err;
 
+    *outlen = (size_t)maclen;
     ok = 1;
 
  err:
     OPENSSL_cleanse(basekey, bklen);
-    EVP_MAC_CTX_free(mctx);
-    EVP_MAC_free(mac);
     EVP_MD_free(owf);
     EVP_MD_CTX_free(ctx);
 
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index 6f97de94de..8a34df3757 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -222,3 +222,65 @@ int EVP_MAC_names_do_all(const EVP_MAC *mac,
 
     return 1;
 }
+
+unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+                         const char *subalg, const OSSL_PARAM *params,
+                         const void *key, size_t keylen,
+                         const unsigned char *data, size_t datalen,
+                         unsigned char *out, size_t outsize, unsigned int *outlen)
+{
+    EVP_MAC *mac = EVP_MAC_fetch(libctx, name, propq);
+    OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    EVP_MAC_CTX *ctx  = NULL;
+    size_t len;
+    unsigned char *res = NULL;
+
+    if (outlen != NULL)
+        *outlen = 0;
+    if (mac == NULL)
+        return NULL;
+    if (subalg != NULL) {
+        const OSSL_PARAM *defined_params = EVP_MAC_settable_ctx_params(mac);
+        const char *param_name = OSSL_MAC_PARAM_DIGEST;
+
+        /*
+         * The underlying algorithm may be a cipher or a digest.
+         * We don't know which it is, but we can ask the MAC what it
+         * should be and bet on that.
+         */
+        if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) {
+            param_name = OSSL_MAC_PARAM_CIPHER;
+            if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) {
+                ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
+                goto err;
+            }
+        }
+        subalg_param[0] =
+            OSSL_PARAM_construct_utf8_string(param_name, (char *)subalg, 0);
+    }
+    /* Single-shot - on NULL key input, set dummy key value for EVP_MAC_Init. */
+    if (key == NULL && keylen == 0)
+        key = data;
+    if ((ctx = EVP_MAC_CTX_new(mac)) != NULL
+            && EVP_MAC_CTX_set_params(ctx, subalg_param)
+            && EVP_MAC_CTX_set_params(ctx, params)
+            && EVP_MAC_init(ctx, key, keylen, params)
+            && EVP_MAC_update(ctx, data, datalen)
+            && EVP_MAC_final(ctx, out, &len, outsize)) {
+        if (out == NULL) {
+            out = OPENSSL_malloc(len);
+            if (out != NULL && !EVP_MAC_final(ctx, out, NULL, len)) {
+                OPENSSL_free(out);
+                out = NULL;
+            }
+        }
+        res = out;
+        if (res != NULL && outlen != NULL)
+            *outlen = (unsigned int)len;
+    }
+
+ err:
+    EVP_MAC_CTX_free(ctx);
+    EVP_MAC_free(mac);
+    return res;
+}
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index 6c1a70e4bd..6d142f2cbb 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -17,8 +17,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include "internal/cryptlib.h"
-#include <openssl/hmac.h>
 #include <openssl/opensslconf.h>
+#include <openssl/hmac.h>
+#include <openssl/core_names.h>
 #include "hmac_local.h"
 
 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
@@ -34,13 +35,12 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
     if (md != NULL && md != ctx->md && (key == NULL || len < 0))
         return 0;
 
-    if (md != NULL) {
+    if (md != NULL)
         ctx->md = md;
-    } else if (ctx->md) {
+    else if (ctx->md != NULL)
         md = ctx->md;
-    } else {
+    else
         return 0;
-    }
 
     /*
      * The HMAC construction is not allowed to be used with the
@@ -217,34 +217,14 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
 }
 
 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
-                    const unsigned char *d, size_t n, unsigned char *md,
-                    unsigned int *md_len)
+                    const unsigned char *data, size_t data_len,
+                    unsigned char *md, unsigned int *md_len)
 {
-    HMAC_CTX *c = NULL;
-    static unsigned char m[EVP_MAX_MD_SIZE];
-    static const unsigned char dummy_key[1] = {'\0'};
+    static unsigned char static_md[EVP_MAX_MD_SIZE];
 
-    if (md == NULL)
-        md = m;
-    if ((c = HMAC_CTX_new()) == NULL)
-        goto err;
-
-    /* For HMAC_Init_ex, NULL key signals reuse. */
-    if (key == NULL && key_len == 0) {
-        key = dummy_key;
-    }
-
-    if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
-        goto err;
-    if (!HMAC_Update(c, d, n))
-        goto err;
-    if (!HMAC_Final(c, md, md_len))
-        goto err;
-    HMAC_CTX_free(c);
-    return md;
- err:
-    HMAC_CTX_free(c);
-    return NULL;
+    return EVP_Q_mac(NULL, "HMAC", NULL, EVP_MD_name(evp_md), NULL,
+                     key, key_len, data, data_len,
+                     md == NULL ? static_md : md, EVP_MD_size(evp_md), md_len);
 }
 
 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod
index 27930eb89a..f4386f9daf 100644
--- a/doc/man3/EVP_MAC.pod
+++ b/doc/man3/EVP_MAC.pod
@@ -7,8 +7,9 @@ EVP_MAC_number, EVP_MAC_name, EVP_MAC_names_do_all, EVP_MAC_description,
 EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params,
 EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup,
 EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
-EVP_MAC_CTX_get_mac_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final,
-EVP_MAC_finalXOF, EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params,
+EVP_MAC_CTX_get_mac_size, EVP_Q_mac,
+EVP_MAC_init, EVP_MAC_update, EVP_MAC_final, EVP_MAC_finalXOF,
+EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params,
 EVP_MAC_CTX_gettable_params, EVP_MAC_CTX_settable_params,
 EVP_MAC_do_all_provided - EVP MAC routines
 
@@ -41,6 +42,11 @@ EVP_MAC_do_all_provided - EVP MAC routines
  int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
 
  size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx);
+ unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+                          const char *subalg, const OSSL_PARAM *params,
+                          const void *key, size_t keylen,
+                          const unsigned char *data, size_t datalen,
+                          unsigned char *out, size_t outsize, unsigned int *outlen);
  int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
                   const OSSL_PARAM params[]);
  int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
@@ -119,6 +125,19 @@ I<ctx>.
 
 =head2 Computing functions
 
+EVP_Q_mac() computes the message authentication code
+of I<data> with length I<datalen>
+using the MAC algorithm I<name> and the key I<key> with length I<keylen>.
+The MAC algorithm is fetched using any given I<libctx> and property query
+string I<propq>. It takes parameters I<subalg> and further I<params>,
+both of which may be NULL if not needed.
+If I<out> is not NULL, it places the result in the memory pointed at by I<out>,
+but only if I<outsize> is sufficient (otherwise no computation is made).
+If I<out> is NULL, it allocates and uses a buffer of suitable length,
+which will be returned on success and must be freed by the caller.
+In either case, also on error,
+it assigns the number of bytes written to I<*outlen> unless I<outlen> is NULL.
+
 EVP_MAC_init() sets up the underlying context I<ctx> with information given
 via the I<key> and I<params> arguments.  The MAC I<key> has a length of
 I<keylen> and the parameters in I<params> are processed before setting
@@ -162,6 +181,7 @@ EVP_MAC_CTX_set_params() passes chosen parameters to the underlying
 context, given a context I<ctx>.
 The set of parameters given with I<params> determine exactly what
 parameters are passed down.
+If I<params> are NULL, the unterlying context should do nothing and return 1.
 Note that a parameter that is unknown in the underlying context is
 simply ignored.
 Also, what happens when a needed parameter isn't passed down is
@@ -325,7 +345,7 @@ not be considered a breaking change to the API.
 
 =head1 RETURN VALUES
 
-EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or
+EVP_MAC_fetch() returns a pointer to a newly fetched B<EVP_MAC>, or
 NULL if allocation failed.
 
 EVP_MAC_up_ref() returns 1 on success, 0 on error.
@@ -351,7 +371,9 @@ EVP_MAC_CTX_free() returns nothing at all.
 EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on
 success, 0 on error.
 
-EVP_MAC_init(), EVP_MAC_update(), EVP_MAC_final() and  EVP_MAC_finalXOF()
+EVP_Q_mac() returns a pointer to the computed MAC value, or NULL on error.
+
+EVP_MAC_init(), EVP_MAC_update(), EVP_MAC_final(), and EVP_MAC_finalXOF()
 return 1 on success, 0 on error.
 
 EVP_MAC_CTX_get_mac_size() returns the expected output size, or 0 if it isn't set.
diff --git a/doc/man3/HMAC.pod b/doc/man3/HMAC.pod
index 816d6e325d..5057360253 100644
--- a/doc/man3/HMAC.pod
+++ b/doc/man3/HMAC.pod
@@ -20,14 +20,14 @@ HMAC_size
 
  #include <openssl/hmac.h>
 
+ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                     const unsigned char *data, size_t data_len,
+                     unsigned char *md, unsigned int *md_len);
+
 Deprecated since OpenSSL 3.0, can be hidden entirely by defining
 B<OPENSSL_API_COMPAT> with a suitable version value, see
 L<openssl_user_macros(7)>:
 
- unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
-                     int key_len, const unsigned char *d, size_t n,
-                     unsigned char *md, unsigned int *md_len);
-
  HMAC_CTX *HMAC_CTX_new(void);
  int HMAC_CTX_reset(HMAC_CTX *ctx);
 
@@ -53,28 +53,29 @@ L<openssl_user_macros(7)>:
 
 =head1 DESCRIPTION
 
-All of the functions described on this page are deprecated. Applications should
-instead use L<EVP_MAC_CTX_new(3)>, L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>,
-L<EVP_MAC_update(3)> and L<EVP_MAC_final(3)>.
-
 HMAC is a MAC (message authentication code), i.e. a keyed hash
 function used for message authentication, which is based on a hash
 function.
 
-HMAC() computes the message authentication code of the B<n> bytes at
-B<d> using the hash function B<evp_md> and the key B<key> which is
-B<key_len> bytes long.
+HMAC() computes the message authentication code of the I<data_len> bytes at
+I<data> using the hash function I<evp_md> and the key I<key> which is
+I<key_len> bytes long. The I<key> may also be NULL with I<key_len> being 0.
 
-It places the result in B<md> (which must have space for the output of
+It places the result in I<md> (which must have space for the output of
 the hash function, which is no more than B<EVP_MAX_MD_SIZE> bytes).
-If B<md> is NULL, the digest is placed in a static array.  The size of
-the output is placed in B<md_len>, unless it is B<NULL>. Note: passing a NULL
-value for B<md>  to use the static array is not thread safe.
+If I<md> is NULL, the digest is placed in a static array.  The size of
+the output is placed in I<md_len>, unless it is NULL. Note: passing a NULL
+value for I<md> to use the static array is not thread safe.
 
-B<evp_md> is a message digest such as EVP_sha1(), EVP_ripemd160() etc. HMAC does
-not support variable output length digests such as EVP_shake128() and
+I<evp_md> is a message digest such as EVP_sha1(), EVP_ripemd160() etc.
+HMAC does not support variable output length digests such as EVP_shake128() and
 EVP_shake256().
 
+All of the functions described below are deprecated.
+Applications should instead use L<EVP_MAC_CTX_new(3)>, L<EVP_MAC_CTX_free(3)>,
+L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)> and L<EVP_MAC_final(3)>
+or the 'quick' single-shot MAC function L<EVP_Q_mac(3)>.
+
 HMAC_CTX_new() creates a new HMAC_CTX in heap memory.
 
 HMAC_CTX_reset() clears an existing B<HMAC_CTX> and associated
@@ -89,27 +90,27 @@ The following functions may be used if the message is not completely
 stored in memory:
 
 HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use the hash
-function B<evp_md> and key B<key>. If both are NULL, or if B<key> is NULL
-and B<evp_md> is the same as the previous call, then the
+function I<evp_md> and key I<key>. If both are NULL, or if I<key> is NULL
+and I<evp_md> is the same as the previous call, then the
 existing key is
-reused. B<ctx> must have been created with HMAC_CTX_new() before the first use
+reused. I<ctx> must have been created with HMAC_CTX_new() before the first use
 of an B<HMAC_CTX> in this function.
 
-If HMAC_Init_ex() is called with B<key> NULL and B<evp_md> is not the
-same as the previous digest used by B<ctx> then an error is returned
+If HMAC_Init_ex() is called with I<key> NULL and I<evp_md> is not the
+same as the previous digest used by I<ctx> then an error is returned
 because reuse of an existing key with a different digest is not supported.
 
 HMAC_Init() initializes a B<HMAC_CTX> structure to use the hash
-function B<evp_md> and the key B<key> which is B<key_len> bytes
+function I<evp_md> and the key I<key> which is I<key_len> bytes
 long.
 
 HMAC_Update() can be called repeatedly with chunks of the message to
-be authenticated (B<len> bytes at B<data>).
+be authenticated (I<len> bytes at I<data>).
 
-HMAC_Final() places the message authentication code in B<md>, which
+HMAC_Final() places the message authentication code in I<md>, which
 must have space for the hash function output.
 
-HMAC_CTX_copy() copies all of the internal state from B<sctx> into B<dctx>.
+HMAC_CTX_copy() copies all of the internal state from I<sctx> into I<dctx>.
 
 HMAC_CTX_set_flags() applies the specified flags to the internal EVP_MD_CTXs.
 These flags have the same meaning as for L<EVP_MD_CTX_set_flags(3)>.
@@ -125,7 +126,7 @@ HMAC() returns a pointer to the message authentication code or NULL if
 an error occurred.
 
 HMAC_CTX_new() returns a pointer to a new B<HMAC_CTX> on success or
-B<NULL> if an error occurred.
+NULL if an error occurred.
 
 HMAC_CTX_reset(), HMAC_Init_ex(), HMAC_Update(), HMAC_Final() and
 HMAC_CTX_copy() return 1 for success or 0 if an error occurred.
@@ -142,11 +143,11 @@ RFC 2104
 
 =head1 SEE ALSO
 
-L<SHA1(3)>, L<evp(7)>
+L<SHA1(3)>, EVP_Q_mac(3), L<evp(7)>
 
 =head1 HISTORY
 
-All of these functions were deprecated in OpenSSL 3.0.
+All functions except for HMAC() were deprecated in OpenSSL 3.0.
 
 HMAC_CTX_init() was replaced with HMAC_CTX_reset() in OpenSSL 1.1.0.
 
diff --git a/doc/man3/PEM_X509_INFO_read_bio_ex.pod b/doc/man3/PEM_X509_INFO_read_bio_ex.pod
index bd79829d2b..0c9b0ab6df 100644
--- a/doc/man3/PEM_X509_INFO_read_bio_ex.pod
+++ b/doc/man3/PEM_X509_INFO_read_bio_ex.pod
@@ -24,11 +24,10 @@ PEM_X509_INFO_read_bio_ex, PEM_X509_INFO_read_ex
 
 PEM_X509_INFO_read_ex() loads the B<X509_INFO> objects from a file I<fp>.
 
-PEM_X509_INFO_read_bio_ex loads the B<X509_INFO> objects using a bio I<bp>.
+PEM_X509_INFO_read_bio_ex() loads the B<X509_INFO> objects using a bio I<bp>.
 
 Each of the loaded B<X509_INFO> objects can contain a CRL, a certificate,
 and/or a private key.
-
 The elements are read sequentially, and as far as they are of different type than
 the elements read before, they are combined into the same B<X509_INFO> object.
 The idea behind this is that if, for instance, a certificate is followed by
diff --git a/doc/man3/SSL_load_client_CA_file.pod b/doc/man3/SSL_load_client_CA_file.pod
index 9fc385a18a..a02cc016ad 100644
--- a/doc/man3/SSL_load_client_CA_file.pod
+++ b/doc/man3/SSL_load_client_CA_file.pod
@@ -28,10 +28,10 @@ SSL_add_store_cert_subjects_to_stack
 
 SSL_load_client_CA_file_ex() reads certificates from I<file> and returns
 a STACK_OF(X509_NAME) with the subject names found. The library context I<libctx>
-and property query <propq> are used when fetching algorithms from providers.
+and property query I<propq> are used when fetching algorithms from providers.
 
 SSL_load_client_CA_file() is similar to SSL_load_client_CA_file_ex()
-but uses NULL for the library context I<libctx> and property query <propq>.
+but uses NULL for the library context I<libctx> and property query I<propq>.
 
 SSL_add_file_cert_subjects_to_stack() reads certificates from I<file>,
 and adds their subject name to the already existing I<stack>.
diff --git a/doc/man3/X509_LOOKUP.pod b/doc/man3/X509_LOOKUP.pod
index 89dbb6a201..615c2070b9 100644
--- a/doc/man3/X509_LOOKUP.pod
+++ b/doc/man3/X509_LOOKUP.pod
@@ -94,7 +94,7 @@ X509_LOOKUP_ctrl_ex() is used to set or get additional data to or from
 a B<X509_LOOKUP> structure or its associated L<X509_LOOKUP_METHOD(3)>.
 The arguments of the control command are passed via I<argc> and I<argl>,
 its return value via I<*ret>. The library context I<libctx> and property
-query <propq> are used when fetching algorithms from providers.
+query I<propq> are used when fetching algorithms from providers.
 The meaning of the arguments depends on the I<cmd> number of the
 control command. In general, this function is not called directly, but
 wrapped by a macro call, see below.
@@ -102,17 +102,17 @@ The control I<cmd>s known to OpenSSL are discussed in more depth
 in L</Control Commands>.
 
 X509_LOOKUP_ctrl() is similar to X509_LOOKUP_ctrl_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_LOOKUP_load_file_ex() passes a filename to be loaded immediately
 into the associated B<X509_STORE>. The library context I<libctx> and property
-query <propq> are used when fetching algorithms from providers.
+query I<propq> are used when fetching algorithms from providers.
 I<type> indicates what type of object is expected.
 This can only be used with a lookup using the implementation
 L<X509_LOOKUP_file(3)>.
 
 X509_LOOKUP_load_file() is similar to X509_LOOKUP_load_file_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_LOOKUP_add_dir() passes a directory specification from which
 certificates and CRLs are loaded on demand into the associated
@@ -124,20 +124,20 @@ L<X509_LOOKUP_hash_dir(3)>.
 X509_LOOKUP_add_store_ex() passes a URI for a directory-like structure
 from which containers with certificates and CRLs are loaded on demand
 into the associated B<X509_STORE>. The library context I<libctx> and property
-query <propq> are used when fetching algorithms from providers.
+query I<propq> are used when fetching algorithms from providers.
 
 X509_LOOKUP_add_store() is similar to X509_LOOKUP_add_store_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_LOOKUP_load_store_ex() passes a URI for a single container from
 which certificates and CRLs are immediately loaded into the associated
-B<X509_STORE>. The library context I<libctx> and property query <propq> are used
+B<X509_STORE>. The library context I<libctx> and property query I<propq> are used
 when fetching algorithms from providers.
 These functions can only be used with a lookup using the
 implementation L<X509_LOOKUP_store(3)>.
 
 X509_LOOKUP_load_store() is similar to X509_LOOKUP_load_store_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_LOOKUP_load_file_ex(), X509_LOOKUP_load_file(),
 X509_LOOKUP_add_dir(),
diff --git a/doc/man3/X509_STORE_add_cert.pod b/doc/man3/X509_STORE_add_cert.pod
index db7f0cfd8c..07e8654acb 100644
--- a/doc/man3/X509_STORE_add_cert.pod
+++ b/doc/man3/X509_STORE_add_cert.pod
@@ -93,10 +93,10 @@ B<X509_LOOKUP> functions can look up objects in that store.
 
 X509_STORE_load_file_ex() loads trusted certificate(s) into an
 B<X509_STORE> from a given file. The library context I<libctx> and property
-query <propq> are used when fetching algorithms from providers.
+query I<propq> are used when fetching algorithms from providers.
 
 X509_STORE_load_file() is similar to X509_STORE_load_file_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_STORE_load_path() loads trusted certificate(s) into an
 B<X509_STORE> from a given directory path.
@@ -105,10 +105,10 @@ documented in L<X509_LOOKUP_hash_dir(3)>.
 
 X509_STORE_load_store_ex() loads trusted certificate(s) into an
 B<X509_STORE> from a store at a given URI. The library context I<libctx> and
-property query <propq> are used when fetching algorithms from providers.
+property query I<propq> are used when fetching algorithms from providers.
 
 X509_STORE_load_store() is similar to X509_STORE_load_store_ex() but
-uses NULL for the library context I<libctx> and property query <propq>.
+uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_STORE_load_locations_ex() combines
 X509_STORE_load_file_ex() and X509_STORE_load_dir() for a given file
@@ -117,17 +117,17 @@ It is permitted to specify just a file, just a directory, or both
 paths.
 
 X509_STORE_load_locations() is similar to X509_STORE_load_locations_ex()
-but uses NULL for the library context I<libctx> and property query <propq>.
+but uses NULL for the library context I<libctx> and property query I<propq>.
 
 X509_STORE_set_default_paths_ex() is somewhat misnamed, in that it does
 not set what default paths should be used for loading certificates.  Instead,
 it loads certificates into the B<X509_STORE> from the hardcoded default
-paths. The library context I<libctx> and property query <propq> are used when
+paths. The library context I<libctx> and property query I<propq> are used when
 fetching algorithms from providers.
 
 X509_STORE_set_default_paths() is similar to
 X509_STORE_set_default_paths_ex() but uses NULL for the library
-context I<libctx> and property query <propq>.
+context I<libctx> and property query I<propq>.
 
 =head1 RETURN VALUES
 
diff --git a/doc/man3/X509_new.pod b/doc/man3/X509_new.pod
index 2514ae34ce..ea2b3a2cc9 100644
--- a/doc/man3/X509_new.pod
+++ b/doc/man3/X509_new.pod
@@ -22,7 +22,7 @@ The X509 ASN1 allocation routines, allocate and free an
 X509 structure, which represents an X509 certificate.
 
 X509_new_ex() allocates and initializes a X509 structure with a
-library context of I<libctx>, property query of <propq> and a reference
+library context of I<libctx>, property query of I<propq> and a reference
 count of B<1>. Many X509 functions such as X509_check_purpose(), and
 X509_verify() use this library context to select which providers supply the
 fetched algorithms (SHA1 is used internally). This created X509 object can then
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 91b84ebf6f..9374e86e66 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1176,6 +1176,11 @@ int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]);
 int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
 
 size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx);
+unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
+                         const char *subalg, const OSSL_PARAM *params,
+                         const void *key, size_t keylen,
+                         const unsigned char *data, size_t datalen,
+                         unsigned char *out, size_t outsize, unsigned int *outlen);
 int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
                  const OSSL_PARAM params[]);
 int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h
index f2f502ea5c..f9e1bff3f7 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/hmac.h
@@ -27,6 +27,7 @@
 # ifdef  __cplusplus
 extern "C" {
 # endif
+
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
 OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
@@ -45,15 +46,15 @@ OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
                                       size_t len);
 OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
                                      unsigned int *len);
-OSSL_DEPRECATEDIN_3_0 unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
-                                          int key_len, const unsigned char *d,
-                                          size_t n, unsigned char *md,
-                                          unsigned int *md_len);
 OSSL_DEPRECATEDIN_3_0 __owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
 OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
 OSSL_DEPRECATEDIN_3_0 const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx);
 # endif
 
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                    const unsigned char *data, size_t data_len,
+                    unsigned char *md, unsigned int *md_len);
+
 # ifdef  __cplusplus
 }
 # endif
diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums
index e6d798648a..6175384c2d 100644
--- a/providers/fips-sources.checksums
+++ b/providers/fips-sources.checksums
@@ -180,7 +180,7 @@ c0f87865be8dab6ea909fd976e5a46e4e8343b18403090c4a59b2af90f9a1329  crypto/evp/evp
 2d657d8de8c2441693d54ef3730d83ca4b5d76c3b3405ece89bff9e46149d670  crypto/evp/keymgmt_lib.c
 56d3ed4313cb811a3c2d062ff8b2a0fd67c4b0d28fe0562a57555b3a95907535  crypto/evp/keymgmt_meth.c
 9fd78bfd59378fc4a9f56ce474310d8d2851aa42862c694ee0e47b175e836c51  crypto/evp/m_sigver.c
-0f5e0cd5c66712803a19774610f6bdfe572f5dda08c58cdf1b19d38a0693911c  crypto/evp/mac_lib.c
+ec959b00487bfc51f4cf33c21a60fd8a73087a622504f459ba4cfe48bb0a738c  crypto/evp/mac_lib.c
 5f4b933a479d7cd589c47388aebfd8d6ffa3943ec2883049fc929e6ca37e26b5  crypto/evp/mac_meth.c
 f5a18107256e00e2eed6a9b54eaf44ef1b99c0f29134e9f363a09daa2d35f1b5  crypto/evp/p_lib.c
 b7e9ce6e8a35e0fc5b4eb4c047cda1e811b757669dbfafa71e743d85e07817a4  crypto/evp/pmeth_check.c
@@ -195,7 +195,7 @@ ead786b4f5689ab69d6cca5d49e513e0f90cb558b67e6c5898255f2671f1393d  crypto/ffc/ffc
 a87945698684673832fbedb4d01e2f11df58f43f79605a9e6d7136bb15b02e52  crypto/ffc/ffc_params.c
 887357f0422954f2ecb855d468ad2456a76372dc401301ba284c0fd8c6b5092e  crypto/ffc/ffc_params_generate.c
 73dac805abab36cd9df53a421221c71d06a366a4ce479fa788be777f11b47159  crypto/ffc/ffc_params_validate.c
-84d8ae0141a79548ad65b31fe4673e8603930f942f21f3a7623e23f539799764  crypto/hmac/hmac.c
+c193773792bec29c791e84d150ffe5ef25f53cb02e23f0e12e9000234b4322e5  crypto/hmac/hmac.c
 7000ba81f54c1d516a536bc6e96ad3729e3b5b15740006c2e22f0b76606042d6  crypto/initthread.c
 c6c83f826eb6465f2a1b186ea692ff6fe32dbfb821d18d254625b69083d68fb0  crypto/lhash/lhash.c
 f866aafae928db1b439ac950dc90744a2397dfe222672fe68b3798396190c8b0  crypto/mem_clr.c
@@ -362,7 +362,7 @@ de342d04be6af69037922d5c97bdc40c0c27f6740636e72786a765d0d8ad9173  providers/impl
 427b9abee979f94371aa4aa99b48f08f1772965c93f9bce6f4531cc4cec136b6  providers/implementations/exchange/ecdh_exch.c
 9bf87b8429398a6465c7e9f749a33b84974303a458736b56f3359b30726d3969  providers/implementations/exchange/ecx_exch.c
 06ba83a8a8235bcdbda56f82b017cb19361469fe47c23cc6218a7e9b88ae6513  providers/implementations/exchange/kdf_exch.c
-4f8049771ff0cb57944e1ffc9599a96023e36b424138e51b1466f9a133f03943  providers/implementations/kdfs/hkdf.c
+9b9e7937be361de8e3c3fa9a2ef17edde8a0a4391bf55c72ff9785c1e4ee7dfc  providers/implementations/kdfs/hkdf.c
 115e13e152cfb7d729659cb26056414f719c5e7cb2a9b3df8b6ad0f232ce109a  providers/implementations/kdfs/kbkdf.c
 f93d3b32e7e3bc6bd4100559b15d392613797e1048010fdc70058ae9297a1125  providers/implementations/kdfs/pbkdf2.c
 abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc  providers/implementations/kdfs/pbkdf2_fips.c
diff --git a/providers/fips.checksum b/providers/fips.checksum
index 4ee2135be1..50a9c51b5c 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-a1ce185646a78b5eb88229b77aec1455e6e361f7428bb884aebe45cb8fdc3703  providers/fips-sources.checksums
+4d501c5fb8a5646c618eb02511a7a1ffab71823f6adee558ee30df8bb4bd6f40  providers/fips-sources.checksums
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index 2d3c72f501..ce0c81c1d2 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -41,12 +41,12 @@ static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
 static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
 static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
 
-static int HKDF(const EVP_MD *evp_md,
+static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
                 const unsigned char *salt, size_t salt_len,
                 const unsigned char *key, size_t key_len,
                 const unsigned char *info, size_t info_len,
                 unsigned char *okm, size_t okm_len);
-static int HKDF_Extract(const EVP_MD *evp_md,
+static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
                         const unsigned char *salt, size_t salt_len,
                         const unsigned char *ikm, size_t ikm_len,
                         unsigned char *prk, size_t prk_len);
@@ -127,6 +127,7 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
                            const OSSL_PARAM params[])
 {
     KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
     const EVP_MD *md;
 
     if (!ossl_prov_is_running() || !kdf_hkdf_set_ctx_params(ctx, params))
@@ -148,13 +149,12 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
 
     switch (ctx->mode) {
     case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
-        return HKDF(md, ctx->salt, ctx->salt_len, ctx->key,
-                    ctx->key_len, ctx->info, ctx->info_len, key,
-                    keylen);
+        return HKDF(libctx, md, ctx->salt, ctx->salt_len,
+                    ctx->key, ctx->key_len, ctx->info, ctx->info_len, key, keylen);
 
     case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
-        return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key,
-                            ctx->key_len, key, keylen);
+        return HKDF_Extract(libctx, md, ctx->salt, ctx->salt_len,
+                            ctx->key, ctx->key_len, key, keylen);
 
     case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
         return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info,
@@ -169,13 +169,13 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     const OSSL_PARAM *p;
     KDF_HKDF *ctx = vctx;
-    OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx);
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
     int n;
 
     if (params == NULL)
         return 1;
 
-    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_MODE)) != NULL) {
@@ -316,7 +316,7 @@ const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {
  *   2.3.  Step 2: Expand
  *     HKDF-Expand(PRK, info, L) -> OKM
  */
-static int HKDF(const EVP_MD *evp_md,
+static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
                 const unsigned char *salt, size_t salt_len,
                 const unsigned char *ikm, size_t ikm_len,
                 const unsigned char *info, size_t info_len,
@@ -332,7 +332,8 @@ static int HKDF(const EVP_MD *evp_md,
     prk_len = (size_t)sz;
 
     /* Step 1: HKDF-Extract(salt, IKM) -> PRK */
-    if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len))
+    if (!HKDF_Extract(libctx, evp_md,
+                      salt, salt_len, ikm, ikm_len, prk, prk_len))
         return 0;
 
     /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */
@@ -366,7 +367,7 @@ static int HKDF(const EVP_MD *evp_md,
  *
  *   PRK = HMAC-Hash(salt, IKM)
  */
-static int HKDF_Extract(const EVP_MD *evp_md,
+static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
                         const unsigned char *salt, size_t salt_len,
                         const unsigned char *ikm, size_t ikm_len,
                         unsigned char *prk, size_t prk_len)
@@ -380,7 +381,10 @@ static int HKDF_Extract(const EVP_MD *evp_md,
         return 0;
     }
     /* calc: PRK = HMAC-Hash(salt, IKM) */
-    return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL;
+    return
+        EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_name(evp_md), NULL, salt,
+                  salt_len, ikm, ikm_len, prk, EVP_MD_size(evp_md), NULL)
+        != NULL;
 }
 
 /*
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index f88d59948d..dba1e5fb8c 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -306,22 +306,14 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
                              unsigned char *out)
 {
     const char *mdname = EVP_MD_name(ssl_handshake_md(s));
-    EVP_MAC *hmac = EVP_MAC_fetch(s->ctx->libctx, "HMAC", s->ctx->propq);
     unsigned char hash[EVP_MAX_MD_SIZE];
     unsigned char finsecret[EVP_MAX_MD_SIZE];
     unsigned char *key = NULL;
+    unsigned int len = 0;
     size_t hashlen, ret = 0;
-    EVP_MAC_CTX *ctx = NULL;
-    OSSL_PARAM params[3], *p = params;
-
-    if (hmac == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
+    OSSL_PARAM params[2], *p = params;
 
     /* Safe to cast away const here since we're not "getting" any data */
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
-                                            (char *)mdname, 0);
     if (s->ctx->propq != NULL)
         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
                                                 (char *)s->ctx->propq,
@@ -345,21 +337,17 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
         key = finsecret;
     }
 
-    ctx = EVP_MAC_CTX_new(hmac);
-    if (ctx == NULL
-            || !EVP_MAC_init(ctx, key, hashlen, params)
-            || !EVP_MAC_update(ctx, hash, hashlen)
-               /* outsize as per sizeof(peer_finish_md) */
-            || !EVP_MAC_final(ctx, out, &hashlen, EVP_MAX_MD_SIZE * 2)) {
+    if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname,
+                   params, key, hashlen, hash, hashlen,
+                   /* outsize as per sizeof(peer_finish_md) */
+                   out, EVP_MAX_MD_SIZE * 2, &len)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         goto err;
     }
 
-    ret = hashlen;
+    ret = len;
  err:
     OPENSSL_cleanse(finsecret, sizeof(finsecret));
-    EVP_MAC_CTX_free(ctx);
-    EVP_MAC_free(hmac);
     return ret;
 }
 
diff --git a/test/hmactest.c b/test/hmactest.c
index babfb0e1a7..918ae0b005 100644
--- a/test/hmactest.c
+++ b/test/hmactest.c
@@ -100,10 +100,7 @@ static int test_hmac_md5(int idx)
                 test[idx].data, test[idx].data_len, NULL, NULL),
                 MD5_DIGEST_LENGTH);
 
-    if (!TEST_str_eq(p, test[idx].digest))
-      return 0;
-
-    return 1;
+    return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest);
 }
 # endif
 
@@ -151,7 +148,7 @@ static int test_hmac_run(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[4].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
         goto err;
 
     if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)))
@@ -164,7 +161,7 @@ static int test_hmac_run(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[5].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest))
         goto err;
 
     if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL))
@@ -172,7 +169,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     /* Test reusing a key */
@@ -181,7 +178,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     /*
@@ -193,7 +190,7 @@ static int test_hmac_run(void)
         || !TEST_true(HMAC_Final(ctx, buf, &len)))
         goto err;
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[6].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest))
         goto err;
 
     ret = 1;
@@ -207,10 +204,10 @@ static int test_hmac_single_shot(void)
 {
     char *p;
 
-    /* Test single-shot with an empty key. */
+    /* Test single-shot with NULL key. */
     p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len,
                 NULL, NULL), SHA_DIGEST_LENGTH);
-    if (!TEST_str_eq(p, test[4].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest))
         return 0;
 
     return 1;
@@ -237,7 +234,7 @@ static int test_hmac_copy(void)
         goto err;
 
     p = pt(buf, len);
-    if (!TEST_str_eq(p, test[7].digest))
+    if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest))
         goto err;
 
     ret = 1;
@@ -253,6 +250,8 @@ static char *pt(unsigned char *md, unsigned int len)
     unsigned int i;
     static char buf[80];
 
+    if (md == NULL)
+        return NULL;
     for (i = 0; i < len; i++)
         sprintf(&(buf[i * 2]), "%02x", md[i]);
     return buf;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 13ec6e26f7..2e89c5dd26 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -2028,7 +2028,7 @@ MDC2_Init                               2075	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_
 i2o_SCT                                 2076	3_0_0	EXIST::FUNCTION:CT
 d2i_TS_STATUS_INFO                      2077	3_0_0	EXIST::FUNCTION:TS
 ERR_error_string_n                      2078	3_0_0	EXIST::FUNCTION:
-HMAC                                    2079	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0
+HMAC                                    2079	3_0_0	EXIST::FUNCTION:
 BN_mul                                  2080	3_0_0	EXIST::FUNCTION:
 BN_get0_nist_prime_384                  2081	3_0_0	EXIST::FUNCTION:
 X509_VERIFY_PARAM_set1_ip_asc           2082	3_0_0	EXIST::FUNCTION:
@@ -4408,6 +4408,7 @@ EVP_MAC_CTX_free                        ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_dup                         ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_mac                         ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_get_mac_size                ?	3_0_0	EXIST::FUNCTION:
+EVP_Q_mac                               ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_init                            ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_update                          ?	3_0_0	EXIST::FUNCTION:
 EVP_MAC_final                           ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list