[openssl] master update

Dr. Paul Dale pauli at openssl.org
Sat Aug 29 07:44:03 UTC 2020


The branch master has been updated
       via  e3bf65da88f714f8721c2985f235b12a7f90d9f8 (commit)
       via  52ae0f8fc23570b6b7cc98d1cb0d6f6dd53ea98a (commit)
       via  2ef9a7ac5eb93c3f5460695c526968faf025b730 (commit)
       via  2106b0471997b6c96fd702ceb0f9a2c8af298a0a (commit)
       via  e5bc0ce2aed293f6356d1702a766f418526890e5 (commit)
       via  2cf765e5a20762df1442c80cd2afc99e8bb1b823 (commit)
       via  a540ef90f55c1e10feb709d09332dfa352d9f33e (commit)
       via  4db71d0175ed42586bcd4e6527caacbd18602adf (commit)
       via  8014b2a966e0a971797d5160c082108b5618d6b3 (commit)
       via  b27b31b62846d21a915acfd45c92ba82d3cd5666 (commit)
       via  6f0bd6ca1c675503962e4580e54ceecd078a8331 (commit)
       via  ada0670bf6c2f67016a55750b1f6b08c54f4242c (commit)
       via  5d51925a90734226f804a7b928326f8ba4bd0434 (commit)
       via  1bf625040c9a1f02782c9b4f993e1a58e6e70448 (commit)
       via  b571e662cdc06febabeac3a117726deaf812afd7 (commit)
       via  409910be16240d1693dbff5065b852998e80cd40 (commit)
       via  e538294f8f9b522279e523ebf6804ed4cb721b80 (commit)
      from  bddfea0271d0596961a43283b36ff49923329a92 (commit)


- Log -----------------------------------------------------------------
commit e3bf65da88f714f8721c2985f235b12a7f90d9f8
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Aug 19 17:33:38 2020 +0100

    Include "legacy" in the name of the various MAC bridge functions
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 52ae0f8fc23570b6b7cc98d1cb0d6f6dd53ea98a
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Aug 17 17:25:37 2020 +0100

    Add some documentation about the EVP_PKEY MAC interface
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 2ef9a7ac5eb93c3f5460695c526968faf025b730
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Aug 17 15:14:14 2020 +0100

    Improve code reuse in the provider MAC bridge
    
    We reuse concepts such as PROV_CIPHER, and make use of some common code
    in provider_util.c
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 2106b0471997b6c96fd702ceb0f9a2c8af298a0a
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Aug 14 17:01:00 2020 +0100

    Document the EVP_PKEY_new_CMAC_key_with_libctx() function
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit e5bc0ce2aed293f6356d1702a766f418526890e5
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Aug 12 14:41:12 2020 +0100

    Extend test_CMAC_keygen in evp_extra_test
    
    The test only setup the generation of a key. It did not complete that
    generation. We extend the test to complete the generation and to use the
    generated key. We also compare the result with a key generated in a
    different way.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 2cf765e5a20762df1442c80cd2afc99e8bb1b823
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Aug 12 13:41:59 2020 +0100

    Delete unused PKEY MAC files
    
    Now that the all the legacy PKEY MAC bridge code has been moved to the
    providers we no longer need the old bridge and it can be removed.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit a540ef90f55c1e10feb709d09332dfa352d9f33e
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Aug 11 16:17:00 2020 +0100

    Extend the provider MAC bridge for CMAC
    
    The previous commits added support for HMAC, SIPHASH and Poly1305 into
    the provider MAC bridge. We now extend that for CMAC too.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 4db71d0175ed42586bcd4e6527caacbd18602adf
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Aug 11 15:28:07 2020 +0100

    Extend the provider MAC bridge for Poly1305
    
    The previous commits added support for HMAC and SIPHASH into the provider
    MAC bridge. We now extend that for Poly1305 too.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 8014b2a966e0a971797d5160c082108b5618d6b3
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Aug 11 14:55:04 2020 +0100

    Don't require a default digest from signature algorithms
    
    Some signature algorithms don't need a default digest, so don't fail if
    we don't have one.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit b27b31b62846d21a915acfd45c92ba82d3cd5666
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Aug 11 14:54:18 2020 +0100

    Extend the provider MAC bridge for SIPHASH
    
    The previous commits added support for HMAC into the provider MAC bridge.
    We now extend that for SIPHASH too.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 6f0bd6ca1c675503962e4580e54ceecd078a8331
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Aug 11 11:50:04 2020 +0100

    Ensure libssl creates libctx aware MAC keys
    
    Convert various mac key creation function calls to use the _with_libctx
    variants.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit ada0670bf6c2f67016a55750b1f6b08c54f4242c
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Aug 10 17:11:39 2020 +0100

    Fix some EVP_MD_CTX_* functions
    
    Fixes some issues with EVP_MD_CTX_* functions when doing EVP_DigestSign*
    and EVP_DigestVerify* functions.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 5d51925a90734226f804a7b928326f8ba4bd0434
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Aug 10 09:16:01 2020 +0100

    Convert EVP_PKEY_CTX_set_mac_key() into a function
    
    Previously it was a macro. We now make it into a function that is params
    aware.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 1bf625040c9a1f02782c9b4f993e1a58e6e70448
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Aug 7 17:20:18 2020 +0100

    Fix evp_extra_test to not assume that HMAC is legacy
    
    evp_extra_test had a test that checks whether an EVP_PKEY_CTX can still
    be created for HMAC even though there are no providers loaded because it
    is a legacy algorithm. However after the earlier commits this is no longer
    the case. We swap the check to a different legacy algorithm (SM2).
    Hopefully before too long there will be no legacy algorithms left and the
    test can be deleted.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit b571e662cdc06febabeac3a117726deaf812afd7
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Aug 7 16:55:42 2020 +0100

    Make the provider side EVP PKEY MAC bridge available in default and fips
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit 409910be16240d1693dbff5065b852998e80cd40
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Aug 7 16:42:02 2020 +0100

    Implement signature functions for EVP_PKEY MAC to EVP_MAC provider bridge
    
    Some MAC implementations were available before the current EVP_MAC API. They
    were used via EVP_DigestSign*. There exists a bridge between the oldAPI and
    the EVP_MAC API however this bridge itself uses a legacy EVP_PKEY_METHOD.
    This commit implements the signature functions for the provider side bridge
    without having to use any legacy code.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

commit e538294f8f9b522279e523ebf6804ed4cb721b80
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Aug 7 16:40:25 2020 +0100

    Implement key management for the EVP_PKEY MAC to EVP_MAC provider bridge
    
    Some MAC implementations were available before the current EVP_MAC API. They
    were used via EVP_DigestSign*. There exists a bridge between the old API and
    the EVP_MAC API however this bridge itself uses a legacy EVP_PKEY_METHOD.
    This commit implements the key management for provider side bridge without
    having to useany legacy code.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12637)

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

Summary of changes:
 crypto/asn1/standard_methods.h                     |  10 -
 crypto/cmac/build.info                             |   2 +-
 crypto/cmac/cm_ameth.c                             |  59 --
 crypto/evp/build.info                              |   1 -
 crypto/evp/digest.c                                |  45 +-
 crypto/evp/m_sigver.c                              |   5 +-
 crypto/evp/p_lib.c                                 |  92 +--
 crypto/evp/pkey_mac.c                              | 696 ---------------------
 crypto/evp/pmeth_lib.c                             |  66 +-
 crypto/hmac/build.info                             |   2 +-
 crypto/hmac/hm_ameth.c                             | 133 ----
 crypto/poly1305/build.info                         |   2 +-
 crypto/poly1305/poly1305_ameth.c                   | 121 ----
 crypto/siphash/build.info                          |   3 +-
 crypto/siphash/siphash_ameth.c                     | 123 ----
 doc/man3/EVP_PKEY_new.pod                          |  57 +-
 doc/man7/EVP_PKEY-HMAC.pod                         |  95 +++
 doc/man7/EVP_SIGNATURE-HMAC.pod                    |  41 ++
 include/crypto/asn1.h                              |   4 -
 include/crypto/evp.h                               |   4 -
 include/openssl/core_names.h                       |   5 +-
 include/openssl/evp.h                              |  10 +-
 providers/common/include/prov/provider_util.h      |  15 +
 providers/common/provider_util.c                   | 109 ++--
 providers/defltprov.c                              |  16 +
 providers/fips/fipsprov.c                          |   8 +
 .../implementations/include/prov/implementations.h |   7 +-
 .../include/prov/{kdfexchange.h => macsignature.h} |  18 +-
 providers/implementations/keymgmt/build.info       |   3 +
 .../implementations/keymgmt/mac_legacy_kmgmt.c     | 513 +++++++++++++++
 providers/implementations/signature/build.info     |   3 +
 providers/implementations/signature/mac_legacy.c   | 191 ++++++
 ssl/statem/extensions.c                            |   6 +-
 ssl/statem/extensions_srvr.c                       |  18 +-
 ssl/t1_enc.c                                       |  18 +-
 test/evp_extra_test.c                              |  61 +-
 test/evp_test.c                                    |   6 +-
 util/libcrypto.num                                 |   2 +
 38 files changed, 1236 insertions(+), 1334 deletions(-)
 delete mode 100644 crypto/cmac/cm_ameth.c
 delete mode 100644 crypto/evp/pkey_mac.c
 delete mode 100644 crypto/hmac/hm_ameth.c
 delete mode 100644 crypto/poly1305/poly1305_ameth.c
 delete mode 100644 crypto/siphash/siphash_ameth.c
 create mode 100644 doc/man7/EVP_PKEY-HMAC.pod
 create mode 100644 doc/man7/EVP_SIGNATURE-HMAC.pod
 copy providers/implementations/include/prov/{kdfexchange.h => macsignature.h} (60%)
 create mode 100644 providers/implementations/keymgmt/mac_legacy_kmgmt.c
 create mode 100644 providers/implementations/signature/mac_legacy.c

diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h
index d461461031..fdf1d23558 100644
--- a/crypto/asn1/standard_methods.h
+++ b/crypto/asn1/standard_methods.h
@@ -29,10 +29,6 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
 #endif
 #ifndef OPENSSL_NO_EC
     &eckey_asn1_meth,
-#endif
-    &hmac_asn1_meth,
-#ifndef OPENSSL_NO_CMAC
-    &cmac_asn1_meth,
 #endif
 #ifndef OPENSSL_NO_RSA
     &rsa_pss_asn1_meth,
@@ -44,12 +40,6 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
     &ecx25519_asn1_meth,
     &ecx448_asn1_meth,
 #endif
-#ifndef OPENSSL_NO_POLY1305
-    &poly1305_asn1_meth,
-#endif
-#ifndef OPENSSL_NO_SIPHASH
-    &siphash_asn1_meth,
-#endif
 #ifndef OPENSSL_NO_EC
     &ed25519_asn1_meth,
     &ed448_asn1_meth,
diff --git a/crypto/cmac/build.info b/crypto/cmac/build.info
index a2f6f218c2..0c0e50941f 100644
--- a/crypto/cmac/build.info
+++ b/crypto/cmac/build.info
@@ -2,5 +2,5 @@ LIBS=../../libcrypto
 
 $COMMON=cmac.c
 
-SOURCE[../../libcrypto]=$COMMON cm_ameth.c
+SOURCE[../../libcrypto]=$COMMON
 SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c
deleted file mode 100644
index aa06cdc98a..0000000000
--- a/crypto/cmac/cm_ameth.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * CMAC low level APIs are deprecated for public use, but still ok for internal
- * use.
- */
-#include "internal/deprecated.h"
-
-#include <stdio.h>
-#include "internal/cryptlib.h"
-#include <openssl/evp.h>
-#include "crypto/asn1.h"
-
-/*
- * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output
- * length and to free up a CMAC key.
- */
-
-static int cmac_size(const EVP_PKEY *pkey)
-{
-    return EVP_MAX_BLOCK_LENGTH;
-}
-
-static void cmac_key_free(EVP_PKEY *pkey)
-{
-    EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
-    EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx);
-
-    EVP_MAC_CTX_free(cmctx);
-    EVP_MAC_free(mac);
-}
-
-const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
-    EVP_PKEY_CMAC,
-    EVP_PKEY_CMAC,
-    0,
-
-    "CMAC",
-    "OpenSSL CMAC method",
-
-    0, 0, 0, 0,
-
-    0, 0, 0,
-
-    cmac_size,
-    0, 0,
-    0, 0, 0, 0, 0, 0, 0,
-
-    cmac_key_free,
-    0,
-    0, 0
-};
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index 81c660051b..4f155f1393 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -16,7 +16,6 @@ SOURCE[../../libcrypto]=$COMMON\
         pmeth_fn.c\
         e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
         e_chacha20_poly1305.c \
-        pkey_mac.c \
         legacy_sha.c
 
 IF[{- !$disabled{'deprecated-3.0'} -}]
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index c9b4e3fd6e..19fddb74ab 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -489,10 +489,12 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
     if (in->fetched_digest != NULL)
         EVP_MD_up_ref(in->fetched_digest);
 
-    out->provctx = in->digest->dupctx(in->provctx);
-    if (out->provctx == NULL) {
-        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
-        return 0;
+    if (in->provctx != NULL) {
+        out->provctx = in->digest->dupctx(in->provctx);
+        if (out->provctx == NULL) {
+            EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
+            return 0;
+        }
     }
 
     /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
@@ -608,9 +610,7 @@ int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
 {
     EVP_PKEY_CTX *pctx = ctx->pctx;
 
-    if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL)
-        return ctx->digest->set_ctx_params(ctx->provctx, params);
-
+    /* If we have a pctx then we should try that first */
     if (pctx != NULL
             && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                 || pctx->operation == EVP_PKEY_OP_SIGNCTX)
@@ -618,6 +618,10 @@ int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
             && pctx->op.sig.signature->set_ctx_md_params != NULL)
         return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.sigprovctx,
                                                          params);
+
+    if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL)
+        return ctx->digest->set_ctx_params(ctx->provctx, params);
+
     return 0;
 }
 
@@ -635,10 +639,7 @@ const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx)
     if (ctx == NULL)
         return NULL;
 
-    if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL)
-        return ctx->digest->settable_ctx_params(
-                  ossl_provider_ctx(EVP_MD_provider(ctx->digest)));
-
+    /* If we have a pctx then we should try that first */
     pctx = ctx->pctx;
     if (pctx != NULL
             && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
@@ -648,6 +649,10 @@ const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx)
         return pctx->op.sig.signature->settable_ctx_md_params(
                    pctx->op.sig.sigprovctx);
 
+    if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL)
+        return ctx->digest->settable_ctx_params(
+                  ossl_provider_ctx(EVP_MD_provider(ctx->digest)));
+
     return NULL;
 }
 
@@ -655,9 +660,7 @@ int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
 {
     EVP_PKEY_CTX *pctx = ctx->pctx;
 
-    if (ctx->digest != NULL && ctx->digest->get_params != NULL)
-        return ctx->digest->get_ctx_params(ctx->provctx, params);
-
+    /* If we have a pctx then we should try that first */
     if (pctx != NULL
             && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
                 || pctx->operation == EVP_PKEY_OP_SIGNCTX)
@@ -666,6 +669,9 @@ int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
         return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.sigprovctx,
                                                          params);
 
+    if (ctx->digest != NULL && ctx->digest->get_params != NULL)
+        return ctx->digest->get_ctx_params(ctx->provctx, params);
+
     return 0;
 }
 
@@ -683,11 +689,7 @@ const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx)
     if (ctx == NULL)
         return NULL;
 
-    if (ctx->digest != NULL
-            && ctx->digest->gettable_ctx_params != NULL)
-        return ctx->digest->gettable_ctx_params(
-                   ossl_provider_ctx(EVP_MD_provider(ctx->digest)));
-
+    /* If we have a pctx then we should try that first */
     pctx = ctx->pctx;
     if (pctx != NULL
             && (pctx->operation == EVP_PKEY_OP_VERIFYCTX
@@ -697,6 +699,11 @@ const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx)
         return pctx->op.sig.signature->gettable_ctx_md_params(
                     pctx->op.sig.sigprovctx);
 
+    if (ctx->digest != NULL
+            && ctx->digest->gettable_ctx_params != NULL)
+        return ctx->digest->gettable_ctx_params(
+                   ossl_provider_ctx(EVP_MD_provider(ctx->digest)));
+
     return NULL;
 }
 
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 04ac121e25..0278d9ca09 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -172,9 +172,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                                                        locmdname,
                                                        sizeof(locmdname)) > 0) {
                 mdname = canon_mdname(locmdname);
-            } else {
-                EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
-                return 0;
             }
         }
 
@@ -186,7 +183,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
              * so the EVP_MD should not be used beyound the lifetime of the
              * EVP_MD_CTX.
              */
-            ctx->reqdigest = ctx->fetched_digest =
+            ctx->digest = ctx->reqdigest = ctx->fetched_digest =
                 EVP_MD_fetch(locpctx->libctx, mdname, props);
         }
     }
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 503009dd93..16c674d920 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -586,64 +586,82 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
     return 1;
 }
 
-EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
-                                size_t len, const EVP_CIPHER *cipher)
+static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len,
+                                  const char *cipher_name,
+                                  const EVP_CIPHER *cipher, OPENSSL_CTX *libctx,
+                                  const char *propq, ENGINE *e)
 {
 # ifndef OPENSSL_NO_CMAC
 #  ifndef OPENSSL_NO_ENGINE
     const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
 #  endif
-    const char *cipher_name = EVP_CIPHER_name(cipher);
-    const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
-    OPENSSL_CTX *libctx =
-        prov == NULL ? NULL : ossl_provider_library_context(prov);
-    EVP_PKEY *ret = EVP_PKEY_new();
-    EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
-    EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
-    OSSL_PARAM params[4];
-    size_t paramsn = 0;
-
-    if (ret == NULL
-        || cmctx == NULL
-        || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) {
-        /* EVPerr already called */
+    OSSL_PARAM params[5], *p = params;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx;
+
+    if (cipher != NULL)
+        cipher_name = EVP_CIPHER_name(cipher);
+
+    if (cipher_name == NULL) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
+        return NULL;
+    }
+
+    ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq);
+    if (ctx == NULL) {
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
+    if (!EVP_PKEY_key_fromdata_init(ctx)) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
+        goto err;
+    }
+
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                            (void *)priv, len);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
+                                            (char *)cipher_name, 0);
+    if (propq != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES,
+                                                (char *)propq, 0);
 #  ifndef OPENSSL_NO_ENGINE
     if (engine_id != NULL)
-        params[paramsn++] =
-            OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE,
+                                                (char *)engine_id, 0);
 #  endif
+    *p = OSSL_PARAM_construct_end();
 
-    params[paramsn++] =
-        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
-                                         (char *)cipher_name, 0);
-    params[paramsn++] =
-        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                          (char *)priv, len);
-    params[paramsn] = OSSL_PARAM_construct_end();
-
-    if (!EVP_MAC_CTX_set_params(cmctx, params)) {
-        EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
+    if (!EVP_PKEY_fromdata(ctx, &pkey, params)) {
+        EVPerr(0, EVP_R_KEY_SETUP_FAILED);
         goto err;
     }
 
-    ret->pkey.ptr = cmctx;
-    return ret;
-
  err:
-    EVP_PKEY_free(ret);
-    EVP_MAC_CTX_free(cmctx);
-    EVP_MAC_free(cmac);
-    return NULL;
+    EVP_PKEY_CTX_free(ctx);
+
+    return pkey;
 # else
-    EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
-           EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+    EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return NULL;
 # endif
 }
 
+EVP_PKEY *EVP_PKEY_new_CMAC_key_with_libctx(const unsigned char *priv,
+                                            size_t len,
+                                            const char *cipher_name,
+                                            OPENSSL_CTX *libctx,
+                                            const char *propq)
+{
+    return new_cmac_key_int(priv, len, cipher_name, NULL, libctx, propq, NULL);
+}
+
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+                                size_t len, const EVP_CIPHER *cipher)
+{
+    return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e);
+}
+
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
 {
     return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c
deleted file mode 100644
index 7e36b3c6bd..0000000000
--- a/crypto/evp/pkey_mac.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/* We need to use some engine deprecated APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/engine.h>
-#include <openssl/params.h>
-#include <openssl/core_names.h>
-#include "crypto/evp.h"
-#include "evp_local.h"
-
-/* MAC PKEY context structure */
-
-typedef struct {
-    EVP_MAC_CTX *ctx;
-
-    /*
-     * We know of two MAC types:
-     *
-     * 1. those who take a secret in raw form, i.e. raw data as a
-     *    ASN1_OCTET_STRING embedded in a EVP_PKEY.  So far, that's
-     *    all of them but CMAC.
-     * 2. those who take a secret with associated cipher in very generic
-     *    form, i.e. a complete EVP_MAC_CTX embedded in a PKEY.  So far,
-     *    only CMAC does this.
-     *
-     * (one might wonder why the second form isn't used for all)
-     */
-#define MAC_TYPE_RAW    1   /* HMAC like MAC type (all but CMAC so far) */
-#define MAC_TYPE_MAC    2   /* CMAC like MAC type (only CMAC known so far) */
-    int type;
-
-    /* The following is only used for MAC_TYPE_RAW implementations */
-    struct {
-        const EVP_MD *md;           /* temp storage of MD */
-        ASN1_OCTET_STRING ktmp;     /* temp storage for key */
-    } raw_data;
-} MAC_PKEY_CTX;
-
-static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
-
-static int pkey_mac_init(EVP_PKEY_CTX *ctx)
-{
-    MAC_PKEY_CTX *hctx;
-    /* We're being smart and using the same base NIDs for PKEY and for MAC */
-    int nid = ctx->pmeth->pkey_id;
-    EVP_MAC *mac;
-
-    ERR_set_mark();
-    mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
-    ERR_pop_to_mark();
-
-    /*
-     * mac == NULL may actually be ok in some situations. In an
-     * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
-     * default libctx. We don't actually need the underlying MAC to be present
-     * to successfully set the key in that case. The resulting EVP_PKEY could
-     * then be used in some other libctx where the MAC *is* present
-     */
-
-    if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
-        EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    if (mac != NULL) {
-        hctx->ctx = EVP_MAC_CTX_new(mac);
-        if (hctx->ctx == NULL) {
-            OPENSSL_free(hctx);
-            return 0;
-        }
-    }
-
-    if (nid == EVP_PKEY_CMAC) {
-        hctx->type = MAC_TYPE_MAC;
-    } else {
-        hctx->type = MAC_TYPE_RAW;
-        hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
-    }
-
-    pkey_mac_cleanup(ctx);
-    EVP_PKEY_CTX_set_data(ctx, hctx);
-    ctx->keygen_info_count = 0;
-
-    return 1;
-}
-
-static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
-{
-    MAC_PKEY_CTX *sctx, *dctx;
-
-    sctx = EVP_PKEY_CTX_get_data(src);
-
-    if (sctx->ctx == NULL) {
-        /* This actually means the fetch failed during the init call */
-        EVPerr(0, EVP_R_FETCH_FAILED);
-        return 0;
-    }
-
-    if (sctx->ctx->data == NULL)
-        return 0;
-
-    dctx = OPENSSL_zalloc(sizeof(*dctx));
-    if (dctx == NULL) {
-        EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    EVP_PKEY_CTX_set_data(dst, dctx);
-    dst->keygen_info_count = 0;
-
-    dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
-    if (dctx->ctx == NULL)
-        goto err;
-
-    /*
-     * Normally, nothing special would be done with the MAC method.  In
-     * this particular case, though, the MAC method was fetched internally
-     * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
-     * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
-     * fetches the MAC method anew in this case.  Therefore, its reference
-     * count must be adjusted here.
-     */
-    if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
-        goto err;
-
-    dctx->type = sctx->type;
-
-    switch (dctx->type) {
-    case MAC_TYPE_RAW:
-        dctx->raw_data.md = sctx->raw_data.md;
-        if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
-            !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
-            goto err;
-        break;
-    case MAC_TYPE_MAC:
-        /* Nothing more to do */
-        break;
-    default:
-        /* This should be dead code */
-        return 0;
-    }
-    return 1;
- err:
-    pkey_mac_cleanup(dst);
-    return 0;
-}
-
-static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
-{
-    /*
-     * For the exact same reasons the MAC reference count is incremented
-     * in pkey_mac_copy() above, it must be explicitly freed here.
-     */
-
-    MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
-
-    if (hctx != NULL) {
-        EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
-
-        switch (hctx->type) {
-        case MAC_TYPE_RAW:
-            OPENSSL_clear_free(hctx->raw_data.ktmp.data,
-                               hctx->raw_data.ktmp.length);
-            break;
-        }
-        EVP_MAC_CTX_free(hctx->ctx);
-        EVP_MAC_free(mac);
-        OPENSSL_free(hctx);
-        EVP_PKEY_CTX_set_data(ctx, NULL);
-    }
-}
-
-static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-    int nid = ctx->pmeth->pkey_id;
-
-    switch (hctx->type) {
-    case MAC_TYPE_RAW:
-        {
-            ASN1_OCTET_STRING *hkey = NULL;
-
-            if (!hctx->raw_data.ktmp.data)
-                return 0;
-            hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
-            if (!hkey)
-                return 0;
-            EVP_PKEY_assign(pkey, nid, hkey);
-        }
-        break;
-    case MAC_TYPE_MAC:
-        {
-            EVP_MAC_CTX *cmkey;
-
-            if (hctx->ctx == NULL) {
-                /* This actually means the fetch failed during the init call */
-                EVPerr(0, EVP_R_FETCH_FAILED);
-                return 0;
-            }
-
-            cmkey = EVP_MAC_CTX_dup(hctx->ctx);
-            if (cmkey == NULL)
-                return 0;
-            if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
-                return 0;
-            EVP_PKEY_assign(pkey, nid, cmkey);
-        }
-        break;
-    default:
-        /* This should be dead code */
-        return 0;
-    }
-
-    return 1;
-}
-
-static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
-
-    if (!EVP_MAC_update(hctx->ctx, data, count))
-        return 0;
-    return 1;
-}
-
-static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-    ASN1_OCTET_STRING *key = NULL;
-    int rv = 1;
-    /*
-     * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
-     * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
-     * as this may be only time it's set during a DigestSign.
-     *
-     * MACs that pass around the key in form of EVP_MAC_CTX are setting
-     * the key through other mechanisms.  (this is only CMAC for now)
-     */
-    int set_key =
-        hctx->type == MAC_TYPE_RAW
-        && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
-
-    if (hctx->ctx == NULL) {
-        /* This actually means the fetch failed during the init call */
-        EVPerr(0, EVP_R_FETCH_FAILED);
-        return 0;
-    }
-
-    if (set_key) {
-        if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
-                          OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
-            return 0;
-        key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
-        if (key == NULL)
-            return 0;
-    }
-
-    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-    EVP_MD_CTX_set_update_fn(mctx, int_update);
-
-    /* Some MACs don't support this control...  that's fine */
-    {
-        OSSL_PARAM params[3];
-        size_t params_n = 0;
-        int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
-
-        /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
-        params[params_n++] =
-            OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
-        if (set_key)
-            params[params_n++] =
-                OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                                  key->data, key->length);
-        params[params_n++] = OSSL_PARAM_construct_end();
-        rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
-    }
-    return rv;
-}
-
-static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
-                             size_t *siglen, EVP_MD_CTX *mctx)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-
-    return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
-}
-
-static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-
-    switch (type) {
-
-    case EVP_PKEY_CTRL_CIPHER:
-        switch (hctx->type) {
-        case MAC_TYPE_RAW:
-            return -2;       /* The raw types don't support ciphers */
-        case MAC_TYPE_MAC:
-            {
-                OSSL_PARAM params[3];
-                size_t params_n = 0;
-                char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
-
-#ifndef OPENSSL_NO_ENGINE
-                if (ctx->engine != NULL) {
-                    char *engid = (char *)ENGINE_get_id(ctx->engine);
-
-                    params[params_n++] =
-                        OSSL_PARAM_construct_utf8_string("engine", engid, 0);
-                }
-#endif
-                params[params_n++] =
-                    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
-                                                     ciphname, 0);
-                params[params_n] = OSSL_PARAM_construct_end();
-
-                if (hctx->ctx == NULL) {
-                    /*
-                     * This actually means the fetch failed during the init call
-                     */
-                    EVPerr(0, EVP_R_FETCH_FAILED);
-                    return 0;
-                }
-
-                if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
-                    || !EVP_MAC_init(hctx->ctx))
-                    return 0;
-            }
-            break;
-        default:
-            /* This should be dead code */
-            return 0;
-        }
-        break;
-
-    case EVP_PKEY_CTRL_MD:
-        switch (hctx->type) {
-        case MAC_TYPE_RAW:
-            hctx->raw_data.md = p2;
-            break;
-        case MAC_TYPE_MAC: {
-                EVP_MAC_CTX *new_mac_ctx;
-
-                if (ctx->pkey == NULL)
-                    return 0;
-                new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
-                if (new_mac_ctx == NULL)
-                    return 0;
-                EVP_MAC_CTX_free(hctx->ctx);
-                hctx->ctx = new_mac_ctx;
-            }
-            break;
-        default:
-            /* This should be dead code */
-            return 0;
-        }
-        break;
-
-    case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
-        {
-            OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
-            size_t size = (size_t)p1;
-            size_t verify = 0;
-
-            /*
-             * We verify that the length is actually set by getting back
-             * the same parameter and checking that it matches what we
-             * tried to set.
-             * TODO(3.0) when we have a more direct mechanism to check if
-             * a parameter was used, we must refactor this to use that.
-             */
-
-            params[0] =
-                OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
-
-            if (hctx->ctx == NULL) {
-                /*
-                 * This actually means the fetch failed during the init call
-                 */
-                EVPerr(0, EVP_R_FETCH_FAILED);
-                return 0;
-            }
-
-            if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
-                return 0;
-
-            params[0] =
-                OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
-
-            if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
-                return 0;
-
-            /*
-             * Since EVP_MAC_{get,set}_ctx_params() returned successfully,
-             * we can only assume that the size was ignored, i.e. this
-             * control is unsupported.
-             */
-            if (verify != size)
-                return -2;
-        }
-        break;
-    case EVP_PKEY_CTRL_SET_MAC_KEY:
-        switch (hctx->type) {
-        case MAC_TYPE_RAW:
-            if ((!p2 && p1 > 0) || (p1 < -1))
-                return 0;
-            if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
-                return 0;
-            break;
-        case MAC_TYPE_MAC:
-            {
-                OSSL_PARAM params[2];
-                size_t params_n = 0;
-
-                params[params_n++] =
-                    OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                                      p2, p1);
-                params[params_n] = OSSL_PARAM_construct_end();
-
-                if (hctx->ctx == NULL) {
-                    /*
-                     * This actually means the fetch failed during the init call
-                     */
-                    EVPerr(0, EVP_R_FETCH_FAILED);
-                    return 0;
-                }
-
-                return EVP_MAC_CTX_set_params(hctx->ctx, params);
-            }
-            break;
-        default:
-            /* This should be dead code */
-            return 0;
-        }
-        break;
-
-    case EVP_PKEY_CTRL_DIGESTINIT:
-        switch (hctx->type) {
-        case MAC_TYPE_RAW:
-            if (hctx->ctx == NULL) {
-                /* This actually means the fetch failed during the init call */
-                EVPerr(0, EVP_R_FETCH_FAILED);
-                return 0;
-            }
-
-            /* Ensure that we have attached the implementation */
-            if (!EVP_MAC_init(hctx->ctx))
-                return 0;
-            {
-                ASN1_OCTET_STRING *key =
-                    (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
-                OSSL_PARAM params[4];
-                size_t params_n = 0;
-                char *mdname =
-                    (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
-
-#ifndef OPENSSL_NO_ENGINE
-                if (ctx->engine != NULL) {
-                    char *engid = (char *)ENGINE_get_id(ctx->engine);
-
-                    params[params_n++] =
-                        OSSL_PARAM_construct_utf8_string("engine", engid, 0);
-                }
-#endif
-                params[params_n++] =
-                    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
-                                                     mdname, 0);
-                params[params_n++] =
-                    OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
-                                                      key->data, key->length);
-                params[params_n] = OSSL_PARAM_construct_end();
-
-                return EVP_MAC_CTX_set_params(hctx->ctx, params);
-            }
-            break;
-        case MAC_TYPE_MAC:
-            return -2;       /* The mac types don't support ciphers */
-        default:
-            /* This should be dead code */
-            return 0;
-        }
-        break;
-
-    default:
-        return -2;
-
-    }
-    return 1;
-}
-
-static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
-                             const char *type, const char *value)
-{
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-    const EVP_MAC *mac;
-    OSSL_PARAM params[2];
-    int ok = 0;
-
-    if (hctx == NULL) {
-        EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX);
-        return 0;
-    }
-    if (hctx->ctx == NULL) {
-        /* This actually means the fetch failed during the init call */
-        EVPerr(0, EVP_R_FETCH_FAILED);
-        return 0;
-    }
-    mac = EVP_MAC_CTX_mac(hctx->ctx);
-
-    /*
-     * Translation of some control names that are equivalent to a single
-     * parameter name.
-     *
-     * "md" and "digest" are the same thing, we use the single "digest"
-     *
-     * "digestsize" was a setting control in siphash, but naming wise,
-     * it's really the same as "size".
-     */
-    if (strcmp(type, "md") == 0)
-        type = OSSL_MAC_PARAM_DIGEST;
-    else if (strcmp(type, "digestsize") == 0)
-        type = OSSL_MAC_PARAM_SIZE;
-
-    if (!OSSL_PARAM_allocate_from_text(&params[0],
-                                       EVP_MAC_settable_ctx_params(mac),
-                                       type, value, strlen(value) + 1, NULL))
-        return 0;
-    params[1] = OSSL_PARAM_construct_end();
-
-    ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
-    OPENSSL_free(params[0].data);
-    return ok;
-}
-
-static const EVP_PKEY_METHOD cmac_pkey_meth = {
-    EVP_PKEY_CMAC,
-    EVP_PKEY_FLAG_SIGCTX_CUSTOM,
-    pkey_mac_init,
-    pkey_mac_copy,
-    pkey_mac_cleanup,
-
-    0, 0,
-
-    0,
-    pkey_mac_keygen,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_signctx_init,
-    pkey_mac_signctx,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_ctrl,
-    pkey_mac_ctrl_str
-};
-
-const EVP_PKEY_METHOD *cmac_pkey_method(void)
-{
-    return &cmac_pkey_meth;
-}
-
-static const EVP_PKEY_METHOD hmac_pkey_meth = {
-    EVP_PKEY_HMAC,
-    0,
-    pkey_mac_init,
-    pkey_mac_copy,
-    pkey_mac_cleanup,
-
-    0, 0,
-
-    0,
-    pkey_mac_keygen,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_signctx_init,
-    pkey_mac_signctx,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_ctrl,
-    pkey_mac_ctrl_str
-};
-
-const EVP_PKEY_METHOD *hmac_pkey_method(void)
-{
-    return &hmac_pkey_meth;
-}
-
-static const EVP_PKEY_METHOD siphash_pkey_meth = {
-    EVP_PKEY_SIPHASH,
-    EVP_PKEY_FLAG_SIGCTX_CUSTOM,
-    pkey_mac_init,
-    pkey_mac_copy,
-    pkey_mac_cleanup,
-
-    0, 0,
-
-    0,
-    pkey_mac_keygen,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_signctx_init,
-    pkey_mac_signctx,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_ctrl,
-    pkey_mac_ctrl_str
-};
-
-const EVP_PKEY_METHOD *siphash_pkey_method(void)
-{
-    return &siphash_pkey_meth;
-}
-
-static const EVP_PKEY_METHOD poly1305_pkey_meth = {
-    EVP_PKEY_POLY1305,
-    EVP_PKEY_FLAG_SIGCTX_CUSTOM,
-    pkey_mac_init,
-    pkey_mac_copy,
-    pkey_mac_cleanup,
-
-    0, 0,
-
-    0,
-    pkey_mac_keygen,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_signctx_init,
-    pkey_mac_signctx,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    0, 0,
-
-    pkey_mac_ctrl,
-    pkey_mac_ctrl_str
-};
-
-const EVP_PKEY_METHOD *poly1305_pkey_method(void)
-{
-    return &poly1305_pkey_meth;
-}
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 7fd5339537..aef7c39a20 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -51,10 +51,6 @@ static pmeth_fn standard_methods[] = {
 # endif
 # ifndef OPENSSL_NO_EC
     ec_pkey_method,
-# endif
-    hmac_pkey_method,
-# ifndef OPENSSL_NO_CMAC
-    cmac_pkey_method,
 # endif
 # ifndef OPENSSL_NO_RSA
     rsa_pss_pkey_method,
@@ -66,12 +62,6 @@ static pmeth_fn standard_methods[] = {
     ecx25519_pkey_method,
     ecx448_pkey_method,
 # endif
-# ifndef OPENSSL_NO_POLY1305
-    poly1305_pkey_method,
-# endif
-# ifndef OPENSSL_NO_SIPHASH
-    siphash_pkey_method,
-# endif
 # ifndef OPENSSL_NO_EC
     ed25519_pkey_method,
     ed448_pkey_method,
@@ -150,10 +140,6 @@ static int is_legacy_alg(int id, const char *keytype)
      * support
      */
     case EVP_PKEY_SM2:
-    case EVP_PKEY_CMAC:
-    case EVP_PKEY_HMAC:
-    case EVP_PKEY_SIPHASH:
-    case EVP_PKEY_POLY1305:
         return 1;
     default:
         return 0;
@@ -845,7 +831,7 @@ static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback,
 {
     OSSL_PARAM octet_string_params[2], *p = octet_string_params;
 
-    if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
+    if (ctx == NULL || (ctx->operation & op) == 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
         return -2;
@@ -1027,17 +1013,19 @@ int EVP_PKEY_CTX_set_scrypt_maxmem_bytes(EVP_PKEY_CTX *ctx,
                                    maxmem_bytes);
 }
 
+int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key,
+                             int keylen)
+{
+    return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.keymgmt.genctx == NULL,
+                                          OSSL_PKEY_PARAM_PRIV_KEY,
+                                          EVP_PKEY_OP_KEYGEN,
+                                          EVP_PKEY_CTRL_SET_MAC_KEY,
+                                          key, keylen);
+}
+
 static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
                                 int cmd, int p1, void *p2)
 {
-    /*
-     * GOST CMS format is different for different cipher algorithms.
-     * Most of other algorithms don't have such a difference
-     * so this ctrl is just ignored.
-     */
-    if (cmd == EVP_PKEY_CTRL_CIPHER)
-        return -2;
-
 # ifndef OPENSSL_NO_DH
     if (keytype == EVP_PKEY_DHX) {
         switch (cmd) {
@@ -1186,6 +1174,29 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
             case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
                 return EVP_PKEY_CTX_set_scrypt_maxmem_bytes(ctx, p1);
             }
+        } else if (optype == EVP_PKEY_OP_KEYGEN) {
+            OSSL_PARAM params[2], *p = params;
+
+            switch (cmd) {
+            case EVP_PKEY_CTRL_CIPHER:
+                {
+                    char *ciphname = (char *)EVP_CIPHER_name(p2);
+
+                    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
+                                                            ciphname, 0);
+                    *p = OSSL_PARAM_construct_end();
+
+                    return EVP_PKEY_CTX_set_params(ctx, params);
+                }
+            case EVP_PKEY_CTRL_SET_MAC_KEY:
+                {
+                    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                                             p2, p1);
+                    *p = OSSL_PARAM_construct_end();
+
+                    return EVP_PKEY_CTX_set_params(ctx, params);
+                }
+            }
         }
         switch (cmd) {
         case EVP_PKEY_CTRL_MD:
@@ -1216,6 +1227,15 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
             return -2;
         }
     }
+
+    /*
+     * GOST CMS format is different for different cipher algorithms.
+     * Most of other algorithms don't have such a difference
+     * so this ctrl is just ignored.
+     */
+    if (cmd == EVP_PKEY_CTRL_CIPHER)
+        return -2;
+
     return 0;
 }
 
diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info
index 4ed90c09f4..b828ab122e 100644
--- a/crypto/hmac/build.info
+++ b/crypto/hmac/build.info
@@ -2,5 +2,5 @@ LIBS=../../libcrypto
 
 $COMMON=hmac.c
 
-SOURCE[../../libcrypto]=$COMMON hm_ameth.c
+SOURCE[../../libcrypto]=$COMMON
 SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c
deleted file mode 100644
index a0e1556b41..0000000000
--- a/crypto/hmac/hm_ameth.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * HMAC low level APIs are deprecated for public use, but still ok for internal
- * use.
- */
-#include "internal/deprecated.h"
-
-#include <stdio.h>
-#include "internal/cryptlib.h"
-#include <openssl/evp.h>
-#include "crypto/asn1.h"
-#include "crypto/evp.h"
-
-/*
- * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output
- * length and to free up an HMAC key.
- */
-
-static int hmac_size(const EVP_PKEY *pkey)
-{
-    return EVP_MAX_MD_SIZE;
-}
-
-static void hmac_key_free(EVP_PKEY *pkey)
-{
-    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
-    if (os) {
-        if (os->data)
-            OPENSSL_cleanse(os->data, os->length);
-        ASN1_OCTET_STRING_free(os);
-    }
-}
-
-static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-{
-    switch (op) {
-    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-        *(int *)arg2 = NID_sha256;
-        return 1;
-
-    default:
-        return -2;
-    }
-}
-
-static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-{
-    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
-}
-
-static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
-                             size_t len)
-{
-    ASN1_OCTET_STRING *os;
-
-    if (pkey->pkey.ptr != NULL)
-        return 0;
-
-    os = ASN1_OCTET_STRING_new();
-    if (os == NULL)
-        return 0;
-
-
-    if (!ASN1_OCTET_STRING_set(os, priv, len)) {
-        ASN1_OCTET_STRING_free(os);
-        return 0;
-    }
-
-    pkey->pkey.ptr = os;
-    return 1;
-}
-
-static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
-                             size_t *len)
-{
-    ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
-
-    if (priv == NULL) {
-        *len = ASN1_STRING_length(os);
-        return 1;
-    }
-
-    if (os == NULL || *len < (size_t)ASN1_STRING_length(os))
-        return 0;
-
-    *len = ASN1_STRING_length(os);
-    memcpy(priv, ASN1_STRING_get0_data(os), *len);
-
-    return 1;
-}
-
-const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
-    EVP_PKEY_HMAC,
-    EVP_PKEY_HMAC,
-    0,
-
-    "HMAC",
-    "OpenSSL HMAC method",
-
-    0, 0, hmac_pkey_public_cmp, 0,
-
-    0, 0, 0,
-
-    hmac_size,
-    0, 0,
-    0, 0, 0, 0, 0, 0, 0,
-
-    hmac_key_free,
-    hmac_pkey_ctrl,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    hmac_set_priv_key,
-    NULL,
-    hmac_get_priv_key,
-    NULL,
-};
diff --git a/crypto/poly1305/build.info b/crypto/poly1305/build.info
index 6425a01583..b3078f21cc 100644
--- a/crypto/poly1305/build.info
+++ b/crypto/poly1305/build.info
@@ -29,7 +29,7 @@ IF[{- !$disabled{asm} -}]
   ENDIF
 ENDIF
 
-SOURCE[../../libcrypto]=poly1305_ameth.c poly1305.c $POLY1305ASM
+SOURCE[../../libcrypto]=poly1305.c $POLY1305ASM
 
 # Implementations are now spread across several libraries, so the defines
 # need to be applied to all affected libraries and modules.
diff --git a/crypto/poly1305/poly1305_ameth.c b/crypto/poly1305/poly1305_ameth.c
deleted file mode 100644
index 2feec9ccc3..0000000000
--- a/crypto/poly1305/poly1305_ameth.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include "internal/cryptlib.h"
-#include <openssl/evp.h>
-#include "crypto/asn1.h"
-#include "crypto/poly1305.h"
-#include "crypto/evp.h"
-
-/*
- * POLY1305 "ASN1" method. This is just here to indicate the maximum
- * POLY1305 output length and to free up a POLY1305 key.
- */
-
-static int poly1305_size(const EVP_PKEY *pkey)
-{
-    return POLY1305_DIGEST_SIZE;
-}
-
-static void poly1305_key_free(EVP_PKEY *pkey)
-{
-    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
-    if (os != NULL) {
-        if (os->data != NULL)
-            OPENSSL_cleanse(os->data, os->length);
-        ASN1_OCTET_STRING_free(os);
-    }
-}
-
-static int poly1305_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-{
-    /* nothing, (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */
-    return -2;
-}
-
-static int poly1305_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-{
-    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
-}
-
-static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
-                                 size_t len)
-{
-    ASN1_OCTET_STRING *os;
-
-    if (pkey->pkey.ptr != NULL || len != POLY1305_KEY_SIZE)
-        return 0;
-
-    os = ASN1_OCTET_STRING_new();
-    if (os == NULL)
-        return 0;
-
-    if (!ASN1_OCTET_STRING_set(os, priv, len)) {
-        ASN1_OCTET_STRING_free(os);
-        return 0;
-    }
-
-    pkey->pkey.ptr = os;
-    return 1;
-}
-
-static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
-                                 size_t *len)
-{
-    ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
-
-    if (priv == NULL) {
-        *len = POLY1305_KEY_SIZE;
-        return 1;
-    }
-
-    if (os == NULL || *len < POLY1305_KEY_SIZE)
-        return 0;
-
-    memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
-    *len = POLY1305_KEY_SIZE;
-
-    return 1;
-}
-
-const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = {
-    EVP_PKEY_POLY1305,
-    EVP_PKEY_POLY1305,
-    0,
-
-    "POLY1305",
-    "OpenSSL POLY1305 method",
-
-    0, 0, poly1305_pkey_public_cmp, 0,
-
-    0, 0, 0,
-
-    poly1305_size,
-    0, 0,
-    0, 0, 0, 0, 0, 0, 0,
-
-    poly1305_key_free,
-    poly1305_pkey_ctrl,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    poly1305_set_priv_key,
-    NULL,
-    poly1305_get_priv_key,
-    NULL,
-};
diff --git a/crypto/siphash/build.info b/crypto/siphash/build.info
index 2dc7101a10..432b6f5ec3 100644
--- a/crypto/siphash/build.info
+++ b/crypto/siphash/build.info
@@ -1,4 +1,3 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
-	siphash.c \
-	siphash_ameth.c
+	siphash.c
diff --git a/crypto/siphash/siphash_ameth.c b/crypto/siphash/siphash_ameth.c
deleted file mode 100644
index 5aa4d88915..0000000000
--- a/crypto/siphash/siphash_ameth.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include "internal/cryptlib.h"
-#include <openssl/evp.h>
-#include "crypto/asn1.h"
-#include "crypto/siphash.h"
-#include "siphash_local.h"
-#include "crypto/evp.h"
-
-/*
- * SIPHASH "ASN1" method. This is just here to indicate the maximum
- * SIPHASH output length and to free up a SIPHASH key.
- */
-
-static int siphash_size(const EVP_PKEY *pkey)
-{
-    return SIPHASH_MAX_DIGEST_SIZE;
-}
-
-static void siphash_key_free(EVP_PKEY *pkey)
-{
-    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
-
-    if (os != NULL) {
-        if (os->data != NULL)
-            OPENSSL_cleanse(os->data, os->length);
-        ASN1_OCTET_STRING_free(os);
-    }
-}
-
-static int siphash_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-{
-    /* nothing (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */
-    return -2;
-}
-
-static int siphash_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-{
-    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
-}
-
-static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
-                                size_t len)
-{
-    ASN1_OCTET_STRING *os;
-
-    if (pkey->pkey.ptr != NULL || len != SIPHASH_KEY_SIZE)
-        return 0;
-
-    os = ASN1_OCTET_STRING_new();
-    if (os == NULL)
-        return 0;
-
-    if (!ASN1_OCTET_STRING_set(os, priv, len)) {
-        ASN1_OCTET_STRING_free(os);
-        return 0;
-    }
-
-    pkey->pkey.ptr = os;
-    return 1;
-}
-
-static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
-                                size_t *len)
-{
-    ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
-
-    if (priv == NULL) {
-        *len = SIPHASH_KEY_SIZE;
-        return 1;
-    }
-
-    if (os == NULL || *len < SIPHASH_KEY_SIZE)
-        return 0;
-
-    memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
-    *len = SIPHASH_KEY_SIZE;
-
-    return 1;
-}
-
-const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = {
-    EVP_PKEY_SIPHASH,
-    EVP_PKEY_SIPHASH,
-    0,
-
-    "SIPHASH",
-    "OpenSSL SIPHASH method",
-
-    0, 0, siphash_pkey_public_cmp, 0,
-
-    0, 0, 0,
-
-    siphash_size,
-    0, 0,
-    0, 0, 0, 0, 0, 0, 0,
-
-    siphash_key_free,
-    siphash_pkey_ctrl,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    NULL,
-    NULL,
-    NULL,
-
-    siphash_set_priv_key,
-    NULL,
-    siphash_get_priv_key,
-    NULL,
-};
diff --git a/doc/man3/EVP_PKEY_new.pod b/doc/man3/EVP_PKEY_new.pod
index ff5744bebd..0543600704 100644
--- a/doc/man3/EVP_PKEY_new.pod
+++ b/doc/man3/EVP_PKEY_new.pod
@@ -9,6 +9,7 @@ EVP_PKEY_new_raw_private_key_with_libctx,
 EVP_PKEY_new_raw_private_key,
 EVP_PKEY_new_raw_public_key_with_libctx,
 EVP_PKEY_new_raw_public_key,
+EVP_PKEY_new_CMAC_key_with_libctx,
 EVP_PKEY_new_CMAC_key,
 EVP_PKEY_new_mac_key,
 EVP_PKEY_get_raw_private_key,
@@ -37,6 +38,11 @@ EVP_PKEY_get_raw_public_key
                                                    size_t keylen);
  EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
                                        const unsigned char *key, size_t keylen);
+ EVP_PKEY *EVP_PKEY_new_CMAC_key_with_libctx(const unsigned char *priv,
+                                             size_t len,
+                                             const char *cipher_name,
+                                             OPENSSL_CTX *libctx,
+                                             const char *propq);
  EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                  size_t len, const EVP_CIPHER *cipher);
  EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key,
@@ -53,10 +59,10 @@ The EVP_PKEY_new() function allocates an empty B<EVP_PKEY> structure which is
 used by OpenSSL to store public and private keys. The reference count is set to
 B<1>.
 
-EVP_PKEY_up_ref() increments the reference count of B<key>.
+EVP_PKEY_up_ref() increments the reference count of I<key>.
 
-EVP_PKEY_free() decrements the reference count of B<key> and, if the reference
-count is zero, frees it up. If B<key> is NULL, nothing is done.
+EVP_PKEY_free() decrements the reference count of I<key> and, if the reference
+count is zero, frees it up. If I<key> is NULL, nothing is done.
 
 EVP_PKEY_new_raw_private_key_with_libctx() allocates a new B<EVP_PKEY>. Unless
 an engine should be used for the key type, a provider for the key is found using
@@ -73,8 +79,8 @@ derived from the given private key data (if appropriate for the algorithm type).
 
 EVP_PKEY_new_raw_private_key() does the same as
 EVP_PKEY_new_raw_private_key_with_libctx() except that the default library
-context and default property query are used instead. If B<e> is non-NULL then
-the new B<EVP_PKEY> structure is associated with the engine B<e>. The B<type>
+context and default property query are used instead. If I<e> is non-NULL then
+the new B<EVP_PKEY> structure is associated with the engine I<e>. The I<type>
 argument indicates what kind of key this is. The value should be a NID for a
 public key algorithm that supports raw private keys, i.e. one of
 B<EVP_PKEY_POLY1305>, B<EVP_PKEY_SIPHASH>, B<EVP_PKEY_X25519>,
@@ -82,40 +88,46 @@ B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>. As for
 EVP_PKEY_new_raw_private_key_with_libctx() you may also use B<EVP_PKEY_HMAC>.
 
 EVP_PKEY_new_raw_public_key_with_libctx() works in the same way as
-EVP_PKEY_new_raw_private_key_with_libctx() except that B<key> points to the raw
+EVP_PKEY_new_raw_private_key_with_libctx() except that I<key> points to the raw
 public key data. The B<EVP_PKEY> structure will be initialised without any
 private key information. Algorithm types that support raw public keys are
 "X25519", "ED25519", "X448" or "ED448".
 
 EVP_PKEY_new_raw_public_key() works in the same way as
-EVP_PKEY_new_raw_private_key() except that B<key> points to the raw public key
+EVP_PKEY_new_raw_private_key() except that I<key> points to the raw public key
 data. The B<EVP_PKEY> structure will be initialised without any private key
 information. Algorithm types that support raw public keys are
 B<EVP_PKEY_X25519>, B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>.
 
-EVP_PKEY_new_CMAC_key() works in the same way as EVP_PKEY_new_raw_private_key()
-except it is only for the B<EVP_PKEY_CMAC> algorithm type. In addition to the
-raw private key data, it also takes a cipher algorithm to be used during
-creation of a CMAC in the B<cipher> argument. The cipher should be a standard
-encryption only cipher. For example AEAD and XTS ciphers should not be used.
+EVP_PKEY_new_CMAC_key_with_libctx() works in the same way as
+EVP_PKEY_new_raw_private_key() except it is only for the B<EVP_PKEY_CMAC>
+algorithm type. In addition to the raw private key data, it also takes a cipher
+algorithm to be used during creation of a CMAC in the I<cipher> argument. The
+cipher should be a standard encryption only cipher. For example AEAD and XTS
+ciphers should not be used. Finally it also takes a library context I<libctx>
+and property query I<propq> which are used when fetching any cryptographic
+algorithms which may be NULL to use the default values.
+
+EVP_PKEY_new_CMAC_key() is the same as EVP_PKEY_new_CMAC_key_with_libctx()
+except that the default values are used for I<libctx> and I<propq>.
 
 EVP_PKEY_new_mac_key() works in the same way as EVP_PKEY_new_raw_private_key().
 New applications should use EVP_PKEY_new_raw_private_key() instead.
 
-EVP_PKEY_get_raw_private_key() fills the buffer provided by B<priv> with raw
-private key data. The size of the B<priv> buffer should be in B<*len> on entry
-to the function, and on exit B<*len> is updated with the number of bytes
-actually written. If the buffer B<priv> is NULL then B<*len> is populated with
+EVP_PKEY_get_raw_private_key() fills the buffer provided by I<priv> with raw
+private key data. The size of the I<priv> buffer should be in I<*len> on entry
+to the function, and on exit I<*len> is updated with the number of bytes
+actually written. If the buffer I<priv> is NULL then I<*len> is populated with
 the number of bytes required to hold the key. The calling application is
 responsible for ensuring that the buffer is large enough to receive the private
 key data. This function only works for algorithms that support raw private keys.
 Currently this is: B<EVP_PKEY_HMAC>, B<EVP_PKEY_POLY1305>, B<EVP_PKEY_SIPHASH>,
 B<EVP_PKEY_X25519>, B<EVP_PKEY_ED25519>, B<EVP_PKEY_X448> or B<EVP_PKEY_ED448>.
 
-EVP_PKEY_get_raw_public_key() fills the buffer provided by B<pub> with raw
-public key data. The size of the B<pub> buffer should be in B<*len> on entry
-to the function, and on exit B<*len> is updated with the number of bytes
-actually written. If the buffer B<pub> is NULL then B<*len> is populated with
+EVP_PKEY_get_raw_public_key() fills the buffer provided by I<pub> with raw
+public key data. The size of the I<pub> buffer should be in I<*len> on entry
+to the function, and on exit I<*len> is updated with the number of bytes
+actually written. If the buffer I<pub> is NULL then I<*len> is populated with
 the number of bytes required to hold the key. The calling application is
 responsible for ensuring that the buffer is large enough to receive the public
 key data. This function only works for algorithms that support raw public  keys.
@@ -158,8 +170,9 @@ EVP_PKEY_new_raw_private_key(), EVP_PKEY_new_raw_public_key(),
 EVP_PKEY_new_CMAC_key(), EVP_PKEY_new_raw_private_key() and
 EVP_PKEY_get_raw_public_key() functions were added in OpenSSL 1.1.1.
 
-The EVP_PKEY_new_raw_private_key_with_libctx and
-EVP_PKEY_new_raw_public_key_with_libctx functions were added in OpenSSL 3.0.
+The EVP_PKEY_new_raw_private_key_with_libctx(),
+EVP_PKEY_new_raw_public_key_with_libctx() and
+EVP_PKEY_new_CMAC_key_with_libctx() functions were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
diff --git a/doc/man7/EVP_PKEY-HMAC.pod b/doc/man7/EVP_PKEY-HMAC.pod
new file mode 100644
index 0000000000..7b6c52bb03
--- /dev/null
+++ b/doc/man7/EVP_PKEY-HMAC.pod
@@ -0,0 +1,95 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY-HMAC, EVP_KEYMGMT-HMAC, EVP_PKEY-SIPHASH, EVP_KEYMGMT-SIPHASH,
+EVP_PKEY-POLY1305, EVP_KEYMGMT-POLY1305, EVP_PKEY-CMAC, EVP_KEYMGMT-CMAC
+- EVP_PKEY legacy MAC keytypes and algorithm support
+
+=head1 DESCRIPTION
+
+The B<HMAC> and B<CMAC> key types are implemented in OpenSSL's default and FIPS
+providers. Additionally the B<SIPHASH> and B<POLY1305> key types are implemented
+in the default provider. Performing MAC operations via an EVP_PKEY
+is considered legacy and are only available for backwards compatibility purposes
+and for a restricted set of algorithms. The preferred way of performing MAC
+operations is via the EVP_MAC APIs. See L<EVP_MAC_init(3)>.
+
+For further details on using EVP_PKEY based MAC keys see
+L<EVP_SIGNATURE-HMAC(7)>, L<EVP_SIGNATURE-SIPHASH(7)>,
+L<EVP_SIGNATURE-POLY1305(7)> or L<EVP_SIGNATURE-CMAC(7)>.
+
+=head2 Common MAC parameters
+
+All the B<MAC> keytypes support the following parameters.
+
+=over 4
+
+=item "priv" (B<OSSL_PKEY_PARAM_PRIV_KEY>) <octet string>
+
+The MAC key value.
+
+=item "properties" (B<OSSL_PKEY_PARAM_PROPERTIES>) <UTF8 string>
+
+A property query string to be used when any algorithms are fetched.
+
+=back
+
+=head2 CMAC parameters
+
+As well as the parameters described above, the B<CMAC> keytype additionally
+supports the following parameters.
+
+=over 4
+
+=item "cipher" (B<OSSL_PKEY_PARAM_CIPHER>) <UTF8 string>
+
+The name of a cipher to be used when generating the MAC.
+
+=item "engine" (B<OSSL_PKEY_PARAM_ENGINE>) <UTF8 string>
+
+The name of an engine to be used for the specified cipher (if any).
+
+=back
+
+=head2 Common MAC key generation parameters
+
+MAC key generation is unusual in that no new key is actually generated. Instead
+a new provider side key object is created with the supplied raw key value. This
+is done for backwards compatibility with previous versions of OpenSSL.
+
+=over 4
+
+=item "priv" (B<OSSL_PKEY_PARAM_PRIV_KEY>) <octet string>
+
+The MAC key value.
+
+=back
+
+=head2 CMAC key generation parameters
+
+In addition to the common MAC key generation parameters, the CMAC key generation
+additionally recognises the following.
+
+=over 4
+
+=item "cipher" (B<OSSL_PKEY_PARAM_CIPHER>) <UTF8 string>
+
+The name of a cipher to be used when generating the MAC.
+
+=back
+
+=head1 SEE ALSO
+
+L<EVP_KEYMGMT(3)>, L<EVP_PKEY(3)>, L<provider-keymgmt(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man7/EVP_SIGNATURE-HMAC.pod b/doc/man7/EVP_SIGNATURE-HMAC.pod
new file mode 100644
index 0000000000..dd74fae88c
--- /dev/null
+++ b/doc/man7/EVP_SIGNATURE-HMAC.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+EVP_SIGNATURE-HMAC, EVP_SIGNATURE-SIPHASH, EVP_SIGNATURE-POLY1305,
+EVP_SIGNATURE-CMAC
+- The legacy B<EVP_PKEY> MAC signature implementations
+
+=head1 DESCRIPTION
+
+The algorithms described here have legacy support for creating MACs using
+L<EVP_DigestSignInit(3)> and related functions. This is not the preferred way of
+creating MACs. Instead you should use the newer L<EVP_MAC_init(3)> functions.
+This mechanism is provided for backwards compatibility with older versions of
+OpenSSL. 
+
+There are no parameters supported by the legacy EVP_PKEY MAC signature
+algorithms. See L<EVP_PKEY-HMAC(7)>, L<EVP_PKEY-SIPHASH(7)>,
+L<EVP_PKEY-POLY1305(7)> or L<EVP_PKEY-CMAC(7)> for details about parameters that
+are supported during the creation of an EVP_PKEY.
+
+=head1 SEE ALSO
+
+L<EVP_MAC_init(3)>,
+L<EVP_DigestSignInit(3)>,
+L<EVP_PKEY-HMAC(7)>,
+L<EVP_PKEY-SIPHASH(7)>,
+L<EVP_PKEY-POLY1305(7)>,
+L<EVP_PKEY-CMAC(7)>,
+L<provider-signature(7)>,
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h
index 68672d1a02..041642f022 100644
--- a/include/crypto/asn1.h
+++ b/include/crypto/asn1.h
@@ -86,7 +86,6 @@ struct evp_pkey_asn1_method_st {
 
 DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
 
-extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5];
@@ -96,12 +95,9 @@ extern const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD ed448_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD sm2_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth;
 
-extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2];
 extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD siphash_asn1_meth;
 
 /*
  * These are used internally in the ASN1_OBJECT to keep track of whether the
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 512b4d6f48..634eb86425 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -131,7 +131,6 @@ DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD)
 
 void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
 
-const EVP_PKEY_METHOD *cmac_pkey_method(void);
 const EVP_PKEY_METHOD *dh_pkey_method(void);
 const EVP_PKEY_METHOD *dhx_pkey_method(void);
 const EVP_PKEY_METHOD *dsa_pkey_method(void);
@@ -141,11 +140,8 @@ const EVP_PKEY_METHOD *ecx25519_pkey_method(void);
 const EVP_PKEY_METHOD *ecx448_pkey_method(void);
 const EVP_PKEY_METHOD *ed25519_pkey_method(void);
 const EVP_PKEY_METHOD *ed448_pkey_method(void);
-const EVP_PKEY_METHOD *hmac_pkey_method(void);
 const EVP_PKEY_METHOD *rsa_pkey_method(void);
 const EVP_PKEY_METHOD *rsa_pss_pkey_method(void);
-const EVP_PKEY_METHOD *poly1305_pkey_method(void);
-const EVP_PKEY_METHOD *siphash_pkey_method(void);
 
 struct evp_mac_st {
     OSSL_PROVIDER *prov;
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 4ca794fd50..3be69d5774 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -56,6 +56,7 @@ extern "C" {
  */
 #define OSSL_ALG_PARAM_DIGEST       "digest"    /* utf8_string */
 #define OSSL_ALG_PARAM_CIPHER       "cipher"    /* utf8_string */
+#define OSSL_ALG_PARAM_ENGINE       "engine"    /* utf8_string */
 #define OSSL_ALG_PARAM_MAC          "mac"       /* utf8_string */
 #define OSSL_ALG_PARAM_PROPERTIES   "properties"/* utf8_string */
 
@@ -247,6 +248,8 @@ extern "C" {
 #define OSSL_PKEY_PARAM_MAX_SIZE            "max-size" /* integer */
 #define OSSL_PKEY_PARAM_SECURITY_BITS       "security-bits" /* integer */
 #define OSSL_PKEY_PARAM_DIGEST              OSSL_ALG_PARAM_DIGEST
+#define OSSL_PKEY_PARAM_CIPHER              OSSL_ALG_PARAM_CIPHER /* utf8 string */
+#define OSSL_PKEY_PARAM_ENGINE              OSSL_ALG_PARAM_ENGINE /* utf8 string */
 #define OSSL_PKEY_PARAM_PROPERTIES          OSSL_ALG_PARAM_PROPERTIES
 #define OSSL_PKEY_PARAM_DEFAULT_DIGEST      "default-digest" /* utf8 string */
 #define OSSL_PKEY_PARAM_MANDATORY_DIGEST    "mandatory-digest" /* utf8 string */
@@ -257,8 +260,6 @@ extern "C" {
 #define OSSL_PKEY_PARAM_MGF1_PROPERTIES     "mgf1-properties"
 #define OSSL_PKEY_PARAM_TLS_ENCODED_PT      "tls-encoded-pt"
 #define OSSL_PKEY_PARAM_GROUP_NAME          "group"
-
-/* Diffie-Hellman/DSA public/private key */
 #define OSSL_PKEY_PARAM_PUB_KEY             "pub"
 #define OSSL_PKEY_PARAM_PRIV_KEY            "priv"
 
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 62015a7b1b..6bd6e26edf 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1526,9 +1526,8 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
 # define EVP_PKEY_OP_TYPE_FROMDATA \
         (EVP_PKEY_OP_PARAMFROMDATA | EVP_PKEY_OP_KEYFROMDATA)
 
-# define  EVP_PKEY_CTX_set_mac_key(ctx, key, len)        \
-                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN,  \
-                                  EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key))
+int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key,
+                             int keylen);
 
 # define EVP_PKEY_CTRL_MD                1
 # define EVP_PKEY_CTRL_PEER_KEY          2
@@ -1636,6 +1635,11 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
 int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
                                 size_t *len);
 
+EVP_PKEY *EVP_PKEY_new_CMAC_key_with_libctx(const unsigned char *priv,
+                                            size_t len,
+                                            const char *cipher_name,
+                                            OPENSSL_CTX *libctx,
+                                            const char *propq);
 EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                 size_t len, const EVP_CIPHER *cipher);
 
diff --git a/providers/common/include/prov/provider_util.h b/providers/common/include/prov/provider_util.h
index 9b5b983299..d964f832ad 100644
--- a/providers/common/include/prov/provider_util.h
+++ b/providers/common/include/prov/provider_util.h
@@ -78,6 +78,21 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
 const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
 ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
 
+
+/*
+ * Set the various parameters on an EVP_MAC_CTX from the supplied arguments.
+ * If any of the supplied ciphername/mdname etc are NULL then the values
+ * from the supplied params (if non NULL) are used instead.
+ */
+int ossl_prov_set_macctx(EVP_MAC_CTX *macctx,
+                         const OSSL_PARAM params[],
+                         const char *ciphername,
+                         const char *mdname,
+                         const char *engine,
+                         const char *properties,
+                         const unsigned char *key,
+                         size_t keylen);
+
 /* MAC functions */
 /*
  * Load an EVP_MAC_CTX* from the specified parameters with the specified
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
index f6155e7dce..1bd514221f 100644
--- a/providers/common/provider_util.c
+++ b/providers/common/provider_util.c
@@ -50,7 +50,7 @@ static int load_common(const OSSL_PARAM params[], const char **propquery,
     /* TODO legacy stuff, to be removed */
     /* Inside the FIPS module, we don't support legacy ciphers */
 #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
-    p = OSSL_PARAM_locate_const(params, "engine");
+    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE);
     if (p != NULL) {
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
@@ -164,6 +164,72 @@ ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
     return pd->engine;
 }
 
+int ossl_prov_set_macctx(EVP_MAC_CTX *macctx,
+                         const OSSL_PARAM params[],
+                         const char *ciphername,
+                         const char *mdname,
+                         const char *engine,
+                         const char *properties,
+                         const unsigned char *key,
+                         size_t keylen)
+{
+    const OSSL_PARAM *p;
+    OSSL_PARAM mac_params[6], *mp = mac_params;
+
+    if (params != NULL) {
+        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 (engine == NULL) {
+            if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE))
+                    != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+                engine = 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_CIPHER,
+                                                 (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_MODULE)
+    if (engine != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE,
+                                                 (char *) engine, 0);
+#endif
+
+    if (key != NULL)
+        *mp++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                  (unsigned char *)key,
+                                                  keylen);
+
+    *mp = OSSL_PARAM_construct_end();
+
+    return EVP_MAC_CTX_set_params(macctx, mac_params);
+
+}
+
 int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
                                       const OSSL_PARAM params[],
                                       const char *macname,
@@ -172,7 +238,6 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
                                       OPENSSL_CTX *libctx)
 {
     const OSSL_PARAM *p;
-    OSSL_PARAM mac_params[5], *mp = mac_params;
     const char *properties = NULL;
 
     if (macname == NULL
@@ -207,44 +272,8 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
     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_CIPHER,
-                                                 (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_MODULE)
-    if ((p = OSSL_PARAM_locate_const(params, "engine")) != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        *mp++ = OSSL_PARAM_construct_utf8_string("engine",
-                                                 p->data, p->data_size);
-    }
-#endif
-    *mp = OSSL_PARAM_construct_end();
-
-    if (EVP_MAC_CTX_set_params(*macctx, mac_params))
+    if (ossl_prov_set_macctx(*macctx, params, ciphername, mdname, NULL,
+                             properties, NULL, 0))
         return 1;
 
     EVP_MAC_CTX_free(*macctx);
diff --git a/providers/defltprov.c b/providers/defltprov.c
index 9aefa801a1..943bdc6136 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -363,6 +363,14 @@ static const OSSL_ALGORITHM deflt_signature[] = {
     { "ED25519:Ed25519", "provider=default", ed25519_signature_functions },
     { "ED448:Ed448", "provider=default", ed448_signature_functions },
     { "ECDSA", "provider=default", ecdsa_signature_functions },
+#endif
+    { "HMAC", "provider=default", mac_legacy_hmac_signature_functions },
+    { "SIPHASH", "provider=default", mac_legacy_siphash_signature_functions },
+#ifndef OPENSSL_NO_POLY1305
+    { "POLY1305", "provider=default", mac_legacy_poly1305_signature_functions },
+#endif
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", "provider=default", mac_legacy_cmac_signature_functions },
 #endif
     { NULL, NULL, NULL }
 };
@@ -392,6 +400,14 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
     { "TLS1-PRF", "provider=default", kdf_keymgmt_functions },
     { "HKDF", "provider=default", kdf_keymgmt_functions },
     { "SCRYPT:id-scrypt", "provider=default", kdf_keymgmt_functions },
+    { "HMAC", "provider=default", mac_legacy_keymgmt_functions },
+    { "SIPHASH", "provider=default", mac_legacy_keymgmt_functions },
+#ifndef OPENSSL_NO_POLY1305
+    { "POLY1305", "provider=default", mac_legacy_keymgmt_functions },
+#endif
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", "provider=default", cmac_legacy_keymgmt_functions },
+#endif
     { NULL, NULL, NULL }
 };
 
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index b29cae509c..c9867f998c 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -435,6 +435,10 @@ static const OSSL_ALGORITHM fips_signature[] = {
     { "ED25519", FIPS_DEFAULT_PROPERTIES, ed25519_signature_functions },
     { "ED448", FIPS_DEFAULT_PROPERTIES, ed448_signature_functions },
     { "ECDSA", FIPS_DEFAULT_PROPERTIES, ecdsa_signature_functions },
+#endif
+    { "HMAC", FIPS_DEFAULT_PROPERTIES, mac_legacy_hmac_signature_functions },
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", FIPS_DEFAULT_PROPERTIES, mac_legacy_cmac_signature_functions },
 #endif
     { NULL, NULL, NULL }
 };
@@ -464,6 +468,10 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
 #endif
     { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, kdf_keymgmt_functions },
     { "HKDF", FIPS_DEFAULT_PROPERTIES, kdf_keymgmt_functions },
+    { "HMAC", FIPS_DEFAULT_PROPERTIES, mac_legacy_keymgmt_functions },
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", FIPS_DEFAULT_PROPERTIES, cmac_legacy_keymgmt_functions },
+#endif
     { NULL, NULL, NULL }
 };
 
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index f07a7b00f0..1b8642415f 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -278,6 +278,8 @@ extern const OSSL_DISPATCH ed25519_keymgmt_functions[];
 extern const OSSL_DISPATCH ed448_keymgmt_functions[];
 extern const OSSL_DISPATCH ec_keymgmt_functions[];
 extern const OSSL_DISPATCH kdf_keymgmt_functions[];
+extern const OSSL_DISPATCH mac_legacy_keymgmt_functions[];
+extern const OSSL_DISPATCH cmac_legacy_keymgmt_functions[];
 
 /* Key Exchange */
 extern const OSSL_DISPATCH dh_keyexch_functions[];
@@ -294,7 +296,10 @@ extern const OSSL_DISPATCH rsa_signature_functions[];
 extern const OSSL_DISPATCH ed25519_signature_functions[];
 extern const OSSL_DISPATCH ed448_signature_functions[];
 extern const OSSL_DISPATCH ecdsa_signature_functions[];
-
+extern const OSSL_DISPATCH mac_legacy_hmac_signature_functions[];
+extern const OSSL_DISPATCH mac_legacy_siphash_signature_functions[];
+extern const OSSL_DISPATCH mac_legacy_poly1305_signature_functions[];
+extern const OSSL_DISPATCH mac_legacy_cmac_signature_functions[];
 
 /* Asym Cipher */
 extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
diff --git a/providers/implementations/include/prov/kdfexchange.h b/providers/implementations/include/prov/macsignature.h
similarity index 60%
copy from providers/implementations/include/prov/kdfexchange.h
copy to providers/implementations/include/prov/macsignature.h
index 5c817bb929..bec5c46fbe 100644
--- a/providers/implementations/include/prov/kdfexchange.h
+++ b/providers/implementations/include/prov/macsignature.h
@@ -10,15 +10,21 @@
 #include <stdlib.h>
 #include <openssl/crypto.h>
 #include "internal/refcount.h"
+#include "prov/provider_util.h"
 
-struct kdf_data_st {
+struct mac_key_st {
+    CRYPTO_RWLOCK *lock;
     OPENSSL_CTX *libctx;
     CRYPTO_REF_COUNT refcnt;
-    CRYPTO_RWLOCK *lock;
+    unsigned char *priv_key;
+    size_t priv_key_len;
+    PROV_CIPHER cipher;
+    char *properties;
+    int cmac;
 };
 
-typedef struct kdf_data_st KDF_DATA;
+typedef struct mac_key_st MAC_KEY;
 
-KDF_DATA *kdf_data_new(void *provctx);
-void kdf_data_free(KDF_DATA *kdfdata);
-int kdf_data_up_ref(KDF_DATA *kdfdata);
+MAC_KEY *mac_key_new(OPENSSL_CTX *libctx, int cmac);
+void mac_key_free(MAC_KEY *mackey);
+int mac_key_up_ref(MAC_KEY *mackey);
diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info
index 53c84ac3d4..978cd706ae 100644
--- a/providers/implementations/keymgmt/build.info
+++ b/providers/implementations/keymgmt/build.info
@@ -36,3 +36,6 @@ SOURCE[../../libfips.a]=rsa_kmgmt.c
 SOURCE[../../libnonfips.a]=rsa_kmgmt.c
 
 SOURCE[$KDF_GOAL]=kdf_legacy_kmgmt.c
+
+SOURCE[../../libfips.a]=mac_legacy_kmgmt.c
+SOURCE[../../libnonfips.a]=mac_legacy_kmgmt.c
diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
new file mode 100644
index 0000000000..dd18eecf12
--- /dev/null
+++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* We need to use some engine deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
+#include <string.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include "openssl/param_build.h"
+#include "internal/param_build_set.h"
+#include "prov/implementations.h"
+#include "prov/providercommon.h"
+#include "prov/provider_ctx.h"
+#include "prov/macsignature.h"
+#include "e_os.h" /* strcasecmp */
+
+static OSSL_FUNC_keymgmt_new_fn mac_new;
+static OSSL_FUNC_keymgmt_free_fn mac_free;
+static OSSL_FUNC_keymgmt_gen_init_fn mac_gen_init;
+static OSSL_FUNC_keymgmt_gen_fn mac_gen;
+static OSSL_FUNC_keymgmt_gen_cleanup_fn mac_gen_cleanup;
+static OSSL_FUNC_keymgmt_get_params_fn mac_get_params;
+static OSSL_FUNC_keymgmt_gettable_params_fn mac_gettable_params;
+static OSSL_FUNC_keymgmt_set_params_fn mac_set_params;
+static OSSL_FUNC_keymgmt_settable_params_fn mac_settable_params;
+static OSSL_FUNC_keymgmt_has_fn mac_has;
+static OSSL_FUNC_keymgmt_match_fn mac_match;
+static OSSL_FUNC_keymgmt_import_fn mac_import;
+static OSSL_FUNC_keymgmt_import_types_fn mac_imexport_types;
+static OSSL_FUNC_keymgmt_export_fn mac_export;
+static OSSL_FUNC_keymgmt_export_types_fn mac_imexport_types;
+
+struct mac_gen_ctx {
+    OPENSSL_CTX *libctx;
+    int selection;
+    unsigned char *priv_key;
+    size_t priv_key_len;
+    PROV_CIPHER cipher;
+};
+
+MAC_KEY *mac_key_new(OPENSSL_CTX *libctx, int cmac)
+{
+    MAC_KEY *mackey = OPENSSL_zalloc(sizeof(*mackey));
+
+    if (mackey == NULL)
+        return NULL;
+
+    mackey->lock = CRYPTO_THREAD_lock_new();
+    if (mackey->lock == NULL) {
+        OPENSSL_free(mackey);
+        return NULL;
+    }
+    mackey->libctx = libctx;
+    mackey->refcnt = 1;
+    mackey->cmac = cmac;
+
+    return mackey;
+}
+
+void mac_key_free(MAC_KEY *mackey)
+{
+    int ref = 0;
+
+    if (mackey == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&mackey->refcnt, &ref, mackey->lock);
+    if (ref > 0)
+        return;
+
+    OPENSSL_secure_clear_free(mackey->priv_key, mackey->priv_key_len);
+    OPENSSL_free(mackey->properties);
+    ossl_prov_cipher_reset(&mackey->cipher);
+    CRYPTO_THREAD_lock_free(mackey->lock);
+    OPENSSL_free(mackey);
+}
+
+int mac_key_up_ref(MAC_KEY *mackey)
+{
+    int ref = 0;
+
+    CRYPTO_UP_REF(&mackey->refcnt, &ref, mackey->lock);
+    return 1;
+}
+
+static void *mac_new(void *provctx)
+{
+    return mac_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), 0);
+}
+
+static void *mac_new_cmac(void *provctx)
+{
+    return mac_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), 1);
+}
+
+static void mac_free(void *mackey)
+{
+    mac_key_free(mackey);
+}
+
+static int mac_has(void *keydata, int selection)
+{
+    MAC_KEY *key = keydata;
+    int ok = 0;
+
+    if (key != NULL) {
+        /*
+         * MAC keys always have all the parameters they need (i.e. none).
+         * Therefore we always return with 1, if asked about parameters.
+         * Similarly for public keys.
+         */
+        ok = 1;
+
+        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+            ok = key->priv_key != NULL;
+    }
+    return ok;
+}
+
+static int mac_match(const void *keydata1, const void *keydata2, int selection)
+{
+    const MAC_KEY *key1 = keydata1;
+    const MAC_KEY *key2 = keydata2;
+    int ok = 1;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if ((key1->priv_key == NULL && key2->priv_key != NULL)
+                || (key1->priv_key != NULL && key2->priv_key == NULL)
+                || key1->priv_key_len != key2->priv_key_len
+                || (key1->cipher.cipher == NULL && key2->cipher.cipher != NULL)
+                || (key1->cipher.cipher != NULL && key2->cipher.cipher == NULL))
+            ok = 0;
+        else
+            ok = ok && (key1->priv_key == NULL /* implies key2->privkey == NULL */
+                        || CRYPTO_memcmp(key1->priv_key, key2->priv_key,
+                                         key1->priv_key_len) == 0);
+        if (key1->cipher.cipher != NULL)
+            ok = ok && EVP_CIPHER_is_a(key1->cipher.cipher,
+                                       EVP_CIPHER_name(key2->cipher.cipher));
+    }
+    return ok;
+}
+
+static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+            return 0;
+        }
+        OPENSSL_secure_clear_free(key->priv_key, key->priv_key_len);
+        key->priv_key = OPENSSL_secure_malloc(p->data_size);
+        if (key->priv_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(key->priv_key, p->data, p->data_size);
+        key->priv_key_len = p->data_size;
+    }
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+            return 0;
+        }
+        OPENSSL_free(key->properties);
+        key->properties = OPENSSL_strdup(p->data);
+        if (key->properties == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+
+    if (key->cmac && !ossl_prov_cipher_load_from_params(&key->cipher, params,
+                                                        key->libctx)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    if (key->priv_key != NULL)
+        return 1;
+
+    return 0;
+}
+
+static int mac_import(void *keydata, int selection, const OSSL_PARAM params[])
+{
+    MAC_KEY *key = keydata;
+
+    if (key == NULL)
+        return 0;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) == 0)
+        return 0;
+
+    return mac_key_fromdata(key, params);
+}
+
+static int key_to_params(MAC_KEY *key, OSSL_PARAM_BLD *tmpl,
+                         OSSL_PARAM params[])
+{
+    if (key == NULL)
+        return 0;
+
+    if (key->priv_key != NULL
+        && !ossl_param_build_set_octet_string(tmpl, params,
+                                              OSSL_PKEY_PARAM_PRIV_KEY,
+                                              key->priv_key, key->priv_key_len))
+        return 0;
+
+    if (key->cipher.cipher != NULL
+        && !ossl_param_build_set_utf8_string(tmpl, params,
+                                             OSSL_PKEY_PARAM_CIPHER,
+                                             EVP_CIPHER_name(key->cipher.cipher)))
+        return 0;
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
+    if (key->cipher.engine != NULL
+        && !ossl_param_build_set_utf8_string(tmpl, params,
+                                             OSSL_PKEY_PARAM_ENGINE,
+                                             ENGINE_get_id(key->cipher.engine)))
+        return 0;
+#endif
+
+    return 1;
+}
+
+static int mac_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
+                      void *cbarg)
+{
+    MAC_KEY *key = keydata;
+    OSSL_PARAM_BLD *tmpl;
+    OSSL_PARAM *params = NULL;
+    int ret = 0;
+
+    if (key == NULL)
+        return 0;
+
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL)
+        return 0;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+         && !key_to_params(key, tmpl, NULL))
+        goto err;
+
+    params = OSSL_PARAM_BLD_to_param(tmpl);
+    if (params == NULL)
+        goto err;
+
+    ret = param_cb(params, cbarg);
+    OSSL_PARAM_BLD_free_params(params);
+err:
+    OSSL_PARAM_BLD_free(tmpl);
+    return ret;
+}
+
+static const OSSL_PARAM mac_key_types[] = {
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *mac_imexport_types(int selection)
+{
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        return mac_key_types;
+    return NULL;
+}
+
+static const OSSL_PARAM cmac_key_types[] = {
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_imexport_types(int selection)
+{
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        return cmac_key_types;
+    return NULL;
+}
+
+static int mac_get_params(void *key, OSSL_PARAM params[])
+{
+    return key_to_params(key, NULL, params);
+}
+
+static const OSSL_PARAM *mac_gettable_params(void *provctx)
+{
+    static const OSSL_PARAM gettable_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return gettable_params;
+}
+
+static const OSSL_PARAM *cmac_gettable_params(void *provctx)
+{
+    static const OSSL_PARAM gettable_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return gettable_params;
+}
+
+static int mac_set_params(void *keydata, const OSSL_PARAM params[])
+{
+    MAC_KEY *key = keydata;
+    const OSSL_PARAM *p;
+
+    if (key == NULL)
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+    if (p != NULL)
+        return mac_key_fromdata(key, params);
+
+    return 1;
+}
+
+static const OSSL_PARAM *mac_settable_params(void *provctx)
+{
+    static const OSSL_PARAM settable_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return settable_params;
+}
+
+static void *mac_gen_init(void *provctx, int selection)
+{
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+    struct mac_gen_ctx *gctx = NULL;
+
+    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
+        gctx->libctx = libctx;
+        gctx->selection = selection;
+    }
+    return gctx;
+}
+
+static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+    struct mac_gen_ctx *gctx = genctx;
+    const OSSL_PARAM *p;
+
+    if (gctx == NULL)
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+            return 0;
+        }
+        gctx->priv_key = OPENSSL_secure_malloc(p->data_size);
+        if (gctx->priv_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(gctx->priv_key, p->data, p->data_size);
+        gctx->priv_key_len = p->data_size;
+    }
+
+    return 1;
+}
+
+static int cmac_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+    struct mac_gen_ctx *gctx = genctx;
+
+    if (!mac_gen_set_params(genctx, params))
+        return 0;
+
+    if (!ossl_prov_cipher_load_from_params(&gctx->cipher, params,
+                                           gctx->libctx)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    return 1;
+}
+
+static const OSSL_PARAM *mac_gen_settable_params(void *provctx)
+{
+    static OSSL_PARAM settable[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return settable;
+}
+
+static const OSSL_PARAM *cmac_gen_settable_params(void *provctx)
+{
+    static OSSL_PARAM settable[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return settable;
+}
+
+static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg)
+{
+    struct mac_gen_ctx *gctx = genctx;
+    MAC_KEY *key;
+
+    if (gctx == NULL)
+        return NULL;
+
+    if ((key = mac_key_new(gctx->libctx, 0)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    /* If we're doing parameter generation then we just return a blank key */
+    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
+        return key;
+
+    if (gctx->priv_key == NULL) {
+        ERR_raise(ERR_LIB_PROV, EVP_R_INVALID_KEY);
+        mac_key_free(key);
+        return NULL;
+    }
+
+    /*
+     * This is horrible but required for backwards compatibility. We don't
+     * actually do real key generation at all. We simply copy the key that was
+     * previously set in the gctx. Hopefully at some point in the future all
+     * of this can be removed and we will only support the EVP_KDF APIs.
+     */
+    if (!ossl_prov_cipher_copy(&key->cipher, &gctx->cipher)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
+        return NULL;
+    }
+    ossl_prov_cipher_reset(&gctx->cipher);
+    key->priv_key = gctx->priv_key;
+    key->priv_key_len = gctx->priv_key_len;
+    gctx->priv_key_len = 0;
+    gctx->priv_key = NULL;
+
+    return key;
+}
+
+static void mac_gen_cleanup(void *genctx)
+{
+    struct mac_gen_ctx *gctx = genctx;
+
+    OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len);
+    ossl_prov_cipher_reset(&gctx->cipher);
+    OPENSSL_free(gctx);
+}
+
+const OSSL_DISPATCH mac_legacy_keymgmt_functions[] = {
+    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new },
+    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free },
+    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params },
+    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))mac_gettable_params },
+    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params },
+    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params },
+    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has },
+    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match },
+    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import },
+    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))mac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export },
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))mac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init },
+    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))mac_gen_set_params },
+    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
+        (void (*)(void))mac_gen_settable_params },
+    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },
+    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
+    { 0, NULL }
+};
+
+const OSSL_DISPATCH cmac_legacy_keymgmt_functions[] = {
+    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new_cmac },
+    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free },
+    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params },
+    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))cmac_gettable_params },
+    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params },
+    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params },
+    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has },
+    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match },
+    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import },
+    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))cmac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export },
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))cmac_imexport_types },
+    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init },
+    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))cmac_gen_set_params },
+    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
+        (void (*)(void))cmac_gen_settable_params },
+    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },
+    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
+    { 0, NULL }
+};
diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info
index 0e7765ae24..5a813083b2 100644
--- a/providers/implementations/signature/build.info
+++ b/providers/implementations/signature/build.info
@@ -20,3 +20,6 @@ SOURCE[../../libnonfips.a]=rsa.c
 DEPEND[rsa.o]=../../common/include/prov/der_rsa.h
 DEPEND[dsa.o]=../../common/include/prov/der_dsa.h
 DEPEND[ecdsa.o]=../../common/include/prov/der_ec.h
+
+SOURCE[../../libfips.a]=mac_legacy.c
+SOURCE[../../libnonfips.a]=mac_legacy.c
diff --git a/providers/implementations/signature/mac_legacy.c b/providers/implementations/signature/mac_legacy.c
new file mode 100644
index 0000000000..2b8edcad9d
--- /dev/null
+++ b/providers/implementations/signature/mac_legacy.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* We need to use some engine deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/macsignature.h"
+
+static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx;
+static OSSL_FUNC_signature_digest_sign_init_fn mac_digest_sign_init;
+static OSSL_FUNC_signature_digest_sign_update_fn mac_digest_sign_update;
+static OSSL_FUNC_signature_digest_sign_final_fn mac_digest_sign_final;
+static OSSL_FUNC_signature_freectx_fn mac_freectx;
+static OSSL_FUNC_signature_dupctx_fn mac_dupctx;
+
+typedef struct {
+    OPENSSL_CTX *libctx;
+    char *propq;
+    MAC_KEY *key;
+    EVP_MAC_CTX *macctx;
+} PROV_MAC_CTX;
+
+static void *mac_newctx(void *provctx, const char *propq, const char *macname)
+{
+    PROV_MAC_CTX *pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX));
+    EVP_MAC *mac = NULL;
+
+    if (pmacctx == NULL)
+        return NULL;
+
+    pmacctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+    if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq);
+    if (mac == NULL)
+        goto err;
+
+    pmacctx->macctx = EVP_MAC_CTX_new(mac);
+    if (pmacctx->macctx == NULL)
+        goto err;
+
+    EVP_MAC_free(mac);
+
+    return pmacctx;
+
+ err:
+    OPENSSL_free(pmacctx);
+    EVP_MAC_free(mac);
+    return NULL;
+}
+
+#define MAC_NEWCTX(funcname, macname) \
+    static void *mac_##funcname##_newctx(void *provctx, const char *propq) \
+    { \
+        return mac_newctx(provctx, propq, macname); \
+    }
+
+MAC_NEWCTX(hmac, "HMAC")
+MAC_NEWCTX(siphash, "SIPHASH")
+MAC_NEWCTX(poly1305, "POLY1305")
+MAC_NEWCTX(cmac, "CMAC")
+
+static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey)
+{
+    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
+    const char *ciphername = NULL, *engine = NULL;
+
+    if (pmacctx == NULL || vkey == NULL || !mac_key_up_ref(vkey))
+        return 0;
+
+    mac_key_free(pmacctx->key);
+    pmacctx->key = vkey;
+
+    if (pmacctx->key->cipher.cipher != NULL)
+        ciphername = (char *)EVP_CIPHER_name(pmacctx->key->cipher.cipher);
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
+    if (pmacctx->key->cipher.engine != NULL)
+        engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine);
+#endif
+
+    if (!ossl_prov_set_macctx(pmacctx->macctx, NULL,
+                              (char *)ciphername,
+                              (char *)mdname,
+                              (char *)engine,
+                              pmacctx->key->properties,
+                              pmacctx->key->priv_key,
+                              pmacctx->key->priv_key_len))
+        return 0;
+
+    if (!EVP_MAC_init(pmacctx->macctx))
+        return 0;
+
+    return 1;
+}
+
+int mac_digest_sign_update(void *vpmacctx, const unsigned char *data,
+                           size_t datalen)
+{
+    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
+
+    if (pmacctx == NULL || pmacctx->macctx == NULL)
+        return 0;
+
+    return EVP_MAC_update(pmacctx->macctx, data, datalen);
+}
+
+int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen,
+                          size_t macsize)
+{
+    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
+
+    if (pmacctx == NULL || pmacctx->macctx == NULL)
+        return 0;
+
+    return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize);
+}
+
+static void mac_freectx(void *vpmacctx)
+{
+    PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
+
+    OPENSSL_free(ctx->propq);
+    EVP_MAC_CTX_free(ctx->macctx);
+    mac_key_free(ctx->key);
+    OPENSSL_free(ctx);
+}
+
+static void *mac_dupctx(void *vpmacctx)
+{
+    PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx;
+    PROV_MAC_CTX *dstctx;
+
+    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+    if (dstctx == NULL)
+        return NULL;
+
+    *dstctx = *srcctx;
+    dstctx->key = NULL;
+    dstctx->macctx = NULL;
+
+    if (srcctx->key != NULL && !mac_key_up_ref(srcctx->key))
+        goto err;
+    dstctx->key = srcctx->key;
+
+    if (srcctx->macctx != NULL) {
+        dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx);
+        if (dstctx->macctx == NULL)
+            goto err;
+    }
+
+    return dstctx;
+ err:
+    mac_freectx(dstctx);
+    return NULL;
+}
+
+#define MAC_SIGNATURE_FUNCTIONS(funcname) \
+    const OSSL_DISPATCH mac_legacy_##funcname##_signature_functions[] = { \
+        { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \
+        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
+        (void (*)(void))mac_digest_sign_init }, \
+        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \
+        (void (*)(void))mac_digest_sign_update }, \
+        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, \
+        (void (*)(void))mac_digest_sign_final }, \
+        { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx }, \
+        { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx }, \
+        { 0, NULL } \
+    };
+
+MAC_SIGNATURE_FUNCTIONS(hmac)
+MAC_SIGNATURE_FUNCTIONS(siphash)
+MAC_SIGNATURE_FUNCTIONS(poly1305)
+MAC_SIGNATURE_FUNCTIONS(cmac)
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 1a8e3cf829..c842e20fbf 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -1598,8 +1598,10 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
         goto err;
     }
 
-    mackey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finishedkey,
-                                          hashsize);
+    mackey = EVP_PKEY_new_raw_private_key_with_libctx(s->ctx->libctx, "HMAC",
+                                                      s->ctx->propq,
+                                                      finishedkey,
+                                                      hashsize);
     if (mackey == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER,
                  ERR_R_INTERNAL_ERROR);
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 3eeafef828..b5cd34b646 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -771,10 +771,11 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
 
     /* Verify the HMAC of the cookie */
     hctx = EVP_MD_CTX_create();
-    pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
-                                        s->session_ctx->ext.cookie_hmac_key,
-                                        sizeof(s->session_ctx->ext
-                                               .cookie_hmac_key));
+    pkey = EVP_PKEY_new_raw_private_key_with_libctx(s->ctx->libctx, "HMAC",
+                                                    s->ctx->propq,
+                                                    s->session_ctx->ext.cookie_hmac_key,
+                                                    sizeof(s->session_ctx->ext
+                                                           .cookie_hmac_key));
     if (hctx == NULL || pkey == NULL) {
         EVP_MD_CTX_free(hctx);
         EVP_PKEY_free(pkey);
@@ -1863,10 +1864,11 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context,
 
     /* HMAC the cookie */
     hctx = EVP_MD_CTX_create();
-    pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
-                                        s->session_ctx->ext.cookie_hmac_key,
-                                        sizeof(s->session_ctx->ext
-                                               .cookie_hmac_key));
+    pkey = EVP_PKEY_new_raw_private_key_with_libctx(s->ctx->libctx, "HMAC",
+                                                    s->ctx->propq,
+                                                    s->session_ctx->ext.cookie_hmac_key,
+                                                    sizeof(s->session_ctx->ext
+                                                           .cookie_hmac_key));
     if (hctx == NULL || pkey == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE,
                  ERR_R_MALLOC_FAILURE);
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8285e5cd27..2e46187024 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -376,9 +376,21 @@ int tls1_change_cipher_state(SSL *s, int which)
     memcpy(mac_secret, ms, i);
 
     if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
-        /* TODO(size_t): Convert this function */
-        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
-                                               (int)*mac_secret_size);
+        if (mac_type == EVP_PKEY_HMAC) {
+            mac_key = EVP_PKEY_new_raw_private_key_with_libctx(s->ctx->libctx,
+                                                               "HMAC",
+                                                               s->ctx->propq,
+                                                               mac_secret,
+                                                               *mac_secret_size);
+        } else {
+            /*
+             * If its not HMAC then the only other types of MAC we support are
+             * the GOST MACs, so we need to use the old style way of creating
+             * a MAC key.
+             */
+            mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
+                                           (int)*mac_secret_size);
+        }
         if (mac_key == NULL
             || EVP_DigestSignInit_with_libctx(mac_ctx, NULL, EVP_MD_name(m),
                                               s->ctx->libctx, s->ctx->propq,
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 4da65a2400..bae6f2339b 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -27,6 +27,7 @@
 #include <openssl/params.h>
 #include <openssl/dsa.h>
 #include <openssl/dh.h>
+#include <openssl/aes.h>
 #include "testutil.h"
 #include "internal/nelem.h"
 #include "internal/sizes.h"
@@ -1254,23 +1255,69 @@ static int test_EVP_PKEY_check(int i)
 }
 
 #ifndef OPENSSL_NO_CMAC
+static int get_cmac_val(EVP_PKEY *pkey, unsigned char *mac)
+{
+    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
+    const char msg[] = "Hello World";
+    size_t maclen;
+    int ret = 1;
+
+    if (!TEST_ptr(mdctx)
+            || !TEST_true(EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey))
+            || !TEST_true(EVP_DigestSignUpdate(mdctx, msg, sizeof(msg)))
+            || !TEST_true(EVP_DigestSignFinal(mdctx, mac, &maclen))
+            || !TEST_size_t_eq(maclen, AES_BLOCK_SIZE))
+        ret = 0;
+
+    EVP_MD_CTX_free(mdctx);
+
+    return ret;
+}
 static int test_CMAC_keygen(void)
 {
+    static unsigned char key[] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+        0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+    };
     /*
      * This is a legacy method for CMACs, but should still work.
      * This verifies that it works without an ENGINE.
      */
     EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_CMAC, NULL);
     int ret = 0;
+    EVP_PKEY *pkey = NULL;
+    unsigned char mac[AES_BLOCK_SIZE], mac2[AES_BLOCK_SIZE];
+
+    /* Test a CMAC key created using the "generated" method */
+    if (!TEST_int_gt(EVP_PKEY_keygen_init(kctx), 0)
+            || !TEST_int_gt(EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,
+                                            EVP_PKEY_CTRL_CIPHER,
+                                            0, (void *)EVP_aes_256_ecb()), 0)
+            || !TEST_int_gt(EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,
+                                            EVP_PKEY_CTRL_SET_MAC_KEY,
+                                            sizeof(key), (void *)key), 0)
+            || !TEST_int_gt(EVP_PKEY_keygen(kctx, &pkey), 0)
+            || !TEST_ptr(pkey)
+            || !TEST_true(get_cmac_val(pkey, mac)))
+        goto done;
+
+    EVP_PKEY_free(pkey);
 
-    if (!TEST_true(EVP_PKEY_keygen_init(kctx) > 0)
-        && !TEST_true(EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,
-                                        EVP_PKEY_CTRL_CIPHER,
-                                        0, (void *)EVP_aes_256_ecb()) > 0))
+    /*
+     * Test a CMAC key using the direct method, and compare with the mac
+     * created above.
+     */
+    pkey = EVP_PKEY_new_CMAC_key(NULL, key, sizeof(key), EVP_aes_256_ecb());
+    if (!TEST_ptr(pkey)
+            || !TEST_true(get_cmac_val(pkey, mac2))
+            || !TEST_mem_eq(mac, sizeof(mac), mac2, sizeof(mac2)))
         goto done;
+
     ret = 1;
 
  done:
+    EVP_PKEY_free(pkey);
     EVP_PKEY_CTX_free(kctx);
     return ret;
 }
@@ -1760,15 +1807,17 @@ static int test_pkey_ctx_fail_without_provider(int tst)
     if (!TEST_ptr(nullprov))
         goto err;
 
-    pctx = EVP_PKEY_CTX_new_from_name(tmpctx, tst == 0 ? "RSA" : "HMAC", "");
+    pctx = EVP_PKEY_CTX_new_from_name(tmpctx, tst == 0 ? "RSA" : "SM2", "");
 
     /* RSA is not available via any provider so we expect this to fail */
     if (tst == 0 && !TEST_ptr_null(pctx))
         goto err;
 
     /*
-     * HMAC is always available because it is implemented via legacy codepaths
+     * SM2 is always available because it is implemented via legacy codepaths
      * and not in a provider at all. We expect this to pass.
+     * TODO(3.0): This can be removed once there are no more algorithms
+     * available via legacy codepaths
      */
     if (tst == 1 && !TEST_ptr(pctx))
         goto err;
diff --git a/test/evp_test.c b/test/evp_test.c
index adcfea0038..238bbaf3d5 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -1161,8 +1161,10 @@ static int mac_test_run_pkey(EVP_TEST *t)
             t->err = "MAC_KEY_CREATE_ERROR";
             goto err;
         }
-        key = EVP_PKEY_new_CMAC_key(NULL, expected->key, expected->key_len,
-                                    cipher);
+        key = EVP_PKEY_new_CMAC_key_with_libctx(expected->key,
+                                                expected->key_len,
+                                                EVP_CIPHER_name(cipher),
+                                                libctx, NULL);
     } else {
         key = EVP_PKEY_new_raw_private_key_with_libctx(libctx,
                                                        OBJ_nid2sn(expected->type),
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 99790a1b74..96f834500d 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5284,3 +5284,5 @@ OSSL_STORE_LOADER_names_do_all          ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_get_utf8_string_ptr          ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_get_octet_string_ptr         ?	3_0_0	EXIST::FUNCTION:
 OSSL_DECODER_CTX_set_passphrase_cb      ?	3_0_0	EXIST::FUNCTION:
+EVP_PKEY_CTX_set_mac_key                ?	3_0_0	EXIST::FUNCTION:
+EVP_PKEY_new_CMAC_key_with_libctx       ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list