[openssl] master update

Richard Levitte levitte at openssl.org
Thu Aug 15 20:12:51 UTC 2019


The branch master has been updated
       via  467b8e56753e53ed2b9a9f1ad35970a5ceb837d9 (commit)
       via  d1cafb083d0cb84b2081dd5ca4ba6bed05b8c6ac (commit)
       via  7dd0f299387bac79c304dc7cb8056cd4684fb91f (commit)
       via  bb31895d87a57e7bb1d3f0939edc53d674094ea4 (commit)
       via  810a1d0320fa1706c722d1cfcae398bfb8219837 (commit)
       via  f73eb733eeeb50df0068d01efaa3221cadb07389 (commit)
       via  25446a66b69a28c85d178e4454d2caed75d75293 (commit)
       via  776796e81895fc66994a90bb62da4c7f50d34368 (commit)
       via  d747fb2ec5ee964e8367e7baec8d499d4832def6 (commit)
       via  6a4f9cd113e7fc0734eb4b62e596488e71961040 (commit)
       via  ae0b6b92038b3f6e3a0e2f354cd900f96bce4d8b (commit)
       via  4657693d9e53ea45cbb903969370ddf9d331dafd (commit)
       via  e23cda000ef2e54e83da61e102ce6d22ed56721a (commit)
       via  5183ebdcf5aa49e7a6b065a54575aa5748964736 (commit)
       via  d33313be449741aeb68f40831afece4107467bdf (commit)
       via  2e5db6ad84ecd80954a66e250eae7d96e4565ea1 (commit)
       via  55a0a117e7d911752bc7e3e00a67f7a5ad168159 (commit)
       via  e74bd29053a543ab4908ae8545b46f2e38c98bab (commit)
      from  3ded2288a45d2cc3a27a1b08d29499cbcec52c0e (commit)


- Log -----------------------------------------------------------------
commit 467b8e56753e53ed2b9a9f1ad35970a5ceb837d9
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Aug 2 10:40:30 2019 +0200

    Re-implement 'openssl list -mac-algorithms'
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit d1cafb083d0cb84b2081dd5ca4ba6bed05b8c6ac
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jun 4 18:17:49 2019 +0200

    Implement EVP_MAC_do_all_ex()
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 7dd0f299387bac79c304dc7cb8056cd4684fb91f
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jun 4 18:14:38 2019 +0200

    Add EVP_MAC_provider()
    
    For information processing.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit bb31895d87a57e7bb1d3f0939edc53d674094ea4
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Aug 13 10:20:05 2019 +0200

    Rename the hash implementations KMAC{128,256} to KECCAK_KMAC{128,256}
    
    This avoids getting them confused with the MAC implementations.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 810a1d0320fa1706c722d1cfcae398bfb8219837
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Aug 12 13:52:53 2019 +0200

    OSSL_PARAM_construct_from_text(): handle non-hex octet string input
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit f73eb733eeeb50df0068d01efaa3221cadb07389
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Aug 12 13:14:51 2019 +0200

    Adjust some provider reason codes
    
    BLAKE2 MACs came with a set of new reason codes.  Those talking about
    lengths are consistently called PROV_R_INVALID_FOO_LENGTH, for any
    name FOO.  The cipher messages were briefer.  In the interest of
    having more humanly readable messages, we adjust the reasons used by
    the ciphers (that's just IV length and key length).
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 25446a66b69a28c85d178e4454d2caed75d75293
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jul 30 22:52:07 2019 +0200

    Adapt the MAC tests, and tests for other things that use EVP_MAC
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 776796e81895fc66994a90bb62da4c7f50d34368
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jun 4 18:00:04 2019 +0200

    Adapt diverse code to provider based MACs.
    
    CRMF, SSKDF, TLS1_PRF and SIV are affected by this.
    
    This also forces the need to check MAC names, which leads to storing
    the names in the created methods, which affects all EVP APIs, not just
    EVP_MAC.  We will want that kind of information anyway (for example
    for 'openssl list')...  Consequently, EVP_MAC_name() is re-implemented.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit d747fb2ec5ee964e8367e7baec8d499d4832def6
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Jun 2 17:11:53 2019 +0200

    Adapt apps/mac.c to use provider based MACs
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 6a4f9cd113e7fc0734eb4b62e596488e71961040
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Jun 2 09:35:51 2019 +0200

    Remove init of MACs from EVP
    
    Now that all our MACs have moved to the default provider, we let it
    take over completely
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit ae0b6b92038b3f6e3a0e2f354cd900f96bce4d8b
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Jun 2 09:33:28 2019 +0200

    Move Poly1305 to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 4657693d9e53ea45cbb903969370ddf9d331dafd
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Jun 2 08:51:58 2019 +0200

    Move SipHash to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit e23cda000ef2e54e83da61e102ce6d22ed56721a
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Jun 2 08:46:35 2019 +0200

    Move KMAC to providers
    
    Instead of using evp_keccak_kmac128() and evp_keccak_kmac256(), we refer
    to the hash implementation by name, and fetch it, which should get us the
    implementation from providers/common/digests/sha3_prov.c.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 5183ebdcf5aa49e7a6b065a54575aa5748964736
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Jun 1 18:36:10 2019 +0200

    Move HMAC to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit d33313be449741aeb68f40831afece4107467bdf
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Jun 1 14:05:45 2019 +0200

    Move GMAC to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 2e5db6ad84ecd80954a66e250eae7d96e4565ea1
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Jun 1 11:18:15 2019 +0200

    Move CMAC to providers
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit 55a0a117e7d911752bc7e3e00a67f7a5ad168159
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue May 7 12:40:25 2019 +0200

    Move BLAKE2 MACs to the providers
    
    This also moves the remaining parts of BLAKE2 digests to the default
    provider, and removes the legacy EVP implementation.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

commit e74bd29053a543ab4908ae8545b46f2e38c98bab
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue May 7 12:39:58 2019 +0200

    Prepare EVP_MAC infrastructure for moving all MACs to providers
    
    Quite a few adaptations are needed, most prominently the added code
    to allow provider based MACs.
    
    As part of this, all the old information functions are gone, except
    for EVP_MAC_name().  Some of them will reappear later, for example
    EVP_MAC_do_all() in some form.
    
    MACs by EVP_PKEY was particularly difficult to deal with, as they
    need to allocate and deallocate EVP_MAC_CTXs "under the hood", and
    thereby implicitly fetch the corresponding EVP_MAC.  This means that
    EVP_MACs can't be constant in a EVP_MAC_CTX, as their reference count
    may need to be incremented and decremented as part of the allocation
    or deallocation of the EVP_MAC_CTX.  It may be that other provider
    based EVP operation types may need to be handled in a similar manner.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8877)

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

Summary of changes:
 apps/list.c                                        |  55 +++-
 apps/mac.c                                         |  65 ++--
 crypto/blake2/blake2b_mac.c                        | 196 ------------
 crypto/blake2/blake2s_mac.c                        | 196 ------------
 crypto/blake2/build.info                           |   3 +-
 crypto/build.info                                  |   4 +-
 crypto/cmac/build.info                             |   6 +-
 crypto/cmac/cm_ameth.c                             |   3 +
 crypto/cmac/cm_meth.c                              | 172 ----------
 crypto/crmf/crmf_pbm.c                             |  30 +-
 crypto/err/openssl.txt                             |  17 +-
 crypto/evp/build.info                              |   2 +-
 crypto/evp/c_allm.c                                |  32 --
 crypto/evp/evp_locl.h                              |   2 +-
 crypto/evp/mac_lib.c                               | 162 ++++------
 crypto/evp/mac_meth.c                              | 209 ++++++++++++
 crypto/evp/names.c                                 |  73 -----
 crypto/evp/p_lib.c                                 |  32 +-
 crypto/evp/pkey_mac.c                              | 186 ++++++++---
 crypto/gmac/build.info                             |   2 -
 crypto/gmac/gmac.c                                 | 195 ------------
 crypto/hmac/build.info                             |   2 +-
 crypto/hmac/hm_meth.c                              | 192 -----------
 crypto/include/internal/evp_int.h                  |  40 ++-
 crypto/include/internal/modes_int.h                |   1 +
 crypto/init.c                                      |  29 --
 crypto/kdf/sskdf.c                                 | 106 +++---
 crypto/kdf/tls1_prf.c                              |  32 +-
 crypto/kmac/build.info                             |   3 -
 crypto/modes/siv128.c                              |  32 +-
 crypto/params_from_text.c                          |   2 +
 crypto/poly1305/build.info                         |   2 +-
 crypto/poly1305/poly1305_meth.c                    | 147 ---------
 crypto/provider_core.c                             |   7 +-
 crypto/siphash/build.info                          |   1 -
 crypto/siphash/siphash_meth.c                      | 146 ---------
 doc/internal/man3/ossl_provider_new.pod            |   9 +
 doc/man3/EVP_MAC.pod                               | 322 ++++++++++---------
 doc/man7/provider-mac.pod                          | 255 +++++++++++++++
 include/internal/provider.h                        |   1 +
 include/openssl/core_names.h                       |  20 ++
 include/openssl/core_numbers.h                     |  36 +++
 include/openssl/crypto.h                           |   4 +-
 include/openssl/evp.h                              |  65 ++--
 providers/common/build.info                        |   2 +-
 providers/common/ciphers/aes.c                     |   4 +-
 providers/common/ciphers/gcm.c                     |   8 +-
 providers/common/include/internal/provider_algs.h  |  11 +
 .../common/include/internal/providercommonerr.h    |   8 +-
 providers/common/macs/build.info                   |  11 +
 providers/common/macs/cmac_prov.c                  | 265 +++++++++++++++
 providers/common/macs/gmac_prov.c                  | 291 +++++++++++++++++
 providers/common/macs/hmac_prov.c                  | 284 +++++++++++++++++
 .../kmac.c => providers/common/macs/kmac_prov.c    | 354 +++++++++++++--------
 providers/common/provider_err.c                    |  11 +-
 providers/default/build.info                       |   3 +-
 providers/default/defltprov.c                      |  32 +-
 .../default/include}/internal/blake2.h             |   0
 providers/default/macs/blake2_mac_impl.c           | 230 +++++++++++++
 providers/default/macs/blake2b_mac.c               |  36 +++
 providers/default/macs/blake2s_mac.c               |  36 +++
 providers/default/macs/build.info                  |   4 +
 providers/default/macs/poly1305_prov.c             | 169 ++++++++++
 providers/default/macs/siphash_prov.c              | 188 +++++++++++
 providers/fips/fipsprov.c                          |  19 +-
 ssl/ssl_init.c                                     |   3 +-
 test/evp_kdf_test.c                                |   8 +-
 test/evp_test.c                                    | 159 +++++----
 test/recipes/30-test_evp_data/evpmac.txt           |   8 +-
 util/libcrypto.num                                 |  32 +-
 70 files changed, 3152 insertions(+), 2120 deletions(-)
 delete mode 100644 crypto/blake2/blake2b_mac.c
 delete mode 100644 crypto/blake2/blake2s_mac.c
 delete mode 100644 crypto/cmac/cm_meth.c
 delete mode 100644 crypto/evp/c_allm.c
 create mode 100644 crypto/evp/mac_meth.c
 delete mode 100644 crypto/gmac/build.info
 delete mode 100644 crypto/gmac/gmac.c
 delete mode 100644 crypto/hmac/hm_meth.c
 delete mode 100644 crypto/kmac/build.info
 delete mode 100644 crypto/poly1305/poly1305_meth.c
 delete mode 100644 crypto/siphash/siphash_meth.c
 create mode 100644 doc/man7/provider-mac.pod
 create mode 100644 providers/common/macs/build.info
 create mode 100644 providers/common/macs/cmac_prov.c
 create mode 100644 providers/common/macs/gmac_prov.c
 create mode 100644 providers/common/macs/hmac_prov.c
 rename crypto/kmac/kmac.c => providers/common/macs/kmac_prov.c (50%)
 rename {include => providers/default/include}/internal/blake2.h (100%)
 create mode 100644 providers/default/macs/blake2_mac_impl.c
 create mode 100644 providers/default/macs/blake2b_mac.c
 create mode 100644 providers/default/macs/blake2s_mac.c
 create mode 100644 providers/default/macs/build.info
 create mode 100644 providers/default/macs/poly1305_prov.c
 create mode 100644 providers/default/macs/siphash_prov.c

diff --git a/apps/list.c b/apps/list.c
index c22a2c6267..0d93f5498f 100644
--- a/apps/list.c
+++ b/apps/list.c
@@ -229,18 +229,51 @@ static void list_digests(void)
     sk_EVP_MD_pop_free(digests, EVP_MD_meth_free);
 }
 
-static void list_mac_fn(const EVP_MAC *m,
-                        const char *from, const char *to, void *arg)
+DEFINE_STACK_OF(EVP_MAC)
+static int mac_cmp(const EVP_MAC * const *a, const EVP_MAC * const *b)
 {
-    if (m != NULL) {
-        BIO_printf(arg, "%s\n", EVP_MAC_name(m));
-    } else {
-        if (from == NULL)
-            from = "<undefined>";
-        if (to == NULL)
-            to = "<undefined>";
-        BIO_printf(arg, "%s => %s\n", from, to);
+    int ret = strcasecmp(EVP_MAC_name(*a), EVP_MAC_name(*b));
+
+    if (ret == 0)
+        ret = strcmp(OSSL_PROVIDER_name(EVP_MAC_provider(*a)),
+                     OSSL_PROVIDER_name(EVP_MAC_provider(*b)));
+
+    return ret;
+}
+
+static void collect_macs(EVP_MAC *mac, void *stack)
+{
+    STACK_OF(EVP_MAC) *mac_stack = stack;
+
+    sk_EVP_MAC_push(mac_stack, mac);
+    EVP_MAC_up_ref(mac);
+}
+
+static void list_macs(void)
+{
+    STACK_OF(EVP_MAC) *macs = sk_EVP_MAC_new(mac_cmp);
+    int i;
+
+    BIO_printf(bio_out, "Provided MACs:\n");
+    EVP_MAC_do_all_ex(NULL, collect_macs, macs);
+    sk_EVP_MAC_sort(macs);
+    for (i = 0; i < sk_EVP_MAC_num(macs); i++) {
+        const EVP_MAC *m = sk_EVP_MAC_value(macs, i);
+
+        BIO_printf(bio_out, "  %s", EVP_MAC_name(m));
+        BIO_printf(bio_out, " @ %s\n",
+                   OSSL_PROVIDER_name(EVP_MAC_provider(m)));
+
+        if (verbose) {
+            print_param_types("retrievable algorithm parameters",
+                              EVP_MAC_gettable_params(m));
+            print_param_types("retrievable operation parameters",
+                              EVP_MAC_CTX_gettable_params(m));
+            print_param_types("settable operation parameters",
+                              EVP_MAC_CTX_settable_params(m));
+        }
     }
+    sk_EVP_MAC_pop_free(macs, EVP_MAC_free);
 }
 
 static void list_missing_help(void)
@@ -705,7 +738,7 @@ opthelp:
     if (todo.digest_algorithms)
         list_digests();
     if (todo.mac_algorithms)
-        EVP_MAC_do_all_sorted(list_mac_fn, bio_out);
+        list_macs();
     if (todo.cipher_commands)
         list_type(FT_cipher, one);
     if (todo.cipher_algorithms)
diff --git a/apps/mac.c b/apps/mac.c
index 946c3c7aa1..8220356e42 100644
--- a/apps/mac.c
+++ b/apps/mac.c
@@ -14,6 +14,7 @@
 #include <openssl/bio.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#include <openssl/params.h>
 
 #undef BUFSIZE
 #define BUFSIZE 1024*8
@@ -37,29 +38,11 @@ const OPTIONS mac_options[] = {
     {NULL}
 };
 
-static int mac_ctrl_string(EVP_MAC_CTX *ctx, const char *value)
-{
-    int rv;
-    char *stmp, *vtmp = NULL;
-
-    stmp = OPENSSL_strdup(value);
-    if (stmp == NULL)
-        return -1;
-    vtmp = strchr(stmp, ':');
-    if (vtmp != NULL) {
-        *vtmp = 0;
-        vtmp++;
-    }
-    rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp);
-    OPENSSL_free(stmp);
-    return rv;
-}
-
 int mac_main(int argc, char **argv)
 {
     int ret = 1;
     char *prog;
-    const EVP_MAC *mac = NULL;
+    EVP_MAC *mac = NULL;
     OPTION_CHOICE o;
     EVP_MAC_CTX *ctx = NULL;
     STACK_OF(OPENSSL_STRING) *opts = NULL;
@@ -109,7 +92,7 @@ opthelp:
         goto opthelp;
     }
 
-    mac = EVP_get_macbyname(argv[0]);
+    mac = EVP_MAC_fetch(NULL, argv[0], NULL);
     if (mac == NULL) {
         BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]);
         goto opthelp;
@@ -120,14 +103,45 @@ opthelp:
         goto err;
 
     if (opts != NULL) {
-        for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
-            char *opt = sk_OPENSSL_STRING_value(opts, i);
-            if (mac_ctrl_string(ctx, opt) <= 0) {
+        OSSL_PARAM *params =
+            OPENSSL_zalloc(sizeof(OSSL_PARAM)
+                           * (sk_OPENSSL_STRING_num(opts) + 1));
+        const OSSL_PARAM *paramdefs = EVP_MAC_CTX_settable_params(mac);
+        size_t params_n;
+        int ok = 1;
+
+        for (params_n = 0; params_n < (size_t)sk_OPENSSL_STRING_num(opts);
+             params_n++) {
+            char *opt = sk_OPENSSL_STRING_value(opts, (int)params_n);
+            char *stmp, *vtmp = NULL;
+
+            if ((stmp = OPENSSL_strdup(opt)) == NULL
+                || (vtmp = strchr(stmp, ':')) == NULL
+                || (*vtmp++ = 0) /* Always zero */
+                || !OSSL_PARAM_allocate_from_text(&params[params_n], paramdefs,
+                                                  stmp, vtmp, strlen(vtmp))) {
                 BIO_printf(bio_err, "MAC parameter error '%s'\n", opt);
                 ERR_print_errors(bio_err);
+                ok = 0;
+            }
+            OPENSSL_free(stmp);
+            if (!ok)
+                break;
+        }
+        if (ok) {
+            params[params_n] = OSSL_PARAM_construct_end();
+            if (!EVP_MAC_CTX_set_params(ctx, params)) {
+                BIO_printf(bio_err, "MAC parameter error\n");
+                ERR_print_errors(bio_err);
                 goto err;
             }
         }
+        for (; params_n-- > 0;) {
+            OPENSSL_free(params[params_n].data);
+        }
+        OPENSSL_free(params);
+        if (!ok)
+            goto err;
     }
 
     /* Use text mode for stdin */
@@ -161,7 +175,7 @@ opthelp:
         }
     }
 
-    if (!EVP_MAC_final(ctx, NULL, &len)) {
+    if (!EVP_MAC_final(ctx, NULL, &len, 0)) {
         BIO_printf(bio_err, "EVP_MAC_final failed\n");
         goto err;
     }
@@ -170,7 +184,7 @@ opthelp:
         goto err;
     }
 
-    if (!EVP_MAC_final(ctx, buf, &len)) {
+    if (!EVP_MAC_final(ctx, buf, &len, BUFSIZE)) {
         BIO_printf(bio_err, "EVP_MAC_final failed\n");
         goto err;
     }
@@ -195,5 +209,6 @@ err:
     BIO_free(in);
     BIO_free(out);
     EVP_MAC_CTX_free(ctx);
+    EVP_MAC_free(mac);
     return ret;
 }
diff --git a/crypto/blake2/blake2b_mac.c b/crypto/blake2/blake2b_mac.c
deleted file mode 100644
index f6025b1f70..0000000000
--- a/crypto/blake2/blake2b_mac.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 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
- */
-
-#ifndef OPENSSL_NO_BLAKE2
-
-# include <openssl/evp.h>
-# include "internal/blake2.h"
-# include "internal/cryptlib.h"
-# include "internal/evp_int.h"
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    BLAKE2B_CTX ctx;
-    BLAKE2B_PARAM params;
-    unsigned char key[BLAKE2B_KEYBYTES];
-};
-
-static EVP_MAC_IMPL *blake2b_mac_new(void)
-{
-    EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx));
-    if (macctx != NULL) {
-        blake2b_param_init(&macctx->params);
-        /* ctx initialization is deferred to blake2b_init() */
-    }
-    return macctx;
-}
-
-static void blake2b_mac_free(EVP_MAC_IMPL *macctx)
-{
-    if (macctx != NULL) {
-        OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
-        OPENSSL_free(macctx);
-    }
-}
-
-static EVP_MAC_IMPL *blake2b_mac_dup(const EVP_MAC_IMPL *src)
-{
-    EVP_MAC_IMPL *dst;
-
-    dst = OPENSSL_zalloc(sizeof(*dst));
-    if (dst == NULL)
-        return NULL;
-
-    *dst = *src;
-    return dst;
-}
-
-static int blake2b_mac_init(EVP_MAC_IMPL *macctx)
-{
-    /* Check key has been set */
-    if (macctx->params.key_length == 0) {
-        EVPerr(EVP_F_BLAKE2B_MAC_INIT, EVP_R_NO_KEY_SET);
-        return 0;
-    }
-
-    return blake2b_init_key(&macctx->ctx, &macctx->params, macctx->key);
-}
-
-static int blake2b_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data,
-                              size_t datalen)
-{
-    return blake2b_update(&macctx->ctx, data, datalen);
-}
-
-static int blake2b_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out)
-{
-    return blake2b_final(out, &macctx->ctx);
-}
-
-/*
- * ALL Ctrl functions should be set before init().
- */
-static int blake2b_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args)
-{
-    const unsigned char *p;
-    size_t len;
-    size_t size;
-
-    switch (cmd) {
-        case EVP_MAC_CTRL_SET_SIZE:
-            size = va_arg(args, size_t);
-            if (size < 1 || size > BLAKE2B_OUTBYTES) {
-                EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
-                return 0;
-            }
-            blake2b_param_set_digest_length(&macctx->params, (uint8_t)size);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_KEY:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len < 1 || len > BLAKE2B_KEYBYTES) {
-                EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
-                return 0;
-            }
-            blake2b_param_set_key_length(&macctx->params, (uint8_t)len);
-            memcpy(macctx->key, p, len);
-            memset(macctx->key + len, 0, BLAKE2B_KEYBYTES - len);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_CUSTOM:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len > BLAKE2B_PERSONALBYTES) {
-                EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH);
-                return 0;
-            }
-            blake2b_param_set_personal(&macctx->params, p, len);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_SALT:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len > BLAKE2B_SALTBYTES) {
-                EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH);
-                return 0;
-            }
-            blake2b_param_set_salt(&macctx->params, p, len);
-            return 1;
-
-        default:
-            return -2;
-    }
-}
-
-static int blake2b_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = blake2b_mac_ctrl(macctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int blake2b_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen)
-{
-    return blake2b_mac_ctrl_int(macctx, cmd, buf, buflen);
-}
-
-static int blake2b_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type,
-                                const char *value)
-{
-    if (value == NULL)
-        return 0;
-
-    if (strcmp(type, "outlen") == 0)
-        return blake2b_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value));
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "custom") == 0)
-        return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    if (strcmp(type, "hexcustom") == 0)
-        return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    if (strcmp(type, "salt") == 0)
-        return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
-                            value);
-    if (strcmp(type, "hexsalt") == 0)
-        return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
-                            value);
-    return -2;
-}
-
-static size_t blake2b_mac_size(EVP_MAC_IMPL *macctx)
-{
-    return macctx->params.digest_length;
-}
-
-const EVP_MAC blake2b_mac_meth = {
-    EVP_MAC_BLAKE2B,
-    blake2b_mac_new,
-    blake2b_mac_dup,
-    blake2b_mac_free,
-    blake2b_mac_size,
-    blake2b_mac_init,
-    blake2b_mac_update,
-    blake2b_mac_final,
-    blake2b_mac_ctrl,
-    blake2b_mac_ctrl_str
-};
-
-#endif
diff --git a/crypto/blake2/blake2s_mac.c b/crypto/blake2/blake2s_mac.c
deleted file mode 100644
index 9ce8db1360..0000000000
--- a/crypto/blake2/blake2s_mac.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 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
- */
-
-#ifndef OPENSSL_NO_BLAKE2
-
-# include <openssl/evp.h>
-# include "internal/blake2.h"
-# include "internal/cryptlib.h"
-# include "internal/evp_int.h"
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    BLAKE2S_CTX ctx;
-    BLAKE2S_PARAM params;
-    unsigned char key[BLAKE2S_KEYBYTES];
-};
-
-static EVP_MAC_IMPL *blake2s_mac_new(void)
-{
-    EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx));
-    if (macctx != NULL) {
-        blake2s_param_init(&macctx->params);
-        /* ctx initialization is deferred to BLAKE2s_Init() */
-    }
-    return macctx;
-}
-
-static void blake2s_mac_free(EVP_MAC_IMPL *macctx)
-{
-    if (macctx != NULL) {
-        OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
-        OPENSSL_free(macctx);
-    }
-}
-
-static EVP_MAC_IMPL *blake2s_mac_dup(const EVP_MAC_IMPL *src)
-{
-    EVP_MAC_IMPL *dst;
-
-    dst = OPENSSL_malloc(sizeof(*dst));
-    if (dst == NULL)
-        return NULL;
-
-    *dst = *src;
-    return dst;
-}
-
-static int blake2s_mac_init(EVP_MAC_IMPL *macctx)
-{
-    /* Check key has been set */
-    if (macctx->params.key_length == 0) {
-        EVPerr(EVP_F_BLAKE2S_MAC_INIT, EVP_R_NO_KEY_SET);
-        return 0;
-    }
-
-    return blake2s_init_key(&macctx->ctx, &macctx->params, macctx->key);
-}
-
-static int blake2s_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data,
-                              size_t datalen)
-{
-    return blake2s_update(&macctx->ctx, data, datalen);
-}
-
-static int blake2s_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out)
-{
-    return blake2s_final(out, &macctx->ctx);
-}
-
-/*
- * ALL Ctrl functions should be set before init().
- */
-static int blake2s_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args)
-{
-    const unsigned char *p;
-    size_t len;
-    size_t size;
-
-    switch (cmd) {
-        case EVP_MAC_CTRL_SET_SIZE:
-            size = va_arg(args, size_t);
-            if (size < 1 || size > BLAKE2S_OUTBYTES) {
-                EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
-                return 0;
-            }
-            blake2s_param_set_digest_length(&macctx->params, (uint8_t)size);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_KEY:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len < 1 || len > BLAKE2S_KEYBYTES) {
-                EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
-                return 0;
-            }
-            blake2s_param_set_key_length(&macctx->params, (uint8_t)len);
-            memcpy(macctx->key, p, len);
-            memset(macctx->key + len, 0, BLAKE2S_KEYBYTES - len);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_CUSTOM:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len > BLAKE2S_PERSONALBYTES) {
-                EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH);
-                return 0;
-            }
-            blake2s_param_set_personal(&macctx->params, p, len);
-            return 1;
-
-        case EVP_MAC_CTRL_SET_SALT:
-            p = va_arg(args, const unsigned char *);
-            len = va_arg(args, size_t);
-            if (len > BLAKE2S_SALTBYTES) {
-                EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH);
-                return 0;
-            }
-            blake2s_param_set_salt(&macctx->params, p, len);
-            return 1;
-
-        default:
-            return -2;
-    }
-}
-
-static int blake2s_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = blake2s_mac_ctrl(macctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int blake2s_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen)
-{
-    return blake2s_mac_ctrl_int(macctx, cmd, buf, buflen);
-}
-
-static int blake2s_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type,
-                                const char *value)
-{
-    if (value == NULL)
-        return 0;
-
-    if (strcmp(type, "outlen") == 0)
-        return blake2s_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value));
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "custom") == 0)
-        return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    if (strcmp(type, "hexcustom") == 0)
-        return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    if (strcmp(type, "salt") == 0)
-        return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
-                            value);
-    if (strcmp(type, "hexsalt") == 0)
-        return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
-                            value);
-    return -2;
-}
-
-static size_t blake2s_mac_size(EVP_MAC_IMPL *macctx)
-{
-    return macctx->params.digest_length;
-}
-
-const EVP_MAC blake2s_mac_meth = {
-    EVP_MAC_BLAKE2S,
-    blake2s_mac_new,
-    blake2s_mac_dup,
-    blake2s_mac_free,
-    blake2s_mac_size,
-    blake2s_mac_init,
-    blake2s_mac_update,
-    blake2s_mac_final,
-    blake2s_mac_ctrl,
-    blake2s_mac_ctrl_str
-};
-
-#endif
diff --git a/crypto/blake2/build.info b/crypto/blake2/build.info
index f02bf9a6fa..8b5ebcec9c 100644
--- a/crypto/blake2/build.info
+++ b/crypto/blake2/build.info
@@ -1,3 +1,2 @@
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
-        blake2b_mac.c blake2s_mac.c m_blake2b.c m_blake2s.c
+SOURCE[../../libcrypto]=m_blake2b.c m_blake2s.c
diff --git a/crypto/build.info b/crypto/build.info
index 2130382034..96e265ff40 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -2,10 +2,10 @@
 # there for further explanations.
 SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \
         txt_db pkcs7 pkcs12 ui kdf store property \
-        md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
+        md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 blake2 \
         siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
         seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
-        err comp ocsp cms ts srp cmac ct async kmac ess crmf cmp
+        err comp ocsp cms ts srp cmac ct async ess crmf cmp
 
 LIBS=../libcrypto
 
diff --git a/crypto/cmac/build.info b/crypto/cmac/build.info
index c460598e20..f6c8bfabbc 100644
--- a/crypto/cmac/build.info
+++ b/crypto/cmac/build.info
@@ -1,2 +1,6 @@
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_meth.c
+
+$COMMON=cmac.c
+
+SOURCE[../../libcrypto]=$COMMON cm_ameth.c
+SOURCE[../../providers/fips]=$COMMON
diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c
index ed513b113f..b1ee0d3d2f 100644
--- a/crypto/cmac/cm_ameth.c
+++ b/crypto/cmac/cm_ameth.c
@@ -25,7 +25,10 @@ static int cmac_size(const EVP_PKEY *pkey)
 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 = {
diff --git a/crypto/cmac/cm_meth.c b/crypto/cmac/cm_meth.c
deleted file mode 100644
index 07acf050b3..0000000000
--- a/crypto/cmac/cm_meth.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright 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/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/evp.h>
-#include <openssl/cmac.h>
-#include "internal/evp_int.h"
-
-/* local CMAC pkey structure */
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    /* tmpcipher and tmpengine are set to NULL after a CMAC_Init call */
-    const EVP_CIPHER *tmpcipher; /* cached CMAC cipher */
-    const ENGINE *tmpengine;     /* cached CMAC cipher engine */
-    CMAC_CTX *ctx;
-};
-
-static EVP_MAC_IMPL *cmac_new(void)
-{
-    EVP_MAC_IMPL *cctx;
-
-    if ((cctx = OPENSSL_zalloc(sizeof(*cctx))) == NULL
-        || (cctx->ctx = CMAC_CTX_new()) == NULL) {
-        OPENSSL_free(cctx);
-        cctx = NULL;
-    }
-
-    return cctx;
-}
-
-static void cmac_free(EVP_MAC_IMPL *cctx)
-{
-    if (cctx != NULL) {
-        CMAC_CTX_free(cctx->ctx);
-        OPENSSL_free(cctx);
-    }
-}
-
-static EVP_MAC_IMPL *cmac_dup(const EVP_MAC_IMPL *csrc)
-{
-    EVP_MAC_IMPL *cdst = cmac_new();
-
-    if (cdst == NULL)
-        return NULL;
-
-    if (!CMAC_CTX_copy(cdst->ctx, csrc->ctx)) {
-        cmac_free(cdst);
-        return NULL;
-    }
-
-    cdst->tmpengine = csrc->tmpengine;
-    cdst->tmpcipher = csrc->tmpcipher;
-
-    return cdst;
-}
-
-static size_t cmac_size(EVP_MAC_IMPL *cctx)
-{
-    return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(cctx->ctx));
-}
-
-static int cmac_init(EVP_MAC_IMPL *cctx)
-{
-    int rv = CMAC_Init(cctx->ctx, NULL, 0, cctx->tmpcipher,
-                       (ENGINE *)cctx->tmpengine);
-    cctx->tmpcipher = NULL;
-    cctx->tmpengine = NULL;
-
-    return rv;
-}
-
-static int cmac_update(EVP_MAC_IMPL *cctx, const unsigned char *data,
-                       size_t datalen)
-{
-    return CMAC_Update(cctx->ctx, data, datalen);
-}
-
-static int cmac_final(EVP_MAC_IMPL *cctx, unsigned char *out)
-{
-    size_t hlen;
-
-    return CMAC_Final(cctx->ctx, out, &hlen);
-}
-
-static int cmac_ctrl(EVP_MAC_IMPL *cctx, int cmd, va_list args)
-{
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_KEY:
-        {
-            const unsigned char *key = va_arg(args, const unsigned char *);
-            size_t keylen = va_arg(args, size_t);
-            int rv = CMAC_Init(cctx->ctx, key, keylen, cctx->tmpcipher,
-                               (ENGINE *)cctx->tmpengine);
-
-            cctx->tmpcipher = NULL;
-            cctx->tmpengine = NULL;
-
-            return rv;
-        }
-        break;
-    case EVP_MAC_CTRL_SET_CIPHER:
-        cctx->tmpcipher = va_arg(args, const EVP_CIPHER *);
-        break;
-    case EVP_MAC_CTRL_SET_ENGINE:
-        cctx->tmpengine = va_arg(args, const ENGINE *);
-        break;
-    default:
-        return -2;
-    }
-    return 1;
-}
-
-static int cmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = cmac_ctrl(hctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int cmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
-{
-    return cmac_ctrl_int(hctx, cmd, buf, buflen);
-}
-
-static int cmac_ctrl_str(EVP_MAC_IMPL *cctx, const char *type,
-                         const char *value)
-{
-    if (!value)
-        return 0;
-    if (strcmp(type, "cipher") == 0) {
-        const EVP_CIPHER *c = EVP_get_cipherbyname(value);
-
-        if (c == NULL)
-            return 0;
-        return cmac_ctrl_int(cctx, EVP_MAC_CTRL_SET_CIPHER, c);
-    }
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    return -2;
-}
-
-const EVP_MAC cmac_meth = {
-    EVP_MAC_CMAC,
-    cmac_new,
-    cmac_dup,
-    cmac_free,
-    cmac_size,
-    cmac_init,
-    cmac_update,
-    cmac_final,
-    cmac_ctrl,
-    cmac_ctrl_str
-};
diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c
index 7b29166610..40c12dd32a 100644
--- a/crypto/crmf/crmf_pbm.c
+++ b/crypto/crmf/crmf_pbm.c
@@ -12,6 +12,8 @@
  */
 
 
+#include <string.h>
+
 #include <openssl/rand.h>
 #include <openssl/evp.h>
 
@@ -22,6 +24,8 @@
 #include <openssl/crmf.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
 
 /*-
  * creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4)
@@ -120,9 +124,10 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
 int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
                       const unsigned char *msg, size_t msglen,
                       const unsigned char *sec, size_t seclen,
-                      unsigned char **mac, size_t *maclen)
+                      unsigned char **out, size_t *outlen)
 {
     int mac_nid, hmac_md_nid = NID_undef;
+    const char *mdname = NULL;
     const EVP_MD *m = NULL;
     EVP_MD_CTX *ctx = NULL;
     unsigned char basekey[EVP_MAX_MD_SIZE];
@@ -130,9 +135,12 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
     int64_t iterations;
     unsigned char *mac_res = 0;
     int ok = 0;
+    EVP_MAC *mac = NULL;
     EVP_MAC_CTX *mctx = NULL;
+    OSSL_PARAM macparams[3] =
+        { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
 
-    if (mac == NULL || pbmp == NULL || pbmp->mac == NULL
+    if (out == NULL || pbmp == NULL || pbmp->mac == NULL
             || pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
         CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_NULL_ARGUMENT);
         goto err;
@@ -193,17 +201,22 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
     mac_nid = OBJ_obj2nid(pbmp->mac->algorithm);
 
     if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL)
-            || ((m = EVP_get_digestbynid(hmac_md_nid)) == NULL)) {
+        || ((mdname = OBJ_nid2sn(hmac_md_nid)) == NULL)) {
         CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
         goto err;
     }
 
-    if ((mctx = EVP_MAC_CTX_new(EVP_get_macbyname("HMAC"))) == NULL
-            || EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_MD, m) <= 0
-            || EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_KEY, basekey, bklen) <= 0
+    macparams[0] =
+        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                         (char *)mdname, strlen(mdname) + 1);
+    macparams[1] =
+        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen);
+    if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
+            || (mctx = EVP_MAC_CTX_new(mac)) == NULL
+            || !EVP_MAC_CTX_set_params(mctx, macparams)
             || !EVP_MAC_init(mctx)
             || !EVP_MAC_update(mctx, msg, msglen)
-            || !EVP_MAC_final(mctx, mac_res, maclen))
+            || !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
         goto err;
 
     ok = 1;
@@ -212,10 +225,11 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
     /* cleanup */
     OPENSSL_cleanse(basekey, bklen);
     EVP_MAC_CTX_free(mctx);
+    EVP_MAC_free(mac);
     EVP_MD_CTX_free(ctx);
 
     if (ok == 1) {
-        *mac = mac_res;
+        *out = mac_res;
         return 1;
     }
 
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 5d5981035c..988e6117ec 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -801,10 +801,6 @@ EVP_F_ARIA_GCM_CTRL:197:aria_gcm_ctrl
 EVP_F_ARIA_GCM_INIT_KEY:176:aria_gcm_init_key
 EVP_F_ARIA_INIT_KEY:185:aria_init_key
 EVP_F_B64_NEW:198:b64_new
-EVP_F_BLAKE2B_MAC_CTRL:220:blake2b_mac_ctrl
-EVP_F_BLAKE2B_MAC_INIT:221:blake2b_mac_init
-EVP_F_BLAKE2S_MAC_CTRL:222:blake2s_mac_ctrl
-EVP_F_BLAKE2S_MAC_INIT:223:blake2s_mac_init
 EVP_F_CAMELLIA_INIT_KEY:159:camellia_init_key
 EVP_F_CHACHA20_POLY1305_CTRL:182:chacha20_poly1305_ctrl
 EVP_F_CMLL_T4_INIT_KEY:179:cmll_t4_init_key
@@ -1162,6 +1158,11 @@ PROV_F_AES_EINIT:109:aes_einit
 PROV_F_AES_INIT_KEY:110:aes_init_key
 PROV_F_AES_STREAM_UPDATE:111:aes_stream_update
 PROV_F_AES_T4_INIT_KEY:112:aes_t4_init_key
+PROV_F_BLAKE2_MAC_INIT:115:blake2_mac_init
+PROV_F_BLAKE2_MAC_SET_PARAMS:116:blake2_mac_set_params
+PROV_F_GMAC_SET_PARAMS:117:gmac_set_params
+PROV_F_KMAC_SET_PARAMS:118:kmac_set_params
+PROV_F_POLY1305_SET_PARAMS:119:poly1305_set_params
 PROV_F_PROV_AES_KEY_GENERIC_INIT:113:PROV_AES_KEY_generic_init
 PROV_F_TRAILINGDATA:114:trailingdata
 PROV_F_UNPADBLOCK:100:unpadblock
@@ -2710,9 +2711,13 @@ PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
 PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
 PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
 PROV_R_INVALID_AAD:108:invalid aad
-PROV_R_INVALID_IVLEN:109:invalid ivlen
-PROV_R_INVALID_KEYLEN:105:invalid keylen
+PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
+PROV_R_INVALID_IV_LENGTH:109:invalid iv length
+PROV_R_INVALID_KEY_LENGTH:105:invalid key length
+PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
 PROV_R_INVALID_TAG:110:invalid tag
+PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
+PROV_R_NO_KEY_SET:114:no key set
 PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
 PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length
 RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index c650c28882..2546f48d6c 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -16,7 +16,7 @@ SOURCE[../../libcrypto]=$COMMON\
         e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
         e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
         e_chacha20_poly1305.c \
-        mac_lib.c c_allm.c pkey_mac.c exchange.c
+        mac_lib.c mac_meth.c pkey_mac.c exchange.c
 SOURCE[../../providers/fips]=$COMMON
 
 INCLUDE[e_aes.o]=.. ../modes
diff --git a/crypto/evp/c_allm.c b/crypto/evp/c_allm.c
deleted file mode 100644
index f5442dfa6c..0000000000
--- a/crypto/evp/c_allm.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 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 <openssl/evp.h>
-#include "internal/evp_int.h"
-
-void openssl_add_all_macs_int(void)
-{
-#ifndef OPENSSL_NO_BLAKE2
-    EVP_add_mac(&blake2b_mac_meth);
-    EVP_add_mac(&blake2s_mac_meth);
-#endif
-#ifndef OPENSSL_NO_CMAC
-    EVP_add_mac(&cmac_meth);
-#endif
-    EVP_add_mac(&gmac_meth);
-    EVP_add_mac(&hmac_meth);
-    EVP_add_mac(&kmac128_meth);
-    EVP_add_mac(&kmac256_meth);
-#ifndef OPENSSL_NO_SIPHASH
-    EVP_add_mac(&siphash_meth);
-#endif
-#ifndef OPENSSL_NO_POLY1305
-    EVP_add_mac(&poly1305_meth);
-#endif
-}
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 59072e368b..3fd73212a4 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -56,7 +56,7 @@ struct evp_cipher_ctx_st {
 } /* EVP_CIPHER_CTX */ ;
 
 struct evp_mac_ctx_st {
-    const EVP_MAC *meth;         /* Method structure */
+    EVP_MAC *meth;               /* Method structure */
     void *data;                  /* Individual method data */
 } /* EVP_MAC_CTX */;
 
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index ee4a68f459..7b07b55e3d 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -11,26 +11,24 @@
 #include <stdarg.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#include <openssl/core.h>
+#include <openssl/core_names.h>
 #include <openssl/ossl_typ.h>
 #include "internal/nelem.h"
 #include "internal/evp_int.h"
+#include "internal/provider.h"
 #include "evp_locl.h"
 
-EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id)
-{
-    const EVP_MAC *mac = EVP_get_macbynid(id);
-
-    if (mac == NULL)
-        return NULL;
-    return EVP_MAC_CTX_new(mac);
-}
-
-EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
+EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac)
 {
     EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
 
-    if (ctx == NULL || (ctx->data = mac->new()) == NULL) {
+    if (ctx == NULL
+        || (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL
+        || !EVP_MAC_up_ref(mac)) {
         EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        if (ctx != NULL)
+            mac->freectx(ctx->data);
         OPENSSL_free(ctx);
         ctx = NULL;
     } else {
@@ -41,9 +39,11 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
 
 void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
 {
-    if (ctx != NULL && ctx->data != NULL) {
-        ctx->meth->free(ctx->data);
+    if (ctx != NULL) {
+        ctx->meth->freectx(ctx->data);
         ctx->data = NULL;
+        /* refcnt-- */
+        EVP_MAC_free(ctx->meth);
     }
     OPENSSL_free(ctx);
 }
@@ -62,8 +62,13 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
     }
 
     *dst = *src;
+    if (!EVP_MAC_up_ref(dst->meth)) {
+        EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(dst);
+        return NULL;
+    }
 
-    dst->data = src->meth->dup(src->data);
+    dst->data = src->meth->dupctx(src->data);
     if (dst->data == NULL) {
         EVP_MAC_CTX_free(dst);
         return NULL;
@@ -72,16 +77,31 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
     return dst;
 }
 
-const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
+EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
 {
     return ctx->meth;
 }
 
 size_t EVP_MAC_size(EVP_MAC_CTX *ctx)
 {
-    if (ctx->data != NULL)
-        return ctx->meth->size(ctx->data);
-    /* If the MAC hasn't been initialized yet, we return zero */
+    size_t sz = 0;
+
+    if (ctx->data != NULL) {
+        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+        params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN, &sz);
+        if (ctx->meth->ctx_get_params != NULL) {
+            if (ctx->meth->ctx_get_params(ctx->data, params))
+                return sz;
+        } else if (ctx->meth->get_params != NULL) {
+            if (ctx->meth->get_params(params))
+                return sz;
+        }
+    }
+    /*
+     * If the MAC hasn't been initialized yet, or there is no size to get,
+     * we return zero
+     */
     return 0;
 }
 
@@ -97,101 +117,43 @@ int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
     return ctx->meth->update(ctx->data, data, datalen);
 }
 
-int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen)
+int EVP_MAC_final(EVP_MAC_CTX *ctx,
+                  unsigned char *out, size_t *outl, size_t outsize)
 {
-    int l = ctx->meth->size(ctx->data);
+    int l = EVP_MAC_size(ctx);
 
     if (l < 0)
         return 0;
-    if (poutlen != NULL)
-        *poutlen = l;
+    if (outl != NULL)
+        *outl = l;
     if (out == NULL)
         return 1;
-    return ctx->meth->final(ctx->data, out);
-}
-
-int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...)
-{
-    int ok = -1;
-    va_list args;
-
-    va_start(args, cmd);
-    ok = EVP_MAC_vctrl(ctx, cmd, args);
-    va_end(args);
-
-    if (ok == -2)
-        EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
-
-    return ok;
-}
-
-int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args)
-{
-    int ok = 1;
-
-    if (ctx == NULL || ctx->meth == NULL)
-        return -2;
-
-    switch (cmd) {
-#if 0
-    case ...:
-        /* code */
-        ok = 1;
-        break;
-#endif
-    default:
-        if (ctx->meth->ctrl != NULL)
-            ok = ctx->meth->ctrl(ctx->data, cmd, args);
-        else
-            ok = -2;
-        break;
-    }
-
-    return ok;
-}
-
-int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value)
-{
-    int ok = 1;
-
-    if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) {
-        EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
-        return -2;
-    }
-
-    ok = ctx->meth->ctrl_str(ctx->data, type, value);
-
-    if (ok == -2)
-        EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
-    return ok;
+    return ctx->meth->final(ctx->data, out, outl, outsize);
 }
 
-int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value)
+/*
+ * The {get,set}_params functions return 1 if there is no corresponding
+ * function in the implementation.  This is the same as if there was one,
+ * but it didn't recognise any of the given params, i.e. nothing in the
+ * bag of parameters was useful.
+ */
+int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[])
 {
-    size_t len;
-
-    len = strlen(value);
-    if (len > INT_MAX)
-        return -1;
-    return EVP_MAC_ctrl(ctx, cmd, value, len);
+    if (mac->get_params != NULL)
+        return mac->get_params(params);
+    return 1;
 }
 
-int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex)
+int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[])
 {
-    unsigned char *bin;
-    long binlen;
-    int rv = -1;
-
-    bin = OPENSSL_hexstr2buf(hex, &binlen);
-    if (bin == NULL)
-        return 0;
-    if (binlen <= INT_MAX)
-        rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen);
-    OPENSSL_free(bin);
-    return rv;
+    if (ctx->meth->ctx_get_params != NULL)
+        return ctx->meth->ctx_get_params(ctx->data, params);
+    return 1;
 }
 
-int EVP_MAC_nid(const EVP_MAC *mac)
+int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[])
 {
-    return mac->type;
+    if (ctx->meth->ctx_set_params != NULL)
+        return ctx->meth->ctx_set_params(ctx->data, params);
+    return 1;
 }
diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c
new file mode 100644
index 0000000000..e5eed33774
--- /dev/null
+++ b/crypto/evp/mac_meth.c
@@ -0,0 +1,209 @@
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/core.h>
+#include <openssl/core_numbers.h>
+#include "internal/evp_int.h"
+#include "internal/provider.h"
+#include "evp_locl.h"
+
+static int evp_mac_up_ref(void *vmac)
+{
+    EVP_MAC *mac = vmac;
+    int ref = 0;
+
+    CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock);
+    return 1;
+}
+
+static void evp_mac_free(void *vmac)
+{
+    EVP_MAC *mac = vmac;
+    int ref = 0;
+
+    if (mac == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock);
+    if (ref > 0)
+        return;
+    ossl_provider_free(mac->prov);
+    OPENSSL_free(mac->name);
+    CRYPTO_THREAD_lock_free(mac->lock);
+    OPENSSL_free(mac);
+}
+
+static void *evp_mac_new(void)
+{
+    EVP_MAC *mac = NULL;
+
+    if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
+        || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) {
+        evp_mac_free(mac);
+        return NULL;
+    }
+
+    mac->refcnt = 1;
+
+    return mac;
+}
+
+static void *evp_mac_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
+                                   OSSL_PROVIDER *prov)
+{
+    EVP_MAC *mac = NULL;
+    int fnmaccnt = 0, fnctxcnt = 0;
+
+    if ((mac = evp_mac_new()) == NULL
+        || (mac->name = OPENSSL_strdup(name)) == NULL) {
+        EVP_MAC_free(mac);
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (; fns->function_id != 0; fns++) {
+        switch (fns->function_id) {
+        case OSSL_FUNC_MAC_NEWCTX:
+            if (mac->newctx != NULL)
+                break;
+            mac->newctx = OSSL_get_OP_mac_newctx(fns);
+            fnctxcnt++;
+            break;
+        case OSSL_FUNC_MAC_DUPCTX:
+            if (mac->dupctx != NULL)
+                break;
+            mac->dupctx = OSSL_get_OP_mac_dupctx(fns);
+            break;
+        case OSSL_FUNC_MAC_FREECTX:
+            if (mac->freectx != NULL)
+                break;
+            mac->freectx = OSSL_get_OP_mac_freectx(fns);
+            fnctxcnt++;
+            break;
+        case OSSL_FUNC_MAC_INIT:
+            if (mac->init != NULL)
+                break;
+            mac->init = OSSL_get_OP_mac_init(fns);
+            fnmaccnt++;
+            break;
+        case OSSL_FUNC_MAC_UPDATE:
+            if (mac->update != NULL)
+                break;
+            mac->update = OSSL_get_OP_mac_update(fns);
+            fnmaccnt++;
+            break;
+        case OSSL_FUNC_MAC_FINAL:
+            if (mac->final != NULL)
+                break;
+            mac->final = OSSL_get_OP_mac_final(fns);
+            fnmaccnt++;
+            break;
+        case OSSL_FUNC_MAC_GETTABLE_PARAMS:
+            if (mac->gettable_params != NULL)
+                break;
+            mac->gettable_params =
+                OSSL_get_OP_mac_gettable_params(fns);
+            break;
+        case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
+            if (mac->gettable_ctx_params != NULL)
+                break;
+            mac->gettable_ctx_params =
+                OSSL_get_OP_mac_gettable_ctx_params(fns);
+            break;
+        case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
+            if (mac->settable_ctx_params != NULL)
+                break;
+            mac->settable_ctx_params =
+                OSSL_get_OP_mac_settable_ctx_params(fns);
+            break;
+        case OSSL_FUNC_MAC_GET_PARAMS:
+            if (mac->get_params != NULL)
+                break;
+            mac->get_params = OSSL_get_OP_mac_get_params(fns);
+            break;
+        case OSSL_FUNC_MAC_CTX_GET_PARAMS:
+            if (mac->ctx_get_params != NULL)
+                break;
+            mac->ctx_get_params = OSSL_get_OP_mac_ctx_get_params(fns);
+            break;
+        case OSSL_FUNC_MAC_CTX_SET_PARAMS:
+            if (mac->ctx_set_params != NULL)
+                break;
+            mac->ctx_set_params = OSSL_get_OP_mac_ctx_set_params(fns);
+            break;
+        }
+    }
+    if (fnmaccnt != 3
+        || fnctxcnt != 2) {
+        /*
+         * In order to be a consistent set of functions we must have at least
+         * a complete set of "mac" functions, and a complete set of context
+         * management functions, as well as the size function.
+         */
+        evp_mac_free(mac);
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+        return NULL;
+    }
+    mac->prov = prov;
+    if (prov != NULL)
+        ossl_provider_up_ref(prov);
+
+    return mac;
+}
+
+EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
+                       const char *properties)
+{
+    return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
+                             evp_mac_from_dispatch, evp_mac_up_ref,
+                             evp_mac_free);
+}
+
+int EVP_MAC_up_ref(EVP_MAC *mac)
+{
+    return evp_mac_up_ref(mac);
+}
+
+void EVP_MAC_free(EVP_MAC *mac)
+{
+    evp_mac_free(mac);
+}
+
+const char *EVP_MAC_name(const EVP_MAC *mac)
+{
+    return mac->name;
+}
+
+const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac)
+{
+    return mac->prov;
+}
+
+const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac)
+{
+    if (mac->gettable_params == NULL)
+        return NULL;
+    return mac->gettable_params();
+}
+
+const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac)
+{
+    if (mac->gettable_ctx_params == NULL)
+        return NULL;
+    return mac->gettable_ctx_params();
+}
+
+const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac)
+{
+    if (mac->settable_ctx_params == NULL)
+        return NULL;
+    return mac->settable_ctx_params();
+}
+
+void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx,
+                       void (*fn)(EVP_MAC *mac, void *arg),
+                       void *arg)
+{
+    evp_generic_do_all(libctx, OSSL_OP_MAC,
+                       (void (*)(void *, void *))fn, arg,
+                       evp_mac_from_dispatch, evp_mac_free);
+}
diff --git a/crypto/evp/names.c b/crypto/evp/names.c
index 5237bcaf24..82db98a1f2 100644
--- a/crypto/evp/names.c
+++ b/crypto/evp/names.c
@@ -56,22 +56,6 @@ int EVP_add_digest(const EVP_MD *md)
     return r;
 }
 
-int EVP_add_mac(const EVP_MAC *m)
-{
-    int r;
-
-    if (m == NULL)
-        return 0;
-
-    r = OBJ_NAME_add(OBJ_nid2sn(m->type), OBJ_NAME_TYPE_MAC_METH,
-                     (const char *)m);
-    if (r == 0)
-        return 0;
-    r = OBJ_NAME_add(OBJ_nid2ln(m->type), OBJ_NAME_TYPE_MAC_METH,
-                     (const char *)m);
-    return r;
-}
-
 /* TODO(3.0) Is this needed after changing to providers? */
 int EVP_add_kdf(const EVP_KDF *k)
 {
@@ -111,17 +95,6 @@ const EVP_MD *EVP_get_digestbyname(const char *name)
     return cp;
 }
 
-const EVP_MAC *EVP_get_macbyname(const char *name)
-{
-    const EVP_MAC *mp;
-
-    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL))
-        return NULL;
-
-    mp = (const EVP_MAC *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MAC_METH);
-    return mp;
-}
-
 /* TODO(3.0) Is this API needed after implementing providers? */
 const EVP_KDF *EVP_get_kdfbyname(const char *name)
 {
@@ -136,7 +109,6 @@ const EVP_KDF *EVP_get_kdfbyname(const char *name)
 
 void evp_cleanup_int(void)
 {
-    OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
     OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH);
     OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
     OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
@@ -237,48 +209,3 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
     dc.arg = arg;
     OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
 }
-
-/* TODO(3.0) Are these do_all API's needed for MAC? */
-struct doall_mac {
-    void *arg;
-    void (*fn) (const EVP_MAC *ciph,
-                const char *from, const char *to, void *arg);
-};
-
-static void do_all_mac_fn(const OBJ_NAME *nm, void *arg)
-{
-    struct doall_mac *dc = arg;
-
-    if (nm->alias)
-        dc->fn(NULL, nm->name, nm->data, dc->arg);
-    else
-        dc->fn((const EVP_MAC *)nm->data, nm->name, NULL, dc->arg);
-}
-
-void EVP_MAC_do_all(void (*fn)
-                    (const EVP_MAC *ciph, const char *from, const char *to,
-                     void *x), void *arg)
-{
-    struct doall_mac dc;
-
-    /* Ignore errors */
-    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
-
-    dc.fn = fn;
-    dc.arg = arg;
-    OBJ_NAME_do_all(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
-}
-
-void EVP_MAC_do_all_sorted(void (*fn)
-                           (const EVP_MAC *ciph, const char *from,
-                            const char *to, void *x), void *arg)
-{
-    struct doall_mac dc;
-
-    /* Ignore errors */
-    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
-
-    dc.fn = fn;
-    dc.arg = arg;
-    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
-}
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 653693e1dc..90e13f4854 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -20,9 +20,12 @@
 #include <openssl/dh.h>
 #include <openssl/cmac.h>
 #include <openssl/engine.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
 
 #include "internal/asn1_int.h"
 #include "internal/evp_int.h"
+#include "internal/provider.h"
 
 static void EVP_PKEY_free_it(EVP_PKEY *x);
 
@@ -318,8 +321,16 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                 size_t len, const EVP_CIPHER *cipher)
 {
 #ifndef OPENSSL_NO_CMAC
+    const char *engine_name = e != NULL ? ENGINE_get_name(e) : NULL;
+    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_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC);
+    EVP_MAC *cmac = EVP_MAC_fetch(libctx, "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
@@ -328,9 +339,21 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
         goto err;
     }
 
-    if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0
-        || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0
-        || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) {
+    if (engine_name != NULL)
+        params[paramsn++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
+                                             (char *)engine_name,
+                                             strlen(engine_name) + 1);
+    params[paramsn++] =
+        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                         (char *)cipher_name,
+                                         strlen(cipher_name) + 1);
+    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);
         goto err;
     }
@@ -341,6 +364,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
  err:
     EVP_PKEY_free(ret);
     EVP_MAC_CTX_free(cmctx);
+    EVP_MAC_free(cmac);
     return NULL;
 #else
     EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c
index fafe3c96f2..07421183ea 100644
--- a/crypto/evp/pkey_mac.c
+++ b/crypto/evp/pkey_mac.c
@@ -7,8 +7,12 @@
  * https://www.openssl.org/source/license.html
  */
 
+#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 "internal/evp_int.h"
 #include "evp_locl.h"
 
@@ -40,18 +44,21 @@ typedef struct {
     } 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 = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
 
     if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
         EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
-    /* We're being smart and using the same base NIDs for PKEY and for MAC */
-    hctx->ctx = EVP_MAC_CTX_new_id(nid);
+    hctx->ctx = EVP_MAC_CTX_new(mac);
     if (hctx->ctx == NULL) {
         OPENSSL_free(hctx);
         return 0;
@@ -64,14 +71,13 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
         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 void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
-
 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     MAC_PKEY_CTX *sctx, *dctx;
@@ -93,6 +99,17 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
     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) {
@@ -117,9 +134,16 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 
 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
 {
-    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(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 = EVP_MAC_CTX_mac(hctx->ctx);
+
         switch (hctx->type) {
         case MAC_TYPE_RAW:
             OPENSSL_clear_free(hctx->raw_data.ktmp.data,
@@ -127,6 +151,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
             break;
         }
         EVP_MAC_CTX_free(hctx->ctx);
+        EVP_MAC_free(mac);
         OPENSSL_free(hctx);
         EVP_PKEY_CTX_set_data(ctx, NULL);
     }
@@ -156,6 +181,8 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 
             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;
@@ -194,25 +221,34 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
         && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
 
     if (set_key) {
-        if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
-            != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
+        if (strcmp(OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))),
+                   EVP_MAC_name(EVP_MAC_CTX_mac(hctx->ctx))) != 0)
             return 0;
         key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
         if (key == NULL)
             return 0;
     }
 
-    /* Some MACs don't support this control...  that's fine */
-    EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
-                 EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
-
     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
     EVP_MD_CTX_set_update_fn(mctx, int_update);
 
-    if (set_key)
-        rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
-                          key->length);
-    return rv > 0;
+    /* 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,
@@ -220,7 +256,7 @@ static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
 {
     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
 
-    return EVP_MAC_final(hctx->ctx, sig, siglen);
+    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)
@@ -235,14 +271,24 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             return -2;       /* The raw types don't support ciphers */
         case MAC_TYPE_MAC:
             {
-                int rv;
-
-                if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
-                                       ctx->engine)) <= 0
-                    || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
-                                          p2)) <= 0
-                    || !(rv = EVP_MAC_init(hctx->ctx)))
-                    return rv;
+                OSSL_PARAM params[3];
+                size_t params_n = 0;
+                char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
+                char *engineid = (char *)ENGINE_get_id(ctx->engine);
+
+                params[params_n++] =
+                    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
+                                                     engineid,
+                                                     strlen(engineid) + 1);
+                params[params_n++] =
+                    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                                     ciphname,
+                                                     strlen(ciphname) + 1);
+                params[params_n] = OSSL_PARAM_construct_end();
+
+                if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
+                    || !EVP_MAC_init(hctx->ctx))
+                    return 0;
             }
             break;
         default:
@@ -276,8 +322,40 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
         break;
 
     case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
-        return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
+        {
+            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_OUTLEN, &size);
+
+            if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
+                return 0;
 
+            params[0] =
+                OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN, &verify);
+
+            if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
+                return 0;
+
+            /*
+             * Since EVP_MAC_CTX_{get,set}_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:
@@ -287,8 +365,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
                 return 0;
             break;
         case MAC_TYPE_MAC:
-            if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
-                return 0;
+            {
+                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();
+
+                return EVP_MAC_CTX_set_params(hctx->ctx, params);
+            }
             break;
         default:
             /* This should be dead code */
@@ -303,17 +390,32 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             if (!EVP_MAC_init(hctx->ctx))
                 return 0;
             {
-                int rv;
                 ASN1_OCTET_STRING *key =
                     (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
-
-                if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
-                                       ctx->engine)) <= 0
-                    || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
-                                          hctx->raw_data.md)) <= 0
-                    || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
-                                          key->data, key->length)) <= 0)
-                    return rv;
+                OSSL_PARAM params[4];
+                size_t params_n = 0;
+                char *mdname =
+                    (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
+                char *engineid = ctx->engine == NULL
+                    ? NULL : (char *)ENGINE_get_id(ctx->engine);
+
+                if (engineid != NULL) {
+                    size_t engineid_l = strlen(engineid) + 1;
+                    params[params_n++] =
+                        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
+                                                         engineid,
+                                                         engineid_l);
+                }
+                params[params_n++] =
+                    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                                     mdname,
+                                                     strlen(mdname) + 1);
+                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:
@@ -335,8 +437,18 @@ 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 = EVP_MAC_CTX_mac(hctx->ctx);
+    OSSL_PARAM params[2];
+    int ok = 0;
 
-    return EVP_MAC_ctrl_str(hctx->ctx, type, value);
+    if (!OSSL_PARAM_allocate_from_text(&params[0],
+                                       EVP_MAC_CTX_settable_params(mac),
+                                       type, value, strlen(value) + 1))
+        return 0;
+    params[1] = OSSL_PARAM_construct_end();
+    ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
+    OPENSSL_free(params[0].data);
+    return ok;
 }
 
 const EVP_PKEY_METHOD cmac_pkey_meth = {
diff --git a/crypto/gmac/build.info b/crypto/gmac/build.info
deleted file mode 100644
index 6d9f22e235..0000000000
--- a/crypto/gmac/build.info
+++ /dev/null
@@ -1,2 +0,0 @@
-LIBS=../../libcrypto
-SOURCE[../../libcrypto]=gmac.c
diff --git a/crypto/gmac/gmac.c b/crypto/gmac/gmac.c
deleted file mode 100644
index 0e2eda38e9..0000000000
--- a/crypto/gmac/gmac.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright 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 <stdlib.h>
-#include <openssl/evp.h>
-#include "internal/cryptlib.h"
-#include "internal/evp_int.h"
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    EVP_CIPHER *cipher;      /* Cache GCM cipher */
-    EVP_CIPHER_CTX *ctx;    /* Cipher context */
-    ENGINE *engine;         /* Engine implementating the algorithm */
-};
-
-static void gmac_free(EVP_MAC_IMPL *gctx)
-{
-    if (gctx != NULL) {
-        EVP_CIPHER_CTX_free(gctx->ctx);
-        OPENSSL_free(gctx);
-    }
-}
-
-static EVP_MAC_IMPL *gmac_new(void)
-{
-    EVP_MAC_IMPL *gctx;
-
-    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL
-        || (gctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
-        gmac_free(gctx);
-        return NULL;
-    }
-    return gctx;
-}
-
-static EVP_MAC_IMPL *gmac_dup(const EVP_MAC_IMPL *gsrc)
-{
-    EVP_MAC_IMPL *gdst;
-
-    gdst = gmac_new();
-    if (gdst == NULL)
-        return NULL;
-
-    if (!EVP_CIPHER_CTX_copy(gdst->ctx, gsrc->ctx)) {
-        gmac_free(gdst);
-        return NULL;
-    }
-
-    gdst->cipher = gsrc->cipher;
-    gdst->engine = gsrc->engine;
-
-    return gdst;
-}
-
-static size_t gmac_size(EVP_MAC_IMPL *gctx)
-{
-    return EVP_GCM_TLS_TAG_LEN;
-}
-
-static int gmac_init(EVP_MAC_IMPL *gctx)
-{
-    return 1;
-}
-
-static int gmac_update(EVP_MAC_IMPL *gctx, const unsigned char *data,
-                       size_t datalen)
-{
-    EVP_CIPHER_CTX *ctx = gctx->ctx;
-    int outlen;
-
-    while (datalen > INT_MAX) {
-        if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
-            return 0;
-        data += INT_MAX;
-        datalen -= INT_MAX;
-    }
-    return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
-}
-
-static int gmac_final(EVP_MAC_IMPL *gctx, unsigned char *out)
-{
-    int hlen;
-
-    if (!EVP_EncryptFinal_ex(gctx->ctx, out, &hlen)
-        || !EVP_CIPHER_CTX_ctrl(gctx->ctx, EVP_CTRL_AEAD_GET_TAG,
-                                gmac_size(gctx), out))
-        return 0;
-    return 1;
-}
-
-static int gmac_ctrl(EVP_MAC_IMPL *gctx, int cmd, va_list args)
-{
-    const unsigned char *p;
-    size_t len;
-    EVP_CIPHER_CTX *ctx = gctx->ctx;
-    const EVP_CIPHER *cipher;
-    ENGINE *engine;
-
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_CIPHER:
-        cipher = va_arg(args, const EVP_CIPHER *);
-        if (cipher == NULL)
-            return 0;
-        if (EVP_CIPHER_mode(cipher) != EVP_CIPH_GCM_MODE) {
-            EVPerr(EVP_F_GMAC_CTRL, EVP_R_CIPHER_NOT_GCM_MODE);
-            return 0;
-        }
-        return EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL);
-
-    case EVP_MAC_CTRL_SET_KEY:
-        p = va_arg(args, const unsigned char *);
-        len = va_arg(args, size_t);
-        if (len != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
-            EVPerr(EVP_F_GMAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        return EVP_EncryptInit_ex(ctx, NULL, NULL, p, NULL);
-
-    case EVP_MAC_CTRL_SET_IV:
-        p = va_arg(args, const unsigned char *);
-        len = va_arg(args, size_t);
-        return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)
-               && EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p);
-
-    case EVP_MAC_CTRL_SET_ENGINE:
-        engine = va_arg(args, ENGINE *);
-        return EVP_EncryptInit_ex(ctx, NULL, engine, NULL, NULL);
-
-    default:
-        return -2;
-    }
-}
-
-static int gmac_ctrl_int(EVP_MAC_IMPL *gctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = gmac_ctrl(gctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int gmac_ctrl_str_cb(void *gctx, int cmd, void *buf, size_t buflen)
-{
-    return gmac_ctrl_int(gctx, cmd, buf, buflen);
-}
-
-static int gmac_ctrl_str(EVP_MAC_IMPL *gctx, const char *type,
-                         const char *value)
-{
-    if (!value)
-        return 0;
-    if (strcmp(type, "cipher") == 0) {
-        const EVP_CIPHER *c = EVP_get_cipherbyname(value);
-
-        if (c == NULL)
-            return 0;
-        return gmac_ctrl_int(gctx, EVP_MAC_CTRL_SET_CIPHER, c);
-    }
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "iv") == 0)
-        return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
-                            value);
-    if (strcmp(type, "hexiv") == 0)
-        return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
-                            value);
-    return -2;
-}
-
-const EVP_MAC gmac_meth = {
-    EVP_MAC_GMAC,
-    gmac_new,
-    gmac_dup,
-    gmac_free,
-    gmac_size,
-    gmac_init,
-    gmac_update,
-    gmac_final,
-    gmac_ctrl,
-    gmac_ctrl_str
-};
diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info
index b1c146182c..56ad67ef8f 100644
--- a/crypto/hmac/build.info
+++ b/crypto/hmac/build.info
@@ -1,6 +1,6 @@
 LIBS=../../libcrypto
 
-$COMMON=hmac.c hm_meth.c
+$COMMON=hmac.c
 
 SOURCE[../../libcrypto]=$COMMON hm_ameth.c
 SOURCE[../../providers/fips]=$COMMON
diff --git a/crypto/hmac/hm_meth.c b/crypto/hmac/hm_meth.c
deleted file mode 100644
index 19278ef67d..0000000000
--- a/crypto/hmac/hm_meth.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 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 <string.h>
-#include <openssl/err.h>
-#include <openssl/ossl_typ.h>
-#include <openssl/asn1.h>
-#include <openssl/hmac.h>
-#include "internal/evp_int.h"
-
-/* local HMAC context structure */
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    /* tmpmd and tmpengine are set to NULL after a CMAC_Init call */
-    const EVP_MD *tmpmd;         /* HMAC digest */
-    const ENGINE *tmpengine;     /* HMAC digest engine */
-    HMAC_CTX *ctx;               /* HMAC context */
-};
-
-static EVP_MAC_IMPL *hmac_new(void)
-{
-    EVP_MAC_IMPL *hctx;
-
-    if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL
-        || (hctx->ctx = HMAC_CTX_new()) == NULL) {
-        OPENSSL_free(hctx);
-        return NULL;
-    }
-
-    return hctx;
-}
-
-static void hmac_free(EVP_MAC_IMPL *hctx)
-{
-    if (hctx != NULL) {
-        HMAC_CTX_free(hctx->ctx);
-        OPENSSL_free(hctx);
-    }
-}
-
-static EVP_MAC_IMPL *hmac_dup(const EVP_MAC_IMPL *hsrc)
-{
-    EVP_MAC_IMPL *hdst;
-
-    hdst = hmac_new();
-    if (hdst == NULL)
-        return NULL;
-
-    if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx)) {
-        hmac_free(hdst);
-        return NULL;
-    }
-
-    hdst->tmpengine = hsrc->tmpengine;
-    hdst->tmpmd = hsrc->tmpmd;
-
-    return hdst;
-}
-
-static size_t hmac_size(EVP_MAC_IMPL *hctx)
-{
-    return HMAC_size(hctx->ctx);
-}
-
-static int hmac_init(EVP_MAC_IMPL *hctx)
-{
-    int rv = 1;
-
-    /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
-    if (hctx->tmpmd != NULL)
-        rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd,
-                          (ENGINE * )hctx->tmpengine);
-    hctx->tmpengine = NULL;
-    hctx->tmpmd = NULL;
-    return rv;
-}
-
-static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
-                       size_t datalen)
-{
-    return HMAC_Update(hctx->ctx, data, datalen);
-}
-
-static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
-{
-    unsigned int hlen;
-
-    return HMAC_Final(hctx->ctx, out, &hlen);
-}
-
-static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
-{
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_FLAGS:
-        {
-            unsigned long flags = va_arg(args, unsigned long);
-
-            HMAC_CTX_set_flags(hctx->ctx, flags);
-        }
-        break;
-    case EVP_MAC_CTRL_SET_KEY:
-        {
-            const unsigned char *key = va_arg(args, const unsigned char *);
-            size_t keylen = va_arg(args, size_t);
-            int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd,
-                                  (ENGINE *)hctx->tmpengine);
-
-            hctx->tmpengine = NULL;
-            hctx->tmpmd = NULL;
-            return rv;
-        }
-        break;
-    case EVP_MAC_CTRL_SET_MD:
-        hctx->tmpmd = va_arg(args, const EVP_MD *);
-        break;
-    case EVP_MAC_CTRL_SET_ENGINE:
-        hctx->tmpengine = va_arg(args, const ENGINE *);
-        break;
-    default:
-        return -2;
-
-    }
-    return 1;
-}
-
-static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = hmac_ctrl(hctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
-{
-    return hmac_ctrl_int(hctx, cmd, buf, buflen);
-}
-
-static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
-                         const char *value)
-{
-    if (!value)
-        return 0;
-#ifndef FIPS_MODE
-    /*
-     * We don't have EVP_get_digestbyname() in FIPS_MODE. That function returns
-     * an EVP_MD without an associated provider implementation (i.e. it is
-     * using "implicit fetch"). We could replace it with an "explicit" fetch
-     * using EVP_MD_fetch(), but we'd then be required to free the returned
-     * EVP_MD somewhere. Probably the complexity isn't worth it as we are
-     * unlikely to need this ctrl in FIPS_MODE anyway.
-     */
-    if (strcmp(type, "digest") == 0) {
-        const EVP_MD *d = EVP_get_digestbyname(value);
-
-        if (d == NULL)
-            return 0;
-        return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
-    }
-#endif
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    return -2;
-}
-
-const EVP_MAC hmac_meth = {
-    EVP_MAC_HMAC,
-    hmac_new,
-    hmac_dup,
-    hmac_free,
-    hmac_size,
-    hmac_init,
-    hmac_update,
-    hmac_final,
-    hmac_ctrl,
-    hmac_ctrl_str
-};
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index ce9b9b8f51..fb443b1484 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -121,28 +121,26 @@ extern const EVP_PKEY_METHOD siphash_pkey_meth;
 /* struct evp_mac_impl_st is defined by the implementation */
 typedef struct evp_mac_impl_st EVP_MAC_IMPL;
 struct evp_mac_st {
-    int type;
-    EVP_MAC_IMPL *(*new) (void);
-    EVP_MAC_IMPL *(*dup) (const EVP_MAC_IMPL *macsrc);
-    void (*free) (EVP_MAC_IMPL *macctx);
-    size_t (*size) (EVP_MAC_IMPL *macctx);
-    int (*init) (EVP_MAC_IMPL *macctx);
-    int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data,
-                   size_t datalen);
-    int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out);
-    int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args);
-    int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value);
-};
+    OSSL_PROVIDER *prov;
+    char *name;
 
-extern const EVP_MAC blake2b_mac_meth;
-extern const EVP_MAC blake2s_mac_meth;
-extern const EVP_MAC cmac_meth;
-extern const EVP_MAC gmac_meth;
-extern const EVP_MAC hmac_meth;
-extern const EVP_MAC kmac128_meth;
-extern const EVP_MAC kmac256_meth;
-extern const EVP_MAC siphash_meth;
-extern const EVP_MAC poly1305_meth;
+    CRYPTO_REF_COUNT refcnt;
+    CRYPTO_RWLOCK *lock;
+
+    OSSL_OP_mac_newctx_fn *newctx;
+    OSSL_OP_mac_dupctx_fn *dupctx;
+    OSSL_OP_mac_freectx_fn *freectx;
+    OSSL_OP_mac_size_fn *size;
+    OSSL_OP_mac_init_fn *init;
+    OSSL_OP_mac_update_fn *update;
+    OSSL_OP_mac_final_fn *final;
+    OSSL_OP_mac_gettable_params_fn *gettable_params;
+    OSSL_OP_mac_gettable_ctx_params_fn *gettable_ctx_params;
+    OSSL_OP_mac_settable_ctx_params_fn *settable_ctx_params;
+    OSSL_OP_mac_get_params_fn *get_params;
+    OSSL_OP_mac_ctx_get_params_fn *ctx_get_params;
+    OSSL_OP_mac_ctx_set_params_fn *ctx_set_params;
+};
 
 /* Internal keccak algorithms used for KMAC */
 const EVP_MD *evp_keccak_kmac128(void);
diff --git a/crypto/include/internal/modes_int.h b/crypto/include/internal/modes_int.h
index 5230f08966..08e4ffae74 100644
--- a/crypto/include/internal/modes_int.h
+++ b/crypto/include/internal/modes_int.h
@@ -211,6 +211,7 @@ struct siv128_context {
     SIV_BLOCK d;
     SIV_BLOCK tag;
     EVP_CIPHER_CTX *cipher_ctx;
+    EVP_MAC *mac;
     EVP_MAC_CTX *mac_ctx_init;
     int final_ret;
     int crypto_ok;
diff --git a/crypto/init.c b/crypto/init.c
index d5f0ebd7b7..04fd33087a 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -226,26 +226,6 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
     return 1;
 }
 
-static CRYPTO_ONCE add_all_macs = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_macs)
-{
-    /*
-     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
-     * pulling in all the macs during static linking
-     */
-#ifndef OPENSSL_NO_AUTOALGINIT
-    OSSL_TRACE(INIT, "openssl_add_all_macs_int()\n");
-    openssl_add_all_macs_int();
-#endif
-    return 1;
-}
-
-DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs)
-{
-    /* Do nothing */
-    return 1;
-}
-
 static CRYPTO_ONCE add_all_kdfs = CRYPTO_ONCE_STATIC_INIT;
 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_kdfs)
 {
@@ -558,15 +538,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
             && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
         return 0;
 
-    if ((opts & OPENSSL_INIT_NO_ADD_ALL_MACS)
-            && !RUN_ONCE_ALT(&add_all_macs, ossl_init_no_add_all_macs,
-                             ossl_init_add_all_macs))
-        return 0;
-
-    if ((opts & OPENSSL_INIT_ADD_ALL_MACS)
-            && !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs))
-        return 0;
-
     if ((opts & OPENSSL_INIT_NO_ADD_ALL_KDFS)
             && !RUN_ONCE_ALT(&add_all_kdfs, ossl_init_no_add_all_kdfs,
                              ossl_init_add_all_kdfs))
diff --git a/crypto/kdf/sskdf.c b/crypto/kdf/sskdf.c
index 62372a50ed..7e5a68be5e 100644
--- a/crypto/kdf/sskdf.c
+++ b/crypto/kdf/sskdf.c
@@ -40,12 +40,14 @@
 #include <openssl/hmac.h>
 #include <openssl/evp.h>
 #include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
 #include "internal/cryptlib.h"
 #include "internal/evp_int.h"
 #include "kdf_local.h"
 
 struct evp_kdf_impl_st {
-    const EVP_MAC *mac; /* H(x) = HMAC_hash OR H(x) = KMAC */
+    EVP_MAC *mac;       /* H(x) = HMAC_hash OR H(x) = KMAC */
     const EVP_MD *md;   /* H(x) = hash OR when H(x) = HMAC_hash */
     unsigned char *secret;
     size_t secret_len;
@@ -141,11 +143,17 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
                      size_t custom_len, size_t kmac_out_len,
                      size_t derived_key_len, unsigned char **out)
 {
+    OSSL_PARAM params[2];
+
     /* Only KMAC has custom data - so return if not KMAC */
     if (custom == NULL)
         return 1;
 
-    if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_CUSTOM, custom, custom_len) <= 0)
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM,
+                                                  (void *)custom, custom_len);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (!EVP_MAC_CTX_set_params(ctx, params))
         return 0;
 
     /* By default only do one iteration if kmac_out_len is not specified */
@@ -160,7 +168,10 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
             || kmac_out_len == 64))
         return 0;
 
-    if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_SIZE, kmac_out_len) <= 0)
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN,
+                                            &kmac_out_len);
+
+    if (EVP_MAC_CTX_set_params(ctx, params) <= 0)
         return 0;
 
     /*
@@ -181,7 +192,7 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
  *     H(x) = HMAC-hash(salt, x) OR
  *     H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
  */
-static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
+static int SSKDF_mac_kdm(EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
                          const unsigned char *kmac_custom,
                          size_t kmac_custom_len, size_t kmac_out_len,
                          const unsigned char *salt, size_t salt_len,
@@ -196,6 +207,8 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
     unsigned char *out = derived_key;
     EVP_MAC_CTX *ctx = NULL, *ctx_init = NULL;
     unsigned char *mac = mac_buf, *kmac_buffer = NULL;
+    OSSL_PARAM params[3];
+    size_t params_n = 0;
 
     if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
             || derived_key_len > SSKDF_MAX_INLEN
@@ -205,11 +218,20 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
     ctx_init = EVP_MAC_CTX_new(kdf_mac);
     if (ctx_init == NULL)
         goto end;
-    if (hmac_md != NULL &&
-            EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, hmac_md) <= 0)
-        goto end;
 
-    if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, salt, salt_len) <= 0)
+    if (hmac_md != NULL) {
+        const char *mdname = EVP_MD_name(hmac_md);
+        params[params_n++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                             (char *)mdname,
+                                             strlen(mdname) + 1);
+    }
+    params[params_n++] =
+        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (void *)salt,
+                                          salt_len);
+    params[params_n] = OSSL_PARAM_construct_end();
+
+    if (!EVP_MAC_CTX_set_params(ctx_init, params))
         goto end;
 
     if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
@@ -239,14 +261,14 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
                 && EVP_MAC_update(ctx, info, info_len)))
             goto end;
         if (len >= out_len) {
-            if (!EVP_MAC_final(ctx, out, NULL))
+            if (!EVP_MAC_final(ctx, out, NULL, len))
                 goto end;
             out += out_len;
             len -= out_len;
             if (len == 0)
                 break;
         } else {
-            if (!EVP_MAC_final(ctx, mac, NULL))
+            if (!EVP_MAC_final(ctx, mac, NULL, len))
                 goto end;
             memcpy(out, mac, len);
             break;
@@ -280,6 +302,10 @@ static void sskdf_reset(EVP_KDF_IMPL *impl)
     OPENSSL_clear_free(impl->secret, impl->secret_len);
     OPENSSL_clear_free(impl->info, impl->info_len);
     OPENSSL_clear_free(impl->salt, impl->salt_len);
+    EVP_MAC_free(impl->mac);
+#if 0                    /* TODO(3.0) When we switch to fetched MDs */
+    EVP_MD_meth_free(impl->md);
+#endif
     memset(impl, 0, sizeof(*impl));
 }
 
@@ -311,7 +337,6 @@ static int sskdf_set_buffer(va_list args, unsigned char **out, size_t *out_len)
 static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
 {
     const EVP_MD *md;
-    const EVP_MAC *mac;
 
     switch (cmd) {
     case EVP_KDF_CTRL_SET_KEY:
@@ -325,17 +350,34 @@ static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
         if (md == NULL)
             return 0;
 
+#if 0                    /* TODO(3.0) When we switch to fetched MDs */
+        EVP_MD_meth_free(impl->md);
+#endif
         impl->md = md;
         return 1;
 
     case EVP_KDF_CTRL_SET_MAC:
-        mac = va_arg(args, const EVP_MAC *);
-        if (mac == NULL)
-            return 0;
+        {
+            const char *name;
+            EVP_MAC *mac;
 
-        impl->mac = mac;
-        return 1;
+            name = va_arg(args, const char *);
+            if (name == NULL)
+                return 0;
+
+            EVP_MAC_free(impl->mac);
+            impl->mac = NULL;
 
+            /*
+             * TODO(3.0) add support for OPENSSL_CTX and properties in KDFs
+             */
+            mac = EVP_MAC_fetch(NULL, name, NULL);
+            if (mac == NULL)
+                return 0;
+
+            impl->mac = mac;
+            return 1;
+        }
     case EVP_KDF_CTRL_SET_SALT:
         return sskdf_set_buffer(args, &impl->salt, &impl->salt_len);
 
@@ -348,20 +390,6 @@ static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
     }
 }
 
-/* Pass a mac to a ctrl */
-static int sskdf_mac2ctrl(EVP_KDF_IMPL *impl,
-                          int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
-                          int cmd, const char *mac_name)
-{
-    const EVP_MAC *mac;
-
-    if (mac_name == NULL || (mac = EVP_get_macbyname(mac_name)) == NULL) {
-        KDFerr(KDF_F_SSKDF_MAC2CTRL, KDF_R_INVALID_MAC_TYPE);
-        return 0;
-    }
-    return call_ctrl(ctrl, impl, cmd, mac);
-}
-
 static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
                           const char *value)
 {
@@ -385,7 +413,7 @@ static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
         return kdf_md2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
 
     if (strcmp(type, "mac") == 0)
-        return sskdf_mac2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MAC, value);
+        return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MAC, value);
 
     if (strcmp(type, "salt") == 0)
         return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
@@ -430,11 +458,16 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
         int ret;
         const unsigned char *custom = NULL;
         size_t custom_len = 0;
-        int nid;
+        const char *macname;
         int default_salt_len;
 
-        nid = EVP_MAC_nid(impl->mac);
-        if (nid == EVP_MAC_HMAC) {
+        /*
+         * TODO(3.0) investigate the necessity to have all these controls.
+         * Why does KMAC require a salt length that's shorter than the MD
+         * block size?
+         */
+        macname = EVP_MAC_name(impl->mac);
+        if (strcmp(macname, "HMAC") == 0) {
             /* H(x) = HMAC(x, salt, hash) */
             if (impl->md == NULL) {
                 KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
@@ -443,11 +476,12 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
             default_salt_len = EVP_MD_block_size(impl->md);
             if (default_salt_len <= 0)
                 return 0;
-        } else if (nid == EVP_MAC_KMAC128 || nid == EVP_MAC_KMAC256) {
+        } else if (strcmp(macname, "KMAC128") == 0
+                   || strcmp(macname, "KMAC256") == 0) {
             /* H(x) = KMACzzz(x, salt, custom) */
             custom = kmac_custom_str;
             custom_len = sizeof(kmac_custom_str);
-            if (nid == EVP_MAC_KMAC128)
+            if (strcmp(macname, "KMAC128") == 0)
                 default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
             else
                 default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c
index b14ae6fee1..1df201dd3f 100644
--- a/crypto/kdf/tls1_prf.c
+++ b/crypto/kdf/tls1_prf.c
@@ -51,6 +51,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/kdf.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
 #include "internal/evp_int.h"
 #include "kdf_local.h"
 
@@ -232,19 +234,30 @@ static int tls1_prf_P_hash(const EVP_MD *md,
                            unsigned char *out, size_t olen)
 {
     size_t chunk;
+    EVP_MAC *mac = NULL;
     EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL, *ctx_init = NULL;
     unsigned char Ai[EVP_MAX_MD_SIZE];
     size_t Ai_len;
     int ret = 0;
+    OSSL_PARAM params[4];
+    int mac_flags;
+    const char *mdname = EVP_MD_name(md);
 
-    ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
+    mac = EVP_MAC_fetch(NULL, "HMAC", NULL); /* Implicit fetch */
+    ctx_init = EVP_MAC_CTX_new(mac);
     if (ctx_init == NULL)
         goto err;
-    if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_FLAGS, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) != 1)
-        goto err;
-    if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, md) != 1)
-        goto err;
-    if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, sec, sec_len) != 1)
+
+    /* TODO(3.0) rethink "flags", also see hmac.c in providers */
+    mac_flags = EVP_MD_CTX_FLAG_NON_FIPS_ALLOW;
+    params[0] = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &mac_flags);
+    params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                                 (char *)mdname,
+                                                 strlen(mdname) + 1);
+    params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                  (void *)sec, sec_len);
+    params[3] = OSSL_PARAM_construct_end();
+    if (!EVP_MAC_CTX_set_params(ctx_init, params))
         goto err;
     if (!EVP_MAC_init(ctx_init))
         goto err;
@@ -260,7 +273,7 @@ static int tls1_prf_P_hash(const EVP_MD *md,
 
     for (;;) {
         /* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */
-        if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len))
+        if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai)))
             goto err;
         EVP_MAC_CTX_free(ctx_Ai);
         ctx_Ai = NULL;
@@ -281,12 +294,12 @@ static int tls1_prf_P_hash(const EVP_MD *md,
             goto err;
         if (olen <= chunk) {
             /* last chunk - use Ai as temp bounce buffer */
-            if (!EVP_MAC_final(ctx, Ai, &Ai_len))
+            if (!EVP_MAC_final(ctx, Ai, &Ai_len, sizeof(Ai)))
                 goto err;
             memcpy(out, Ai, olen);
             break;
         }
-        if (!EVP_MAC_final(ctx, out, NULL))
+        if (!EVP_MAC_final(ctx, out, NULL, olen))
             goto err;
         EVP_MAC_CTX_free(ctx);
         ctx = NULL;
@@ -298,6 +311,7 @@ static int tls1_prf_P_hash(const EVP_MD *md,
     EVP_MAC_CTX_free(ctx);
     EVP_MAC_CTX_free(ctx_Ai);
     EVP_MAC_CTX_free(ctx_init);
+    EVP_MAC_free(mac);
     OPENSSL_cleanse(Ai, sizeof(Ai));
     return ret;
 }
diff --git a/crypto/kmac/build.info b/crypto/kmac/build.info
deleted file mode 100644
index 01d04be580..0000000000
--- a/crypto/kmac/build.info
+++ /dev/null
@@ -1,3 +0,0 @@
-LIBS=../../libcrypto
-SOURCE[../../libcrypto]=kmac.c
-
diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c
index 359252f196..04abea25c1 100644
--- a/crypto/modes/siv128.c
+++ b/crypto/modes/siv128.c
@@ -11,6 +11,8 @@
 #include <stdlib.h>
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
 #include "internal/modes_int.h"
 #include "internal/siv_int.h"
 
@@ -117,7 +119,7 @@ __owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *ou
         if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN))
             goto err;
     }
-    if (!EVP_MAC_final(mac_ctx, out->byte, &out_len)
+    if (!EVP_MAC_final(mac_ctx, out->byte, &out_len, sizeof(out->byte))
         || out_len != SIV_LEN)
         goto err;
 
@@ -167,6 +169,15 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
     static const unsigned char zero[SIV_LEN] = { 0 };
     size_t out_len = SIV_LEN;
     EVP_MAC_CTX *mac_ctx = NULL;
+    OSSL_PARAM params[3];
+    const char *cbc_name = EVP_CIPHER_name(cbc);
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                                 (char *)cbc_name,
+                                                 strlen(cbc_name) + 1);
+    params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                  (void *)key, klen);
+    params[2] = OSSL_PARAM_construct_end();
 
     memset(&ctx->d, 0, sizeof(ctx->d));
     ctx->cipher_ctx = NULL;
@@ -174,16 +185,19 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
 
     if (key == NULL || cbc == NULL || ctr == NULL
             || (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
-            || (ctx->mac_ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_CMAC)) == NULL
-            || EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_CIPHER, cbc) <= 0
-            || EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_KEY, key, klen) <= 0
+            /* TODO(3.0) library context */
+            || (ctx->mac = EVP_MAC_fetch(NULL, "CMAC", NULL)) == NULL
+            || (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL
+            || !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params)
             || !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
             || (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL
             || !EVP_MAC_update(mac_ctx, zero, sizeof(zero))
-            || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len)) {
+            || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len,
+                              sizeof(ctx->d.byte))) {
         EVP_CIPHER_CTX_free(ctx->cipher_ctx);
         EVP_MAC_CTX_free(ctx->mac_ctx_init);
         EVP_MAC_CTX_free(mac_ctx);
+        EVP_MAC_free(ctx->mac);
         return 0;
     }
     EVP_MAC_CTX_free(mac_ctx);
@@ -223,10 +237,10 @@ int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad,
 
     siv128_dbl(&ctx->d);
 
-    mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init);
-    if (mac_ctx == NULL
+    if ((mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL
         || !EVP_MAC_update(mac_ctx, aad, len)
-        || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len)
+        || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len,
+                          sizeof(mac_out.byte))
         || out_len != SIV_LEN) {
         EVP_MAC_CTX_free(mac_ctx);
         return 0;
@@ -345,6 +359,8 @@ int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx)
         ctx->cipher_ctx = NULL;
         EVP_MAC_CTX_free(ctx->mac_ctx_init);
         ctx->mac_ctx_init = NULL;
+        EVP_MAC_free(ctx->mac);
+        ctx->mac = NULL;
         OPENSSL_cleanse(&ctx->d, sizeof(ctx->d));
         OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag));
         ctx->final_ret = -1;
diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c
index 2a861c94fe..72770ddc53 100644
--- a/crypto/params_from_text.c
+++ b/crypto/params_from_text.c
@@ -91,6 +91,8 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
     case OSSL_PARAM_OCTET_STRING:
         if (*ishex) {
             *buf_n = strlen(value) >> 1;
+        } else {
+            *buf_n = value_n;
         }
         break;
     }
diff --git a/crypto/poly1305/build.info b/crypto/poly1305/build.info
index 064c2599d5..cab28f4bdb 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_meth.c poly1305.c $POLY1305ASM
+SOURCE[../../libcrypto]=poly1305_ameth.c poly1305.c $POLY1305ASM
 DEFINE[../../libcrypto]=$POLY1305DEF
 
 GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME)
diff --git a/crypto/poly1305/poly1305_meth.c b/crypto/poly1305/poly1305_meth.c
deleted file mode 100644
index f1ade58b40..0000000000
--- a/crypto/poly1305/poly1305_meth.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 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 <openssl/evp.h>
-#include "internal/evp_int.h"
-#include "internal/poly1305.h"
-#include "internal/cryptlib.h"
-#include "poly1305_local.h"
-
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
-    POLY1305 *ctx;               /* poly1305 context */
-};
-
-static EVP_MAC_IMPL *poly1305_new(void)
-{
-    EVP_MAC_IMPL *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
-            || (ctx->ctx = OPENSSL_zalloc(sizeof(POLY1305))) == NULL) {
-        OPENSSL_free(ctx);
-        return 0;
-    }
-    return ctx;
-}
-
-static void poly1305_free(EVP_MAC_IMPL *ctx)
-{
-    if (ctx != NULL) {
-        OPENSSL_free(ctx->ctx);
-        OPENSSL_free(ctx);
-    }
-}
-
-static EVP_MAC_IMPL *poly1305_dup(const EVP_MAC_IMPL *src)
-{
-    EVP_MAC_IMPL *dst;
-
-    dst = poly1305_new();
-    if (dst == NULL)
-        return NULL;
-
-    *dst->ctx = *src->ctx;
-
-    return dst;
-}
-
-static size_t poly1305_size(EVP_MAC_IMPL *ctx)
-{
-    return POLY1305_DIGEST_SIZE;
-}
-
-static int poly1305_init(EVP_MAC_IMPL *ctx)
-{
-    /* initialize the context in MAC_ctrl function */
-    return 1;
-}
-
-static int poly1305_update(EVP_MAC_IMPL *ctx, const unsigned char *data,
-                       size_t datalen)
-{
-    POLY1305 *poly_ctx = ctx->ctx;
-
-    /* poly1305 has nothing to return in its update function */
-    Poly1305_Update(poly_ctx, data, datalen);
-    return 1;
-}
-
-static int poly1305_final(EVP_MAC_IMPL *ctx, unsigned char *out)
-{
-    POLY1305 *poly_ctx = ctx->ctx;
-
-    Poly1305_Final(poly_ctx, out);
-    return 1;
-}
-
-static int poly1305_ctrl(EVP_MAC_IMPL *ctx, int cmd, va_list args)
-{
-    POLY1305 *poly_ctx = ctx->ctx;
-    unsigned char *key;
-    size_t keylen;
-
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_KEY:
-        key = va_arg(args, unsigned char *);
-        keylen = va_arg(args, size_t);
-
-        if (keylen != POLY1305_KEY_SIZE) {
-            EVPerr(EVP_F_POLY1305_CTRL, EVP_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        Poly1305_Init(poly_ctx, key);
-        return 1;
-    default:
-        return -2;
-    }
-    return 1;
-}
-
-static int poly1305_ctrl_int(EVP_MAC_IMPL *ctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = poly1305_ctrl(ctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int poly1305_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
-{
-    return poly1305_ctrl_int(ctx, cmd, buf, buflen);
-}
-
-static int poly1305_ctrl_str(EVP_MAC_IMPL *ctx,
-                             const char *type, const char *value)
-{
-    if (value == NULL)
-        return 0;
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    return -2;
-}
-
-const EVP_MAC poly1305_meth = {
-    EVP_MAC_POLY1305,
-    poly1305_new,
-    poly1305_dup,
-    poly1305_free,
-    poly1305_size,
-    poly1305_init,
-    poly1305_update,
-    poly1305_final,
-    poly1305_ctrl,
-    poly1305_ctrl_str
-};
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 637ecab1b6..6abada3c4b 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -706,6 +706,11 @@ const char *ossl_provider_module_path(const OSSL_PROVIDER *prov)
 #endif
 }
 
+OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov)
+{
+    return prov->libctx;
+}
+
 /* Wrappers around calls to the provider */
 void ossl_provider_teardown(const OSSL_PROVIDER *prov)
 {
@@ -801,7 +806,7 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
 
 static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov)
 {
-    return prov->libctx;
+    return ossl_provider_library_context(prov);
 }
 
 static int core_thread_start(const OSSL_PROVIDER *prov,
diff --git a/crypto/siphash/build.info b/crypto/siphash/build.info
index b56563f0bb..2dc7101a10 100644
--- a/crypto/siphash/build.info
+++ b/crypto/siphash/build.info
@@ -1,5 +1,4 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
 	siphash.c \
-	siphash_meth.c \
 	siphash_ameth.c
diff --git a/crypto/siphash/siphash_meth.c b/crypto/siphash/siphash_meth.c
deleted file mode 100644
index 5fcff2d1ef..0000000000
--- a/crypto/siphash/siphash_meth.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 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 <stdarg.h>
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include "internal/siphash.h"
-#include "siphash_local.h"
-#include "internal/evp_int.h"
-
-/* local SIPHASH structure is actually a SIPHASH */
-
-struct evp_mac_impl_st {
-    SIPHASH ctx;
-};
-
-static EVP_MAC_IMPL *siphash_new(void)
-{
-    return OPENSSL_zalloc(sizeof(EVP_MAC_IMPL));
-}
-
-static void siphash_free(EVP_MAC_IMPL *sctx)
-{
-    OPENSSL_free(sctx);
-}
-
-static EVP_MAC_IMPL *siphash_dup(const EVP_MAC_IMPL *ssrc)
-{
-    EVP_MAC_IMPL *sdst;
-
-    sdst = siphash_new();
-    if (sdst == NULL)
-        return NULL;
-
-    *sdst = *ssrc;
-
-    return sdst;
-}
-
-static size_t siphash_size(EVP_MAC_IMPL *sctx)
-{
-    return SipHash_hash_size(&sctx->ctx);
-}
-
-static int siphash_init(EVP_MAC_IMPL *sctx)
-{
-    /* Not much to do here, actual initialization happens through controls */
-    return 1;
-}
-
-static int siphash_update(EVP_MAC_IMPL *sctx, const unsigned char *data,
-                       size_t datalen)
-{
-    SipHash_Update(&sctx->ctx, data, datalen);
-    return 1;
-}
-
-static int siphash_final(EVP_MAC_IMPL *sctx, unsigned char *out)
-{
-    size_t hlen = siphash_size(sctx);
-
-    return SipHash_Final(&sctx->ctx, out, hlen);
-}
-
-static int siphash_ctrl(EVP_MAC_IMPL *sctx, int cmd, va_list args)
-{
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_SIZE:
-        {
-            size_t size = va_arg(args, size_t);
-
-            return SipHash_set_hash_size(&sctx->ctx, size);
-        }
-        break;
-    case EVP_MAC_CTRL_SET_KEY:
-        {
-            const unsigned char *key = va_arg(args, const unsigned char *);
-            size_t keylen = va_arg(args, size_t);
-
-            if (key == NULL || keylen != SIPHASH_KEY_SIZE)
-                return 0;
-
-            return SipHash_Init(&sctx->ctx, key, 0, 0);
-        }
-        break;
-    default:
-        return -2;
-    }
-    return 1;
-}
-
-static int siphash_ctrl_int(EVP_MAC_IMPL *sctx, int cmd, ...)
-{
-    int rv;
-    va_list args;
-
-    va_start(args, cmd);
-    rv = siphash_ctrl(sctx, cmd, args);
-    va_end(args);
-
-    return rv;
-}
-
-static int siphash_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
-{
-    return siphash_ctrl_int(ctx, cmd, buf, buflen);
-}
-
-static int siphash_ctrl_str(EVP_MAC_IMPL *ctx,
-                            const char *type, const char *value)
-{
-    if (value == NULL)
-        return 0;
-    if (strcmp(type, "digestsize") == 0) {
-        size_t hash_size = atoi(value);
-
-        return siphash_ctrl_int(ctx, EVP_MAC_CTRL_SET_SIZE, hash_size);
-    }
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    return -2;
-}
-
-const EVP_MAC siphash_meth = {
-    EVP_MAC_SIPHASH,
-    siphash_new,
-    siphash_dup,
-    siphash_free,
-    siphash_size,
-    siphash_init,
-    siphash_update,
-    siphash_final,
-    siphash_ctrl,
-    siphash_ctrl_str
-};
diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod
index dd9f1cbec5..7154d5f36a 100644
--- a/doc/internal/man3/ossl_provider_new.pod
+++ b/doc/internal/man3/ossl_provider_new.pod
@@ -11,6 +11,7 @@ ossl_provider_ctx,
 ossl_provider_forall_loaded,
 ossl_provider_name, ossl_provider_dso,
 ossl_provider_module_name, ossl_provider_module_path,
+ossl_provider_library_context,
 ossl_provider_teardown, ossl_provider_gettable_params,
 ossl_provider_get_params, ossl_provider_query_operation
 - internal provider routines
@@ -52,6 +53,7 @@ ossl_provider_get_params, ossl_provider_query_operation
  const DSO *ossl_provider_dso(OSSL_PROVIDER *prov);
  const char *ossl_provider_module_name(OSSL_PROVIDER *prov);
  const char *ossl_provider_module_path(OSSL_PROVIDER *prov);
+ OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov);
 
  /* Thin wrappers around calls to the provider */
  void ossl_provider_teardown(const OSSL_PROVIDER *prov);
@@ -132,6 +134,9 @@ This will be used in preference to automatically trying to figure out
 the path from the provider name and the default module directory (more
 on this in L</NOTES>).
 
+ossl_provider_library_context() returns the library context the given
+provider I<prov> is registered in.
+
 ossl_provider_add_parameter() adds a global parameter for the provider
 to retrieve as it sees fit.
 The parameters are a combination of I<name> and I<value>, and the
@@ -252,6 +257,10 @@ ossl_provider_module_name(), and ossl_provider_module_path() return a
 pointer to their respective data if it's available, otherwise NULL
 is returned.
 
+ossl_provider_library_context() return a pointer to the library context.
+This may be NULL, and is perfectly valid, as it denotes the default
+global library context.
+
 ossl_provider_teardown() doesnt't return any value.
 
 ossl_provider_gettable_params() returns a pointer to a constant
diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod
index a696c43cc5..6cc28a7355 100644
--- a/doc/man3/EVP_MAC.pod
+++ b/doc/man3/EVP_MAC.pod
@@ -2,11 +2,13 @@
 
 =head1 NAME
 
-EVP_MAC, EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_new_id, EVP_MAC_CTX_free,
-EVP_MAC_CTX_dup, EVP_MAC_CTX_mac, EVP_MAC_size, EVP_MAC_init, EVP_MAC_update,
-EVP_MAC_final, EVP_MAC_ctrl, EVP_MAC_vctrl, EVP_MAC_ctrl_str,
-EVP_MAC_str2ctrl, EVP_MAC_hex2ctrl, EVP_MAC_nid, EVP_MAC_name,
-EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines
+EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free, EVP_MAC_name,
+EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params,
+EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup,
+EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
+EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final,
+EVP_MAC_CTX_gettable_params, EVP_MAC_CTX_settable_params,
+EVP_MAC_do_all_ex - EVP MAC routines
 
 =head1 SYNOPSIS
 
@@ -15,25 +17,34 @@ EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines
  typedef struct evp_mac_st EVP_MAC;
  typedef struct evp_mac_ctx_st EVP_MAC_CTX;
 
- EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
- EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);
+ EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
+                        const char *properties);
+ int EVP_MAC_up_ref(EVP_MAC *mac);
+ void EVP_MAC_free(EVP_MAC *mac);
+ const char *EVP_MAC_name(const EVP_MAC *mac);
+ const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
+ int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
+
+ EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac);
  void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
  EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src);
- const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
+ EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
+ int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]);
+ int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
+
  size_t EVP_MAC_size(EVP_MAC_CTX *ctx);
  int EVP_MAC_init(EVP_MAC_CTX *ctx);
  int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
- int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen);
- int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...);
- int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args);
- int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value);
- int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
- int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
- int EVP_MAC_nid(const EVP_MAC *mac);
- const char *EVP_MAC_name(const EVP_MAC *mac);
- const EVP_MAC *EVP_get_macbyname(const char *name);
- const EVP_MAC *EVP_get_macbynid(int nid);
- const EVP_MAC *EVP_get_macbyobj(const ASN1_OBJECT *o);
+ int EVP_MAC_final(EVP_MAC_CTX *ctx,
+                   unsigned char *out, size_t *outl, size_t outsize);
+
+ const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac);
+ const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac);
+ const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac);
+
+ void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx,
+                        void (*fn)(EVP_MAC *mac, void *arg),
+                        void *arg);
 
 =head1 DESCRIPTION
 
@@ -60,23 +71,36 @@ B<EVP_MAC_CTX> is a context type that holds internal MAC information
 as well as a reference to a computation context, for those MACs that
 rely on an underlying computation algorithm.
 
+=head2 Algorithm implementation fetching
+
+EVP_MAC_fetch() fetches an implementation of a MAC I<algorithm>, given
+a library context I<libctx> and a set of I<properties>.
+See L<provider(7)/Fetching algorithms> for further information.
+
+The returned value must eventually be freed with
+L<EVP_MAC_free(3)>.
+
+EVP_MAC_up_ref() increments the reference count of an already fetched
+MAC.
+
+EVP_MAC_free() frees a fetched algorithm.
+NULL is a valid parameter, for which this function is a no-op.
+
 =head2 Context manipulation functions
 
-EVP_MAC_CTX_new() creates a new context for the MAC type C<mac>.
-EVP_MAC_CTX_new_id() creates a new context for the numerical MAC
-identity <nid>.
+EVP_MAC_CTX_new() creates a new context for the MAC type I<mac>.
 The created context can then be used with most other functions
 described here.
 
 EVP_MAC_CTX_free() frees the contents of the context, including an
 underlying context if there is one, as well as the context itself.
-B<NULL> is a valid parameter, for which this function is a no-op.
+NULL is a valid parameter, for which this function is a no-op.
 
-EVP_MAC_CTX_dup() duplicates the C<src> context and returns a newly allocated
+EVP_MAC_CTX_dup() duplicates the I<src> context and returns a newly allocated
 context.
 
 EVP_MAC_CTX_mac() returns the B<EVP_MAC> associated with the context
-C<ctx>.
+I<ctx>.
 
 =head2 Computing functions
 
@@ -85,131 +109,125 @@ through diverse controls.
 This should be called before calling EVP_MAC_update() and
 EVP_MAC_final().
 
-EVP_MAC_update() adds C<datalen> bytes from C<data> to the MAC input.
+EVP_MAC_update() adds I<datalen> bytes from I<data> to the MAC input.
 
 EVP_MAC_final() does the final computation and stores the result in
-the memory pointed at by C<out>, and sets its size in the B<size_t>
-the C<poutlen> points at.
-If C<out> is B<NULL>, then no computation is made.
+the memory pointed at by I<out> of size I<outsize>, and sets the number
+of bytes written in I<*outl> at.
+If I<out> is B<NULL> or I<outsize> is too small, then no computation
+is made.
 To figure out what the output length will be and allocate space for it
-dynamically, simply call with C<out> being B<NULL> and C<poutlen>
+dynamically, simply call with I<out> being B<NULL> and I<outl>
 pointing at a valid location, then allocate space and make a second
-call with C<out> pointing at the allocated space.
-
-EVP_MAC_ctrl() is used to manipulate or get information on aspects of
-the MAC which may vary depending on the MAC algorithm or its
-implementation.
-This includes the MAC key, and for MACs that use other algorithms to
-do their computation, this is also the way to tell it which one to
-use.
-This functions takes variable arguments, the exact expected arguments
-depend on C<cmd>.
-EVP_MAC_ctrl() can be called both before and after EVP_MAC_init(), but
-the effect will depend on what control is being use.
-See L</CONTROLS> below for a description of standard controls.
-
-EVP_MAC_vctrl() is the variant of EVP_MAC_ctrl() that takes a
-C<va_list> argument instead of variadic arguments.
-
-EVP_MAC_ctrl_str() is an alternative to EVP_MAC_ctrl() to control the
-MAC implementation as E<lt> C<type>, C<value> E<gt> pairs.
-The MAC implementation documentation should specify what control type
-strings are accepted.
-
-EVP_MAC_str2ctrl() and EVP_MAC_hex2ctrl() are helper functions to
-control the MAC implementation with raw strings or with strings
-containing hexadecimal numbers.
-The latter are decoded into bitstrings that are sent on to
-EVP_MAC_ctrl().
+call with I<out> pointing at the allocated space.
+
+EVP_MAC_get_params() retrieves details about the implementation
+I<mac>.
+The set of parameters given with I<params> determine exactly what
+parameters should be retrieved.
+Note that a parameter that is unknown in the underlying context is
+simply ignored.
+
+EVP_MAC_CTX_get_params() retrieves chosen parameters, given the
+context I<ctx> and its underlying context.
+The set of parameters given with I<params> determine exactly what
+parameters should be retrieved.
+Note that a parameter that is unknown in the underlying context is
+simply ignored.
+
+EVP_MAC_CTX_set_params() passes chosen parameters to the underlying
+context, given a context I<ctx>.
+The set of parameters given with I<params> determine exactly what
+parameters are passed down.
+Note that a parameter that is unknown in the underlying context is
+simply ignored.
+Also, what happens when a needed parameter isn't passed down is
+defined by the implementation.
+
+EVP_MAC_gettable_params(), EVP_MAC_CTX_gettable_params() and
+EVP_MAC_CTX_settable_params() get a constant B<OSSL_PARAM> array that
+decribes the retrievable and settable parameters, i.e. parameters that
+can be used with EVP_MAC_CTX_get_params(), EVP_MAC_CTX_get_params()
+and EVP_MAC_CTX_set_params(), respectively.
+See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
 
 =head2 Information functions
 
 EVP_MAC_size() returns the MAC output size for the given context.
 
-EVP_MAC_nid() returns the numeric identity of the given MAC implementation.
-
 EVP_MAC_name() returns the name of the given MAC implementation.
 
-=head2 Object database functions
-
-EVP_get_macbyname() fetches a MAC implementation from the object
-database by name.
-
-EVP_get_macbynid() fetches a MAC implementation from the object
-database by numeric identity.
+EVP_MAC_provider() returns the provider that holds the implementation
+of the given I<mac>.
 
-EVP_get_macbyobj() fetches a MAC implementation from the object
-database by ASN.1 OBJECT (i.e. an encoded OID).
+EVP_MAC_do_all_ex() traverses all MAC implemented by all activated
+providers in the given library context I<libctx>, and for each of the
+implementations, calls the given function I<fn> with the implementation method
+and the given I<arg> as argument.
 
-=head1 CONTROLS
+=head1 PARAMETER NAMES
 
-The standard controls are:
+The standard parameter names are:
 
 =over 4
 
-=item B<EVP_MAC_CTRL_SET_KEY>
+=item OSSL_MAC_PARAM_KEY ("key") <octet string>
 
-This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
-
-These will set the MAC key from the given string of the given length.
-The string may be any bitstring, and can contain NUL bytes.
+Its value is the MAC key as an array of bytes.
 
 For MACs that use an underlying computation algorithm, the algorithm
-I<must> be set first, see B<EVP_MAC_CTRL_SET_ENGINE>,
-B<EVP_MAC_CTRL_SET_MD> and B<EVP_MAC_CTRL_SET_CIPHER> below.
-
-=item B<EVP_MAC_CTRL_SET_IV>
+must be set first, see parameter names "algorithm" below.
 
-This control expects two arguments: C<unsigned char *iv>, C<size_t ivlen>
+=item OSSL_MAC_PARAM_IV ("iv") <octet string>
 
-Some MAC implementations require an IV, this control sets the IV.
+Some MAC implementations require an IV, this parameter sets the IV.
 
-=item B<EVP_MAC_CTRL_SET_CUSTOM>
-
-This control expects two arguments: C<unsigned char *custom>, C<size_t customlen>
+=item OSSL_MAC_PARAM_CUSTOM ("custom") <octet string>
 
 Some MAC implementations (KMAC, BLAKE2) accept a Customization String,
-this control sets the Customization String. The default value is "".
-
-=item B<EVP_MAC_CTRL_SET_SALT>
+this parameter sets the Customization String. The default value is the
+empty string.
 
-This control expects two arguments: C<unsigned char *salt>, C<size_t saltlen>
+=item OSSL_MAC_PARAM_SALT ("salt") <octet string>
 
 This option is used by BLAKE2 MAC.
 
-=item B<EVP_MAC_CTRL_SET_XOF>
+=item OSSL_MAC_PARAM_XOF ("xof") <int>
 
-This control expects one argument: C<int xof>
+It's a simple flag, the value 0 or 1 are expected.
 
 This option is used by KMAC.
 
-=item B<EVP_MAC_CTRL_SET_FLAGS>
-
-This control expects one argument: C<unsigned long flags>
+=item OSSL_MAC_PARAM_FLAGS ("flags") <int>
 
 These will set the MAC flags to the given numbers.
 Some MACs do not support this option.
 
-=item B<EVP_MAC_CTRL_SET_ENGINE>
+=item OSSL_MAC_PARAM_ENGINE ("engine") <utf8string>
+
+=item OSSL_MAC_PARAM_MD ("md") <utf8string>
+
+=item OSSL_MAC_PARAM_DIGEST ("digest") <utf8string>
 
-=item B<EVP_MAC_CTRL_SET_MD>
+=item OSSL_MAC_PARAM_CIPHER ("cipher") <utf8string>
 
-=item B<EVP_MAC_CTRL_SET_CIPHER>
+=item OSSL_MAC_PARAM_ALGORITHM ("algorithm") <utf8string>
 
 For MAC implementations that use an underlying computation algorithm,
-these controls set what the algorithm should be, and the engine that
+these parameters set what the algorithm should be, and the engine that
 implements the algorithm if needed.
 
-Note that not all algorithms may support all digests. HMAC does not support
-variable output length digests such as SHAKE128 or SHAKE256.
+The value is always the name of the intended engine or algorithm.
 
-B<EVP_MAC_CTRL_SET_ENGINE> takes one argument: C<ENGINE *>
+Note that not all algorithms may support all digests.
+HMAC does not support variable output length digests such as SHAKE128
+or SHAKE256.
 
-B<EVP_MAC_CTRL_SET_MD> takes one argument: C<EVP_MD *>
+Also note that OSSL_MAC_PARAM_ALGORITHM can be use generically instead
+of OSSL_MAC_PARAM_MD, OSSL_MAC_PARAM_DIGEST or OSSL_MAC_PARAM_CIPHER,
+and that OSSL_MAC_PARAM_MD and OSSL_MAC_PARAM_DIGEST are also interchangable.
 
-B<EVP_MAC_CTRL_SET_CIPHER> takes one argument: C<EVP_CIPHER *>
-
-=item B<EVP_MAC_CTRL_SET_SIZE>
+=item OSSL_MAC_PARAM_SIZE <unsigned int>
 
 For MAC implementations that support it, set the output size that
 EVP_MAC_final() should produce.
@@ -217,46 +235,42 @@ The allowed sizes vary between MAC implementations.
 
 =back
 
-All these control should be used before the calls to any of
+All these parameters should be used before the calls to any of
 EVP_MAC_init(), EVP_MAC_update() and EVP_MAC_final() for a full
 computation.
 Anything else may give undefined results.
 
-=head1 NOTES
+=head1 RETURN VALUES
 
-EVP_get_macbynid(), EVP_get_macbyobj() and EVP_MAC_name() are
-implemented as a macro.
+EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or
+NULL if allocation failed.
 
-=head1 RETURN VALUES
+EVP_MAC_up_ref() returns 1 on success, 0 on error.
+
+EVP_MAC_free() returns nothing at all.
+
+EVP_MAC_name() returns the name of the MAC, or NULL if NULL was
+passed.
+
+EVP_MAC_provider() returns a pointer to the provider for the MAC, or
+NULL on error.
 
-EVP_MAC_CTX_new(), EVP_MAC_CTX_new_id() and EVP_MAC_CTX_dup() return a pointer
-to a newly created EVP_MAC_CTX, or NULL if allocation failed.
+EVP_MAC_CTX_new() and EVP_MAC_CTX_dup() return a pointer to a newly
+created EVP_MAC_CTX, or NULL if allocation failed.
 
 EVP_MAC_CTX_free() returns nothing at all.
 
-EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 on error.
+EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on
+success, 0 on error.
 
-EVP_MAC_ctrl(), EVP_MAC_ctrl_str(), EVP_MAC_str2ctrl() and
-EVP_MAC_hex2ctrl() return 1 on success and 0 or a negative value on
-error.
-In particular, the value -2 indicates that the given control type
-isn't supported by the MAC implementation.
+EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0
+on error.
 
 EVP_MAC_size() returns the expected output size, or 0 if it isn't
 set.
 If it isn't set, a call to EVP_MAC_init() should get it set.
 
-EVP_MAC_nid() returns the numeric identity for the given C<mac>.
-
-EVP_MAC_name() returns the name for the given C<mac>, if it has been
-added to the object database.
-
-EVP_add_mac() returns 1 if the given C<mac> was successfully added to
-the object database, otherwise 0.
-
-EVP_get_macbyname(), EVP_get_macbynid() and EVP_get_macbyobj() return
-the request MAC implementation, if it exists in the object database,
-otherwise B<NULL>.
+EVP_MAC_do_all_ex() returns nothing at all.
 
 =head1 EXAMPLE
 
@@ -268,29 +282,12 @@ otherwise B<NULL>.
 
   #include <openssl/evp.h>
   #include <openssl/err.h>
-
-  int ctrl_ign_unsupported(EVP_MAC_CTX *ctx, int cmd, ...)
-  {
-      va_list args;
-      int rv;
-
-      va_start(args, cmd);
-      rv = EVP_MAC_vctrl(ctx, cmd, args);
-      va_end(args);
-
-      if (rv == -2)
-          rv = 1;       /* Ignore unsupported, pretend it worked fine */
-
-      return rv;
-  }
+  #include <openssl/params.h>
 
   int main() {
-      const EVP_MAC *mac =
-          EVP_get_macbyname(getenv("MY_MAC"));
-      const EVP_CIPHER *cipher =
-          EVP_get_cipherbyname(getenv("MY_MAC_CIPHER"));
-      const EVP_MD *digest =
-          EVP_get_digestbyname(getenv("MY_MAC_DIGEST"));
+      EVP_MAC *mac = EVP_MAC_fetch(NULL, getenv("MY_MAC"), NULL);
+      const char *cipher = getenv("MY_MAC_CIPHER");
+      const char *digest = getenv("MY_MAC_DIGEST");
       const char *key = getenv("MY_KEY");
       EVP_MAC_CTX *ctx = NULL;
 
@@ -300,14 +297,25 @@ otherwise B<NULL>.
 
       size_t i;
 
+      OSSL_PARAM params[4];
+      size_t params_n = 0;
+
+      if (cipher != NULL)
+          params[params_n++] =
+              OSSL_PARAM_construct_utf8_string("cipher", cipher,
+                                               strlen(cipher) + 1, NULL);
+      if (digest != NULL)
+          params[params_n++] =
+              OSSL_PARAM_construct_utf8_string("digest", digest,
+                                               strlen(digest) + 1, NULL);
+      params[params_n++] =
+          OSSL_PARAM_construct_octet_string("key", key, strlen(key), NULL);
+      params[params_n] = OSSL_PARAM_construct_end();
+
       if (mac == NULL
           || key == NULL
           || (ctx = EVP_MAC_CTX_new(mac)) == NULL
-          || (cipher != NULL
-              && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_CIPHER, cipher))
-          || (digest != NULL
-              && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_MD, digest))
-          || EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY, key, strlen(key)) <= 0)
+          || EVP_MAC_CTX_set_params(ctx, params) <= 0)
           goto err;
 
       if (!EVP_MAC_init(ctx))
@@ -327,10 +335,12 @@ otherwise B<NULL>.
       printf("\n");
 
       EVP_MAC_CTX_free(ctx);
+      EVP_MAC_free(mac);
       exit(0);
 
    err:
       EVP_MAC_CTX_free(ctx);
+      EVP_MAC_free(mac);
       fprintf(stderr, "Something went wrong\n");
       ERR_print_errors_fp(stderr);
       exit (1);
@@ -348,6 +358,8 @@ F<./foo>)
 
 =head1 SEE ALSO
 
+L<property(7)>
+L<OSSL_PARAM(3)>,
 L<EVP_MAC_BLAKE2(7)>,
 L<EVP_MAC_CMAC(7)>,
 L<EVP_MAC_GMAC(7)>,
@@ -362,7 +374,7 @@ These functions were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2018-2019 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
diff --git a/doc/man7/provider-mac.pod b/doc/man7/provider-mac.pod
new file mode 100644
index 0000000000..65aa0124e5
--- /dev/null
+++ b/doc/man7/provider-mac.pod
@@ -0,0 +1,255 @@
+=pod
+
+=head1 NAME
+
+provider-mac - The mac library E<lt>-E<gt> provider functions
+
+=head1 SYNOPSIS
+
+=for comment multiple includes
+
+ #include <openssl/core_numbers.h>
+ #include <openssl/core_names.h>
+
+ /*
+  * None of these are actual functions, but are displayed like this for
+  * the function signatures for functions that are offered as function
+  * pointers in OSSL_DISPATCH arrays.
+  */
+
+ /* Context management */
+ void *OP_mac_newctx(void *provctx);
+ void OP_mac_freectx(void *mctx);
+ void *OP_mac_dupctx(void *src);
+
+ /* Encryption/decryption */
+ int OP_mac_init(void *mctx);
+ int OP_mac_update(void *mctx, const unsigned char *in, size_t inl);
+ int OP_mac_final(void *mctx, unsigned char *out, size_t *outl, size_t outsize);
+
+ /* MAC parameter descriptors */
+ const OSSL_PARAM *OP_mac_get_params(void);
+ const OSSL_PARAM *OP_mac_ctx_get_params(void);
+ const OSSL_PARAM *OP_mac_ctx_set_params(void);
+
+ /* MAC parameters */
+ int OP_mac_get_params(OSSL_PARAM params[]);
+ int OP_mac_ctx_get_params(void *mctx, OSSL_PARAM params[]);
+ int OP_mac_ctx_set_params(void *mctx, const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+This documentation is primarily aimed at provider authors. See L<provider(7)>
+for further information.
+
+The MAC operation enables providers to implement mac algorithms and make
+them available to applications via the API functions L<EVP_MAC_init(3)>,
+L<EVP_MACM_update(3)> and L<EVP_MAC_final(3)>.
+
+All "functions" mentioned here are passed as function pointers between
+F<libcrypto> and the provider in B<OSSL_DISPATCH> arrays via
+B<OSSL_ALGORITHM> arrays that are returned by the provider's
+provider_query_operation() function
+(see L<provider-base(7)/Provider Functions>).
+
+All these "functions" have a corresponding function type definition
+named B<OSSL_{name}_fn>, and a helper function to retrieve the
+function pointer from an B<OSSL_DISPATCH> element named
+B<OSSL_get_{name}>.
+For example, the "function" OP_mac_newctx() has these:
+
+ typedef void *(OSSL_OP_mac_newctx_fn)(void *provctx);
+ static ossl_inline OSSL_OP_mac_newctx_fn
+     OSSL_get_OP_mac_newctx(const OSSL_DISPATCH *opf);
+
+B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
+macros in L<openssl-core_numbers.h(7)>, as follows:
+
+ OP_mac_newctx               OSSL_FUNC_MAC_NEWCTX
+ OP_mac_freectx              OSSL_FUNC_MAC_FREECTX
+ OP_mac_dupctx               OSSL_FUNC_MAC_DUPCTX
+
+ OP_mac_init                 OSSL_FUNC_MAC_INIT
+ OP_mac_update               OSSL_FUNC_MAC_UPDATE
+ OP_mac_final                OSSL_FUNC_MAC_FINAL
+
+ OP_mac_get_params           OSSL_FUNC_MAC_GET_PARAMS
+ OP_mac_ctx_get_params       OSSL_FUNC_MAC_CTX_GET_PARAMS
+ OP_mac_ctx_set_params       OSSL_FUNC_MAC_CTX_SET_PARAMS
+
+ OP_mac_gettable_params      OSSL_FUNC_MAC_GETTABLE_PARAMS
+ OP_mac_gettable_ctx_params  OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS
+ OP_mac_settable_ctx_params  OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS
+
+A mac algorithm implementation may not implement all of these functions.
+In order to be a consistent set of functions, at least the following functions
+must be implemented: OP_mac_newctx(), OP_mac_freectx(), OP_mac_init(),
+OP_mac_update(), OP_mac_final().
+All other functions are optional.
+
+=head2 Context Management Functions
+
+OP_mac_newctx() should create and return a pointer to a provider side
+structure for holding context information during a mac operation.
+A pointer to this context will be passed back in a number of the other mac
+operation function calls.
+The paramater I<provctx> is the provider context generated during provider
+initialisation (see L<provider(3)>).
+
+OP_mac_freectx() is passed a pointer to the provider side mac context in
+the I<mctx> parameter.
+If it receives NULL as I<mctx> value, it should not do anything other than
+return.
+This function should free any resources associated with that context.
+
+OP_mac_dupctx() should duplicate the provider side mac context in the
+I<mctx> parameter and return the duplicate copy.
+
+=head2 Encryption/Decryption Functions
+
+OP_mac_init() initialises a mac operation given a newly created provider
+side mac context in the I<mctx> paramter.
+
+OP_mac_update() is called to supply data for MAC computation of a previously
+initialised mac operation.
+The I<mctx> parameter contains a pointer to a previously initialised provider
+side context.
+OP_mac_update() may be called multiple times for a single mac operation.
+
+OP_mac_final() completes the MAC computation started through previous
+OP_mac_init() and OP_mac_update() calls.
+The I<mctx> parameter contains a pointer to the provider side context.
+The resulting MAC should be written to I<out> and the amount of data written
+to I<*outl>, which should not exceed I<outsize> bytes.
+The same expectations apply to I<outsize> as documented for
+L<EVP_MAC_final(3)>.
+
+=head2 Mac Parameters
+
+See L<OSSL_PARAM(3)> for further details on the parameters structure used by
+these functions.
+
+OP_mac_get_params() gets details of parameter values associated with the
+provider algorithm and stores them in I<params>.
+
+OP_mac_ctx_set_params() sets mac parameters associated with the given
+provider side mac context I<mctx> to I<params>.
+Any parameter settings are additional to any that were previously set.
+
+OP_mac_ctx_get_params() gets details of currently set parameter values
+associated with the given provider side mac context I<mctx> and stores them
+in I<params>.
+
+OP_mac_gettable_params(), OP_mac_gettable_ctx_params(), and
+OP_mac_settable_ctx_params() all return constant B<OSSL_PARAM> arrays
+as descriptors of the parameters that OP_mac_get_params(),
+OP_mac_ctx_get_params(), and OP_mac_ctx_set_params() can handle,
+respectively.
+
+Parameters currently recognised by built-in macs are as follows. Not all
+parameters are relevant to, or are understood by all macs:
+
+=over 4
+
+=item B<OSSL_MAC_PARAM_KEY> (octet string)
+
+Sets the key in the associated MAC ctx.
+
+=item B<OSSL_MAC_PARAM_IV> (octet string)
+
+Sets the IV of the underlying cipher, when applicable.
+
+=item B<OSSL_MAC_PARAM_CUSTOM> (utf8 string)
+
+Sets the custom string in the associated MAC ctx.
+
+=item B<OSSL_MAC_PARAM_SALT> (octet string)
+
+Sets the salt of the underlying cipher, when applicable.
+
+=item B<OSSL_MAC_PARAM_BLOCK_XOF> (int)
+
+Sets XOF mode in the associated MAC ctx.
+0 means no XOF mode, 1 means XOF mode.
+
+=item B<OSSL_MAC_PARAM_FLAGS> (int)
+
+Gets flags associated with the MAC.
+
+=for comment We need to investigate if this is the right approach
+
+=item B<OSSL_MAC_PARAM_ALGORITHM> (utf8 string)
+
+Sets the name of the underlying algorithm to be used.
+It must name a suitable algorithm for the MAC that's being used.
+
+=item B<OSSL_MAC_PARAM_MD> (utf8 string)
+
+=item B<OSSL_MAC_PARAM_DIGEST> (utf8 string)
+
+=item B<OSSL_MAC_PARAM_CIPHER> (utf8 string)
+
+These have the same meaning as B<OSSL_MAC_PARAM_ALGORITHM>, but specify
+the expected operation for the underlying algorithm.
+These are regarded as antiquated, but are kept for easier transition from
+legacy MAC implementations.
+
+=item B<OSSL_MAC_PARAM_ENGINE> (utf8 string)
+
+Sets the name of an engine that implements the underlying algorithm.
+This must be given together with the algorithm naming parameter to be
+considered valid.
+
+=item B<OSSL_MAC_PARAM_PROPERTIES> (utf8 string)
+
+Sets the properties to be queried when trying to fetch the underlying algorithm.
+This must be given together with the algorithm naming parameter to be
+considered valid.
+
+Note that both this and B<OSSL_MAC_PARAM_ENGINE> can be given at the same time.
+If the underlying algorithm ends up being fetched from a provider, offered by
+and engine, or a built in legacy function depends on what is available.
+
+=item B<OSSL_MAC_PARAM_SIZE> (int)
+
+=item B<OSSL_MAC_PARAM_DIGESTSIZE> (int)
+
+=item B<OSSL_MAC_PARAM_OUTLEN> (int)
+
+All three names are considered the same.
+B<OSSL_MAC_PARAM_SIZE> and B<OSSL_MAC_PARAM_DIGESTSIZE> are considered
+antiquated, but are kept for easier transition from legacy MAC implementations.
+
+=back
+
+=head1 RETURN VALUES
+
+OP_mac_newctx() and OP_mac_dupctx() should return the newly created
+provider side mac context, or NULL on failure.
+
+OP_mac_init(), OP_mac_update(), OP_mac_final(), OP_mac_get_params(),
+OP_mac_ctx_get_params() and OP_mac_ctx_set_params() should return 1 for
+success or 0 on error.
+
+OP_mac_gettable_params(), OP_mac_gettable_ctx_params() and
+OP_mac_settable_ctx_params() should return a constant B<OSSL_PARAM>
+array, or NULL if none is offered.
+
+=head1 SEE ALSO
+
+L<provider(7)>
+
+=head1 HISTORY
+
+The provider MAC interface was introduced in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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/internal/provider.h b/include/internal/provider.h
index f88beca8c0..a037233a30 100644
--- a/include/internal/provider.h
+++ b/include/internal/provider.h
@@ -63,6 +63,7 @@ const char *ossl_provider_name(const OSSL_PROVIDER *prov);
 const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov);
 const char *ossl_provider_module_name(const OSSL_PROVIDER *prov);
 const char *ossl_provider_module_path(const OSSL_PROVIDER *prov);
+OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov);
 
 /* Thin wrappers around calls to the provider */
 void ossl_provider_teardown(const OSSL_PROVIDER *prov);
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index bf57d15d38..e2d16be964 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -59,6 +59,26 @@ extern "C" {
 #define OSSL_DIGEST_PARAM_SIZE      "size" /* OSSL_PARAM_INTEGER */
 #define OSSL_DIGEST_PARAM_FLAGS     "flags" /* OSSL_PARAM_UNSIGNED_INTEGER */
 
+/* MAC parameters */
+#define OSSL_MAC_PARAM_KEY          "key"       /* octet string */
+#define OSSL_MAC_PARAM_IV           "iv"        /* octet string */
+#define OSSL_MAC_PARAM_CUSTOM       "custom"    /* utf8 string */
+#define OSSL_MAC_PARAM_SALT         "salt"      /* octet string */
+#define OSSL_MAC_PARAM_XOF          "xof"       /* int, 0 or 1 */
+#define OSSL_MAC_PARAM_FLAGS        "flags"     /* int */
+/* Note that "md" and "digest" are equivalent */
+#define OSSL_MAC_PARAM_MD           "md"        /* utf8 string */
+#define OSSL_MAC_PARAM_DIGEST       "digest"    /* utf8 string */
+#define OSSL_MAC_PARAM_CIPHER       "cipher"    /* utf8 string */
+/* Note that "algorithm" can be used instead of "md", "digest" or "cipher" */
+#define OSSL_MAC_PARAM_ALGORITHM    "algorithm" /* utf8 string */
+#define OSSL_MAC_PARAM_ENGINE       "engine"    /* utf8 string */
+#define OSSL_MAC_PARAM_PROPERTIES   "properties" /* utf8 string */
+/* Note that "size", "digestsize" and "outlen" are equivalent */
+#define OSSL_MAC_PARAM_SIZE         "size"      /* size_t */
+#define OSSL_MAC_PARAM_DIGESTSIZE   "digestsize" /* size_t */
+#define OSSL_MAC_PARAM_OUTLEN       "outlen"    /* size_t */
+
 /* PKEY parameters */
 /* Diffie-Hellman Parameters */
 #define OSSL_PKEY_PARAM_DH_P         "dh-p"
diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h
index 2503119f6e..36eeaf67a8 100644
--- a/include/openssl/core_numbers.h
+++ b/include/openssl/core_numbers.h
@@ -230,6 +230,42 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_settable_ctx_params,
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_cipher_gettable_ctx_params,
                     (void))
 
+/* MACs */
+
+# define OSSL_OP_MAC                                 3
+
+# define OSSL_FUNC_MAC_NEWCTX                        1
+# define OSSL_FUNC_MAC_DUPCTX                        2
+# define OSSL_FUNC_MAC_FREECTX                       3
+# define OSSL_FUNC_MAC_INIT                          4
+# define OSSL_FUNC_MAC_UPDATE                        5
+# define OSSL_FUNC_MAC_FINAL                         6
+# define OSSL_FUNC_MAC_GETTABLE_PARAMS               7
+# define OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS           8
+# define OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS           9
+# define OSSL_FUNC_MAC_GET_PARAMS                   10
+# define OSSL_FUNC_MAC_CTX_GET_PARAMS               11
+# define OSSL_FUNC_MAC_CTX_SET_PARAMS               12
+
+OSSL_CORE_MAKE_FUNC(void *, OP_mac_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void *, OP_mac_dupctx, (void *src))
+OSSL_CORE_MAKE_FUNC(void, OP_mac_freectx, (void *mctx))
+OSSL_CORE_MAKE_FUNC(size_t, OP_mac_size, (void *mctx))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_init, (void *mctx))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_update,
+                    (void *mctx, const unsigned char *in, size_t inl))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_final,
+                    (void *mctx,
+                     unsigned char *out, size_t *outl, size_t outsize))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_gettable_params, (void))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_gettable_ctx_params, (void))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_mac_settable_ctx_params, (void))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_get_params, (OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_ctx_get_params,
+                    (void *mctx, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_mac_ctx_set_params,
+                    (void *mctx, const OSSL_PARAM params[]))
+
 /*-
  * Key management
  *
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index accb22f3b1..f8789176d5 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -403,8 +403,8 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
 /* OPENSSL_INIT_BASE_ONLY                    0x00040000L */
 # define OPENSSL_INIT_NO_ATEXIT              0x00080000L
 /* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */
-# define OPENSSL_INIT_NO_ADD_ALL_MACS        0x04000000L
-# define OPENSSL_INIT_ADD_ALL_MACS           0x08000000L
+/* FREE: 0x04000000L */
+/* FREE: 0x08000000L */
 # define OPENSSL_INIT_NO_ADD_ALL_KDFS        0x10000000L
 # define OPENSSL_INIT_ADD_ALL_KDFS           0x20000000L
 /* FREE: 0x40000000L */
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 7fcc4505f5..c778ef43da 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -14,6 +14,7 @@
 
 # include <openssl/opensslconf.h>
 # include <openssl/ossl_typ.h>
+# include <openssl/core.h>
 # include <openssl/symhacks.h>
 # include <openssl/bio.h>
 # include <openssl/evperr.h>
@@ -1025,53 +1026,33 @@ void EVP_MD_do_all_ex(OPENSSL_CTX *libctx,
 
 /* MAC stuff */
 
-# define EVP_MAC_BLAKE2B        NID_blake2bmac
-# define EVP_MAC_BLAKE2S        NID_blake2smac
-# define EVP_MAC_CMAC           NID_cmac
-# define EVP_MAC_GMAC           NID_gmac
-# define EVP_MAC_HMAC           NID_hmac
-# define EVP_MAC_KMAC128        NID_kmac128
-# define EVP_MAC_KMAC256        NID_kmac256
-# define EVP_MAC_SIPHASH        NID_siphash
-# define EVP_MAC_POLY1305       NID_poly1305
-
-EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
-EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);
+EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
+                       const char *properties);
+int EVP_MAC_up_ref(EVP_MAC *mac);
+void EVP_MAC_free(EVP_MAC *mac);
+const char *EVP_MAC_name(const EVP_MAC *mac);
+const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
+int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
+
+EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac);
 void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
 EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src);
-const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
+EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
+int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]);
+int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
+
 size_t EVP_MAC_size(EVP_MAC_CTX *ctx);
 int EVP_MAC_init(EVP_MAC_CTX *ctx);
 int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
-int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen);
-int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...);
-int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args);
-int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value);
-int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
-int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
-int EVP_MAC_nid(const EVP_MAC *mac);
-
-# define EVP_get_macbynid(a)    EVP_get_macbyname(OBJ_nid2sn(a))
-# define EVP_get_macbyobj(a)    EVP_get_macbynid(OBJ_obj2nid(a))
-# define EVP_MAC_name(o)        OBJ_nid2sn(EVP_MAC_nid(o))
-const EVP_MAC *EVP_get_macbyname(const char *name);
-void EVP_MAC_do_all(void (*fn)
-                    (const EVP_MAC *ciph, const char *from, const char *to,
-                     void *x), void *arg);
-void EVP_MAC_do_all_sorted(void (*fn)
-                           (const EVP_MAC *ciph, const char *from,
-                            const char *to, void *x), void *arg);
-
-# define EVP_MAC_CTRL_SET_KEY           0x01 /* unsigned char *, size_t */
-# define EVP_MAC_CTRL_SET_FLAGS         0x02 /* unsigned long */
-# define EVP_MAC_CTRL_SET_ENGINE        0x03 /* ENGINE * */
-# define EVP_MAC_CTRL_SET_MD            0x04 /* EVP_MD * */
-# define EVP_MAC_CTRL_SET_CIPHER        0x05 /* EVP_CIPHER * */
-# define EVP_MAC_CTRL_SET_SIZE          0x06 /* size_t */
-# define EVP_MAC_CTRL_SET_IV            0x07 /* unsigned char *, size_t */
-# define EVP_MAC_CTRL_SET_CUSTOM        0x08 /* unsigned char *, size_t */
-# define EVP_MAC_CTRL_SET_XOF           0x09 /* int */
-# define EVP_MAC_CTRL_SET_SALT          0x0a /* unsigned char *, size_t */
+int EVP_MAC_final(EVP_MAC_CTX *ctx,
+                  unsigned char *out, size_t *outl, size_t outsize);
+const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac);
+const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac);
+const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac);
+
+void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx,
+                       void (*fn)(EVP_MAC *mac, void *arg),
+                       void *arg);
 
 /* PKEY stuff */
 int EVP_PKEY_decrypt_old(unsigned char *dec_key,
diff --git a/providers/common/build.info b/providers/common/build.info
index bc106d0b0f..4c977d3f25 100644
--- a/providers/common/build.info
+++ b/providers/common/build.info
@@ -1,4 +1,4 @@
-SUBDIRS=digests ciphers exchange keymgmt
+SUBDIRS=digests ciphers macs exchange keymgmt
 
 SOURCE[../../libcrypto]=\
         provider_err.c provlib.c
diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c
index a211694a88..32ae19be3f 100644
--- a/providers/common/ciphers/aes.c
+++ b/providers/common/ciphers/aes.c
@@ -59,7 +59,7 @@ static int aes_einit(void *vctx, const unsigned char *key, size_t keylen,
     }
     if (key != NULL) {
         if (keylen != ctx->keylen) {
-            PROVerr(PROV_F_AES_EINIT, PROV_R_INVALID_KEYLEN);
+            PROVerr(PROV_F_AES_EINIT, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
         return ctx->ciph->init(ctx, key, ctx->keylen);
@@ -79,7 +79,7 @@ static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen,
     }
     if (key != NULL) {
         if (keylen != ctx->keylen) {
-            PROVerr(PROV_F_AES_DINIT, PROV_R_INVALID_KEYLEN);
+            PROVerr(PROV_F_AES_DINIT, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
         return ctx->ciph->init(ctx, key, ctx->keylen);
diff --git a/providers/common/ciphers/gcm.c b/providers/common/ciphers/gcm.c
index e3b79f1a94..164c716483 100644
--- a/providers/common/ciphers/gcm.c
+++ b/providers/common/ciphers/gcm.c
@@ -68,7 +68,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
 
     if (iv != NULL) {
         if (ivlen < ctx->ivlen_min || ivlen > sizeof(ctx->iv)) {
-            PROVerr(0, PROV_R_INVALID_IVLEN);
+            PROVerr(0, PROV_R_INVALID_IV_LENGTH);
             return 0;
         }
         ctx->ivlen = ivlen;
@@ -78,7 +78,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
 
     if (key != NULL) {
         if (keylen != ctx->keylen) {
-            PROVerr(0, PROV_R_INVALID_KEYLEN);
+            PROVerr(0, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
         return ctx->hw->setkey(ctx, key, ctx->keylen);
@@ -120,7 +120,7 @@ static int gcm_ctx_get_params(void *vctx, OSSL_PARAM params[])
         if (ctx->iv_gen != 1 && ctx->iv_gen_rand != 1)
             return 0;
         if (ctx->ivlen != (int)p->data_size) {
-            PROVerr(0, PROV_R_INVALID_IVLEN);
+            PROVerr(0, PROV_R_INVALID_IV_LENGTH);
             return 0;
         }
         if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen)) {
@@ -177,7 +177,7 @@ static int gcm_ctx_set_params(void *vctx, const OSSL_PARAM params[])
             return 0;
         }
         if (sz == 0 || sz > sizeof(ctx->iv)) {
-            PROVerr(0, PROV_R_INVALID_IVLEN);
+            PROVerr(0, PROV_R_INVALID_IV_LENGTH);
             return 0;
         }
         ctx->ivlen = sz;
diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h
index 741b07b750..3260d93673 100644
--- a/providers/common/include/internal/provider_algs.h
+++ b/providers/common/include/internal/provider_algs.h
@@ -66,6 +66,17 @@ extern const OSSL_DISPATCH aria192gcm_functions[];
 extern const OSSL_DISPATCH aria128gcm_functions[];
 #endif /* OPENSSL_NO_ARIA */
 
+/* MACs */
+extern const OSSL_DISPATCH blake2bmac_functions[];
+extern const OSSL_DISPATCH blake2smac_functions[];
+extern const OSSL_DISPATCH cmac_functions[];
+extern const OSSL_DISPATCH gmac_functions[];
+extern const OSSL_DISPATCH hmac_functions[];
+extern const OSSL_DISPATCH kmac128_functions[];
+extern const OSSL_DISPATCH kmac256_functions[];
+extern const OSSL_DISPATCH siphash_functions[];
+extern const OSSL_DISPATCH poly1305_functions[];
+
 /* Key management */
 extern const OSSL_DISPATCH dh_keymgmt_functions[];
 
diff --git a/providers/common/include/internal/providercommonerr.h b/providers/common/include/internal/providercommonerr.h
index c52dbd30f8..7c4a175c25 100644
--- a/providers/common/include/internal/providercommonerr.h
+++ b/providers/common/include/internal/providercommonerr.h
@@ -50,9 +50,13 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_FAILED_TO_GET_PARAMETER                   103
 # define PROV_R_FAILED_TO_SET_PARAMETER                   104
 # define PROV_R_INVALID_AAD                               108
-# define PROV_R_INVALID_IVLEN                             109
-# define PROV_R_INVALID_KEYLEN                            105
+# define PROV_R_INVALID_CUSTOM_LENGTH                     111
+# define PROV_R_INVALID_IV_LENGTH                         109
+# define PROV_R_INVALID_KEY_LENGTH                        105
+# define PROV_R_INVALID_SALT_LENGTH                       112
 # define PROV_R_INVALID_TAG                               110
+# define PROV_R_NOT_XOF_OR_INVALID_LENGTH                 113
+# define PROV_R_NO_KEY_SET                                114
 # define PROV_R_OUTPUT_BUFFER_TOO_SMALL                   106
 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH                  107
 
diff --git a/providers/common/macs/build.info b/providers/common/macs/build.info
new file mode 100644
index 0000000000..6bd17291a6
--- /dev/null
+++ b/providers/common/macs/build.info
@@ -0,0 +1,11 @@
+$COMMON=cmac_prov.c gmac_prov.c hmac_prov.c kmac_prov.c
+
+LIBS=../../../libcrypto
+SOURCE[../../../libcrypto]=$COMMON
+INCLUDE[../../../libcrypto]=. ../../../crypto
+
+IF[{- !$disabled{fips} -}]
+  MODULES=../../fips
+  SOURCE[../../fips]=$COMMON
+  INCLUDE[../../fips]=. ../../../crypto
+ENDIF
diff --git a/providers/common/macs/cmac_prov.c b/providers/common/macs/cmac_prov.c
new file mode 100644
index 0000000000..ca42a671ae
--- /dev/null
+++ b/providers/common/macs/cmac_prov.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_CMAC
+
+# include <openssl/core_numbers.h>
+# include <openssl/core_names.h>
+# include <openssl/params.h>
+# include <openssl/engine.h>
+# include <openssl/evp.h>
+# include <openssl/cmac.h>
+
+# include "internal/provider_algs.h"
+# include "internal/provider_ctx.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn cmac_new;
+static OSSL_OP_mac_dupctx_fn cmac_dup;
+static OSSL_OP_mac_freectx_fn cmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn cmac_gettable_ctx_params;
+static OSSL_OP_mac_ctx_get_params_fn cmac_ctx_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn cmac_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn cmac_ctx_set_params;
+static OSSL_OP_mac_init_fn cmac_init;
+static OSSL_OP_mac_update_fn cmac_update;
+static OSSL_OP_mac_final_fn cmac_final;
+
+/* local CMAC data */
+
+struct cmac_data_st {
+    void *provctx;
+    CMAC_CTX *ctx;
+
+    /*
+     * References to the underlying cipher implementation.  tmpcipher
+     * caches the cipher, always.  alloc_cipher only holds a reference
+     * to an explicitly fetched cipher.
+     * tmpcipher is cleared after a CMAC_Init call.
+     */
+    const EVP_CIPHER *tmpcipher; /* cached CMAC cipher */
+    EVP_CIPHER *alloc_cipher;    /* fetched CMAC cipher */
+
+    /*
+     * Conditions for legacy EVP_CIPHER uses.
+     * tmpengine is cleared after a CMAC_Init call.
+     */
+    ENGINE *tmpengine;           /* CMAC cipher engine (legacy) */
+};
+
+static void *cmac_new(void *provctx)
+{
+    struct cmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = CMAC_CTX_new()) == NULL) {
+        OPENSSL_free(macctx);
+        macctx = NULL;
+    }
+    macctx->provctx = provctx;
+
+    return macctx;
+}
+
+static void cmac_free(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        CMAC_CTX_free(macctx->ctx);
+        EVP_CIPHER_meth_free(macctx->alloc_cipher);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *cmac_dup(void *vsrc)
+{
+    struct cmac_data_st *src = vsrc;
+    struct cmac_data_st *dst = cmac_new(src->provctx);
+
+    if (!CMAC_CTX_copy(dst->ctx, src->ctx)) {
+        cmac_free(dst);
+        return NULL;
+    }
+
+    if (src->alloc_cipher != NULL && !EVP_CIPHER_up_ref(src->alloc_cipher)) {
+        cmac_free(dst);
+        return NULL;
+    }
+
+    dst->tmpengine = src->tmpengine;
+    dst->tmpcipher = src->tmpcipher;
+    dst->alloc_cipher = src->alloc_cipher;
+    return dst;
+}
+
+static size_t cmac_size(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(macctx->ctx));
+}
+
+static int cmac_init(void *vmacctx)
+{
+    struct cmac_data_st *macctx = vmacctx;
+    int rv = CMAC_Init(macctx->ctx, NULL, 0, macctx->tmpcipher,
+                       (ENGINE *)macctx->tmpengine);
+
+    macctx->tmpcipher = NULL;
+    macctx->tmpengine = NULL;
+
+    return rv;
+}
+
+static int cmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return CMAC_Update(macctx->ctx, data, datalen);
+}
+
+static int cmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    struct cmac_data_st *macctx = vmacctx;
+
+    return CMAC_Final(macctx->ctx, out, outl);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int cmac_ctx_get_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, cmac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    /* "algorithm" and "cipher" are the same parameter */
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ALGORITHM, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ENGINE, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *cmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int cmac_ctx_set_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct cmac_data_st *macctx = vmacctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CIPHER)) != NULL
+        || ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_ALGORITHM))
+            != NULL)) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+
+        {
+            const char *algoname = p->data;
+            const char *propquery = NULL;
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support engines */
+            ENGINE_finish(macctx->tmpengine);
+            macctx->tmpengine = NULL;
+
+            if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_ENGINE))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                macctx->tmpengine = ENGINE_by_id(p->data);
+                if (macctx->tmpengine == NULL)
+                    return 0;
+            }
+#endif
+            if ((p = OSSL_PARAM_locate_const(params,
+                                             OSSL_MAC_PARAM_PROPERTIES))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                propquery = p->data;
+            }
+
+            EVP_CIPHER_meth_free(macctx->alloc_cipher);
+
+            macctx->tmpcipher = macctx->alloc_cipher =
+                EVP_CIPHER_fetch(PROV_LIBRARY_CONTEXT_OF(macctx->provctx),
+                                 algoname, propquery);
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
+            /* TODO(3.0) BEGIN legacy stuff, to be removed */
+            if (macctx->tmpcipher == NULL)
+                macctx->tmpcipher = EVP_get_cipherbyname(algoname);
+            /* TODO(3.0) END of legacy stuff */
+#endif
+
+            if (macctx->tmpcipher == NULL)
+                return 0;
+        }
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!CMAC_Init(macctx->ctx, p->data, p->data_size,
+                       macctx->tmpcipher, macctx->tmpengine))
+            return 0;
+
+        macctx->tmpcipher = NULL;
+        macctx->tmpengine = NULL;
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH cmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))cmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))cmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))cmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))cmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))cmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))cmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))cmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))cmac_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))cmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))cmac_ctx_set_params },
+    { 0, NULL }
+};
+
+#endif
diff --git a/providers/common/macs/gmac_prov.c b/providers/common/macs/gmac_prov.c
new file mode 100644
index 0000000000..7a29fb3925
--- /dev/null
+++ b/providers/common/macs/gmac_prov.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright 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 <stdlib.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn gmac_new;
+static OSSL_OP_mac_dupctx_fn gmac_dup;
+static OSSL_OP_mac_freectx_fn gmac_free;
+static OSSL_OP_mac_gettable_params_fn gmac_gettable_params;
+static OSSL_OP_mac_get_params_fn gmac_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn gmac_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn gmac_ctx_set_params;
+static OSSL_OP_mac_init_fn gmac_init;
+static OSSL_OP_mac_update_fn gmac_update;
+static OSSL_OP_mac_final_fn gmac_final;
+
+/* local GMAC pkey structure */
+
+struct gmac_data_st {
+    void *provctx;
+    EVP_CIPHER_CTX *ctx;         /* Cipher context */
+
+    /*
+     * References to the underlying cipher implementation.  |cipher| caches
+     * the cipher, always.  |alloc_cipher| only holds a reference to an
+     * explicitly fetched cipher.
+     * |cipher| is cleared after a CMAC_Init call.
+     */
+    const EVP_CIPHER *cipher;    /* Cache GCM cipher */
+    EVP_CIPHER *alloc_cipher;    /* Fetched cipher */
+
+    /*
+     * Conditions for legacy EVP_CIPHER uses.
+     */
+    ENGINE *engine;              /* Engine implementing the algorithm */
+};
+
+static size_t gmac_size(void);
+
+static void gmac_free(void *vmacctx)
+{
+    struct gmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        EVP_CIPHER_CTX_free(macctx->ctx);
+        EVP_CIPHER_meth_free(macctx->alloc_cipher);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *gmac_new(void *provctx)
+{
+    struct gmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
+        gmac_free(macctx);
+        return NULL;
+    }
+    macctx->provctx = provctx;
+
+    return macctx;
+}
+
+static void *gmac_dup(void *vsrc)
+{
+    struct gmac_data_st *src = vsrc;
+    struct gmac_data_st *dst = gmac_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    if (!EVP_CIPHER_CTX_copy(dst->ctx, src->ctx)
+        || (src->alloc_cipher != NULL
+            && !EVP_CIPHER_up_ref(src->alloc_cipher))) {
+        gmac_free(dst);
+        return NULL;
+    }
+
+    dst->cipher = src->cipher;
+    dst->alloc_cipher = src->alloc_cipher;
+    dst->engine = src->engine;
+    return dst;
+}
+
+static int gmac_init(void *vmacctx)
+{
+    return 1;
+}
+
+static int gmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct gmac_data_st *macctx = vmacctx;
+    EVP_CIPHER_CTX *ctx = macctx->ctx;
+    int outlen;
+
+    while (datalen > INT_MAX) {
+        if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
+            return 0;
+        data += INT_MAX;
+        datalen -= INT_MAX;
+    }
+    return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
+}
+
+static int gmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    struct gmac_data_st *macctx = vmacctx;
+    int hlen = 0;
+
+    if (!EVP_EncryptFinal_ex(macctx->ctx, out, &hlen))
+        return 0;
+
+    /* TODO(3.0) Use params */
+    hlen = gmac_size();
+    if (!EVP_CIPHER_CTX_ctrl(macctx->ctx, EVP_CTRL_AEAD_GET_TAG,
+                             hlen, out))
+        return 0;
+
+    *outl = hlen;
+    return 1;
+}
+
+static size_t gmac_size(void)
+{
+    return EVP_GCM_TLS_TAG_LEN;
+}
+
+static const OSSL_PARAM known_gettable_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *gmac_gettable_params(void)
+{
+    return known_gettable_params;
+}
+
+static int gmac_get_params(OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, gmac_size());
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    /* "algorithm" and "cipher" are the same parameter */
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ALGORITHM, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ENGINE, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_IV, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *gmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int gmac_ctx_set_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct gmac_data_st *macctx = vmacctx;
+    EVP_CIPHER_CTX *ctx = macctx->ctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CIPHER)) != NULL
+        || (p = OSSL_PARAM_locate_const(params,
+                                        OSSL_MAC_PARAM_ALGORITHM)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+
+        {
+            const char *algoname = p->data;
+            const char *propquery = NULL;
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support engines */
+            ENGINE_finish(macctx->engine);
+            macctx->engine = NULL;
+
+            if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_ENGINE))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                macctx->engine = ENGINE_by_id(p->data);
+                if (macctx->engine == NULL)
+                    return 0;
+            }
+#endif
+            if ((p = OSSL_PARAM_locate_const(params,
+                                             OSSL_MAC_PARAM_PROPERTIES))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                propquery = p->data;
+            }
+
+            EVP_CIPHER_meth_free(macctx->alloc_cipher);
+            macctx->cipher = macctx->alloc_cipher = NULL;
+
+            macctx->cipher = macctx->alloc_cipher =
+                EVP_CIPHER_fetch(PROV_LIBRARY_CONTEXT_OF(macctx->provctx),
+                                 algoname, propquery);
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy ciphers */
+            /* TODO(3.0) BEGIN legacy stuff, to be removed */
+            if (macctx->cipher == NULL)
+                macctx->cipher = EVP_get_cipherbyname(algoname);
+            /* TODO(3.0) END of legacy stuff */
+#endif
+
+            if (macctx->cipher == NULL)
+                return 0;
+
+            if (EVP_CIPHER_mode(macctx->cipher) != EVP_CIPH_GCM_MODE) {
+                ERR_raise(ERR_LIB_PROV, EVP_R_CIPHER_NOT_GCM_MODE);
+                return 0;
+            }
+        }
+        if (!EVP_EncryptInit_ex(ctx, macctx->cipher, macctx->engine,
+                                NULL, NULL))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (p->data_size != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
+            ERR_raise(ERR_LIB_PROV, EVP_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        if (!EVP_EncryptInit_ex(ctx, NULL, NULL, p->data, NULL))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_IV)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
+                                 p->data_size, NULL)
+            || !EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p->data))
+            return 0;
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH gmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))gmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))gmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))gmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))gmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))gmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))gmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))gmac_gettable_params },
+    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))gmac_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))gmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))gmac_ctx_set_params },
+    { 0, NULL }
+};
diff --git a/providers/common/macs/hmac_prov.c b/providers/common/macs/hmac_prov.c
new file mode 100644
index 0000000000..09d29bec1d
--- /dev/null
+++ b/providers/common/macs/hmac_prov.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright 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 <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn hmac_new;
+static OSSL_OP_mac_dupctx_fn hmac_dup;
+static OSSL_OP_mac_freectx_fn hmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn hmac_gettable_ctx_params;
+static OSSL_OP_mac_ctx_get_params_fn hmac_ctx_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn hmac_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn hmac_ctx_set_params;
+static OSSL_OP_mac_init_fn hmac_init;
+static OSSL_OP_mac_update_fn hmac_update;
+static OSSL_OP_mac_final_fn hmac_final;
+
+/* local HMAC context structure */
+
+/* typedef EVP_MAC_IMPL */
+struct hmac_data_st {
+    void *provctx;
+    HMAC_CTX *ctx;               /* HMAC context */
+
+    /*
+     * References to the underlying digest implementation.  tmpmd caches
+     * the md, always.  alloc_md only holds a reference to an explicitly
+     * fetched digest.
+     * tmpmd is cleared after a CMAC_Init call.
+     */
+    const EVP_MD *tmpmd;         /* HMAC digest */
+    EVP_MD *alloc_md;            /* fetched digest */
+
+    /*
+     * Conditions for legacy EVP_MD uses.
+     * tmpengine is cleared after a CMAC_Init call.
+     */
+    ENGINE *tmpengine;           /* HMAC digest engine */
+};
+
+static size_t hmac_size(void *vmacctx);
+
+static void *hmac_new(void *provctx)
+{
+    struct hmac_data_st *macctx;
+
+    if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
+        || (macctx->ctx = HMAC_CTX_new()) == NULL) {
+        OPENSSL_free(macctx);
+        return NULL;
+    }
+    /* TODO(3.0) Should we do something more with that context? */
+    macctx->provctx = provctx;
+
+    return macctx;
+}
+
+static void hmac_free(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        HMAC_CTX_free(macctx->ctx);
+        EVP_MD_meth_free(macctx->alloc_md);
+        OPENSSL_free(macctx);
+    }
+}
+
+static void *hmac_dup(void *vsrc)
+{
+    struct hmac_data_st *src = vsrc;
+    struct hmac_data_st *dst = hmac_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    if (!HMAC_CTX_copy(dst->ctx, src->ctx)) {
+        hmac_free(dst);
+        return NULL;
+    }
+
+    if (src->alloc_md != NULL && !EVP_MD_up_ref(src->alloc_md)) {
+        hmac_free(dst);
+        return NULL;
+    }
+
+    dst->tmpengine = src->tmpengine;
+    dst->tmpmd = src->tmpmd;
+    dst->alloc_md = src->alloc_md;
+    return dst;
+}
+
+static size_t hmac_size(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    return HMAC_size(macctx->ctx);
+}
+
+static int hmac_init(void *vmacctx)
+{
+    struct hmac_data_st *macctx = vmacctx;
+    int rv = 1;
+
+    /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
+    if (macctx->tmpmd != NULL)
+        rv = HMAC_Init_ex(macctx->ctx, NULL, 0, macctx->tmpmd,
+                          (ENGINE * )macctx->tmpengine);
+    macctx->tmpengine = NULL;
+    macctx->tmpmd = NULL;
+    return rv;
+}
+
+static int hmac_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct hmac_data_st *macctx = vmacctx;
+
+    return HMAC_Update(macctx->ctx, data, datalen);
+}
+
+static int hmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
+{
+    unsigned int hlen;
+    struct hmac_data_st *macctx = vmacctx;
+
+    if (!HMAC_Final(macctx->ctx, out, &hlen))
+        return 0;
+    if (outl != NULL)
+        *outl = hlen;
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *hmac_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int hmac_ctx_get_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, hmac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    /* "algorithm" and "digest" are the same parameter */
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ALGORITHM, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_ENGINE, NULL, 0),
+    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_int(OSSL_MAC_PARAM_FLAGS, NULL),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *hmac_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int hmac_ctx_set_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct hmac_data_st *macctx = vmacctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_DIGEST)) != NULL
+        || (p = OSSL_PARAM_locate_const(params,
+                                        OSSL_MAC_PARAM_ALGORITHM)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+
+        {
+            const char *algoname = p->data;
+            const char *propquery = NULL;
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support engines */
+            ENGINE_finish(macctx->tmpengine);
+            macctx->tmpengine = NULL;
+
+            if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_ENGINE))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                macctx->tmpengine = ENGINE_by_id(p->data);
+                if (macctx->tmpengine == NULL)
+                    return 0;
+            }
+#endif
+            if ((p = OSSL_PARAM_locate_const(params,
+                                             OSSL_MAC_PARAM_PROPERTIES))
+                != NULL) {
+                if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                    return 0;
+
+                propquery = p->data;
+            }
+
+            EVP_MD_meth_free(macctx->alloc_md);
+
+            macctx->tmpmd = macctx->alloc_md =
+                EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(macctx->provctx),
+                             algoname, propquery);
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
+            /* TODO(3.0) BEGIN legacy stuff, to be removed */
+            if (macctx->tmpmd == NULL)
+                macctx->tmpmd = EVP_get_digestbyname(algoname);
+            /* TODO(3.0) END of legacy stuff */
+#endif
+
+            if (macctx->tmpmd == NULL)
+                    return 0;
+        }
+    }
+    /* TODO(3.0) formalize the meaning of "flags", perhaps as other params */
+    if ((p = OSSL_PARAM_locate_const(params,
+                                     OSSL_MAC_PARAM_FLAGS)) != NULL) {
+        int flags = 0;
+
+        if (!OSSL_PARAM_get_int(p, &flags))
+            return 0;
+        HMAC_CTX_set_flags(macctx->ctx, flags);
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+
+        if (!HMAC_Init_ex(macctx->ctx, p->data, p->data_size,
+                          macctx->tmpmd, NULL /* ENGINE */))
+            return 0;
+
+        macctx->tmpmd = NULL;
+        macctx->tmpengine = NULL;
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH hmac_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))hmac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))hmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))hmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))hmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))hmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))hmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))hmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))hmac_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))hmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))hmac_ctx_set_params },
+    { 0, NULL }
+};
diff --git a/crypto/kmac/kmac.c b/providers/common/macs/kmac_prov.c
similarity index 50%
rename from crypto/kmac/kmac.c
rename to providers/common/macs/kmac_prov.c
index 69c334c379..c384cb4e7d 100644
--- a/crypto/kmac/kmac.c
+++ b/providers/common/macs/kmac_prov.c
@@ -47,9 +47,34 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
 #include <openssl/evp.h>
-#include "internal/cryptlib.h"
-#include "internal/evp_int.h"
+#include <openssl/err.h>
+
+#include "internal/providercommonerr.h"
+#include "internal/provider_algs.h"
+#include "internal/provider_ctx.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn kmac128_new;
+static OSSL_OP_mac_newctx_fn kmac256_new;
+static OSSL_OP_mac_dupctx_fn kmac_dup;
+static OSSL_OP_mac_freectx_fn kmac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn kmac_gettable_ctx_params;
+static OSSL_OP_mac_ctx_get_params_fn kmac_ctx_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn kmac_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn kmac_ctx_set_params;
+static OSSL_OP_mac_size_fn kmac_size;
+static OSSL_OP_mac_init_fn kmac_init;
+static OSSL_OP_mac_update_fn kmac_update;
+static OSSL_OP_mac_final_fn kmac_final;
 
 #define KMAC_MAX_BLOCKSIZE ((1600 - 128*2) / 8) /* 168 */
 #define KMAC_MIN_BLOCKSIZE ((1600 - 256*2) / 8) /* 136 */
@@ -85,10 +110,19 @@ static const unsigned char kmac_string[] = {
 
 #define KMAC_FLAG_XOF_MODE          1
 
-/* typedef EVP_MAC_IMPL */
-struct evp_mac_impl_st {
+struct kmac_data_st {
+    void  *provctx;
     EVP_MD_CTX *ctx;
-    const EVP_MD *md;
+
+    /*
+     * References to the underlying keccak_kmac implementation.  |md|
+     * caches the digest, always.  |alloc_md| only holds a reference to an
+     * explicitly fetched digest.
+     * |md| is cleared after a EVP_DigestInit call.
+     */
+    const EVP_MD *md;            /* Cache KMAC digest */
+    EVP_MD *alloc_md;            /* Fetched digest */
+
     size_t out_len;
     int key_len;
     int custom_len;
@@ -109,66 +143,98 @@ static int bytepad(unsigned char *out, int *out_len,
 static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
                                    const unsigned char *in, int in_len,
                                    int w);
-static int kmac_ctrl_str(EVP_MAC_IMPL *kctx, const char *type,
-                         const char *value);
 
-
-static void kmac_free(EVP_MAC_IMPL *kctx)
+static void kmac_free(void *vmacctx)
 {
+    struct kmac_data_st *kctx = vmacctx;
+
     if (kctx != NULL) {
         EVP_MD_CTX_free(kctx->ctx);
+        EVP_MD_meth_free(kctx->alloc_md);
         OPENSSL_cleanse(kctx->key, kctx->key_len);
         OPENSSL_cleanse(kctx->custom, kctx->custom_len);
         OPENSSL_free(kctx);
     }
 }
 
-static EVP_MAC_IMPL *kmac_new(const EVP_MD *md)
+/*
+ * We have KMAC implemented as a hash, which we can use instead of
+ * reimplementing the EVP functionality with direct use of
+ * keccak_mac_init() and friends.
+ */
+static void *kmac_new(void *provctx, EVP_MD *fetched_md, const EVP_MD *md)
 {
-    EVP_MAC_IMPL *kctx = NULL;
+    struct kmac_data_st *kctx = NULL;
+
+    if (md == NULL)
+        return NULL;
 
     if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL
             || (kctx->ctx = EVP_MD_CTX_new()) == NULL) {
         kmac_free(kctx);
         return NULL;
     }
+    kctx->provctx = provctx;
     kctx->md = md;
-    kctx->out_len = md->md_size;
+    kctx->alloc_md = fetched_md;
+    kctx->out_len = EVP_MD_size(md);
     return kctx;
 }
 
-static EVP_MAC_IMPL *kmac128_new(void)
+static void *kmac_fetch_new(void *provctx, const char *mdname)
 {
-    return kmac_new(evp_keccak_kmac128());
+    EVP_MD *fetched_md = EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(provctx),
+                                      mdname, NULL);
+    const EVP_MD *md = fetched_md;
+    void *ret = NULL;
+
+#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
+    /* TODO(3.0) BEGIN legacy stuff, to be removed */
+    if (md == NULL)
+        md = EVP_get_digestbyname(mdname);
+    /* TODO(3.0) END of legacy stuff */
+#endif
+
+    ret = kmac_new(provctx, fetched_md, md);
+    if (ret == NULL)
+        EVP_MD_meth_free(fetched_md);
+    return ret;
 }
 
-static EVP_MAC_IMPL *kmac256_new(void)
+static void *kmac128_new(void *provctx)
 {
-    return kmac_new(evp_keccak_kmac256());
+    return kmac_fetch_new(provctx, "KECCAK_KMAC128");
 }
 
-static EVP_MAC_IMPL *kmac_dup(const EVP_MAC_IMPL *gsrc)
+static void *kmac256_new(void *provctx)
 {
-    EVP_MAC_IMPL *gdst;
+    return kmac_fetch_new(provctx, "KECCAK_KMAC256");
+}
+
+static void *kmac_dup(void *vsrc)
+{
+    struct kmac_data_st *src = vsrc;
+    struct kmac_data_st *dst = kmac_new(src->provctx, src->alloc_md, src->md);
 
-    gdst = kmac_new(gsrc->md);
-    if (gdst == NULL)
+    if (dst == NULL)
         return NULL;
 
-    if (!EVP_MD_CTX_copy(gdst->ctx, gsrc->ctx)) {
-        kmac_free(gdst);
+    if (!EVP_MD_CTX_copy(dst->ctx, src->ctx)
+        || (src->alloc_md != NULL && !EVP_MD_up_ref(src->alloc_md))) {
+        kmac_free(dst);
         return NULL;
     }
 
-    gdst->md = gsrc->md;
-    gdst->out_len = gsrc->out_len;
-    gdst->key_len = gsrc->key_len;
-    gdst->custom_len = gsrc->custom_len;
-    gdst->xof_mode = gsrc->xof_mode;
-    memcpy(gdst->key, gsrc->key, gsrc->key_len);
-    memcpy(gdst->custom, gsrc->custom, gdst->custom_len);
+    dst->md = src->md;
+    dst->alloc_md = src->alloc_md;
+    dst->out_len = src->out_len;
+    dst->key_len = src->key_len;
+    dst->custom_len = src->custom_len;
+    dst->xof_mode = src->xof_mode;
+    memcpy(dst->key, src->key, src->key_len);
+    memcpy(dst->custom, src->custom, dst->custom_len);
 
-    return gdst;
+    return dst;
 }
 
 /*
@@ -176,12 +242,14 @@ static EVP_MAC_IMPL *kmac_dup(const EVP_MAC_IMPL *gsrc)
  * md, key and custom. Setting the fields afterwards will have no
  * effect on the output mac.
  */
-static int kmac_init(EVP_MAC_IMPL *kctx)
+static int kmac_init(void *vmacctx)
 {
+    struct kmac_data_st *kctx = vmacctx;
     EVP_MD_CTX *ctx = kctx->ctx;
     unsigned char out[KMAC_MAX_BLOCKSIZE];
     int out_len, block_len;
 
+
     /* Check key has been set */
     if (kctx->key_len == 0) {
         EVPerr(EVP_F_KMAC_INIT, EVP_R_NO_KEY_SET);
@@ -193,8 +261,13 @@ static int kmac_init(EVP_MAC_IMPL *kctx)
     block_len = EVP_MD_block_size(kctx->md);
 
     /* Set default custom string if it is not already set */
-    if (kctx->custom_len == 0)
-        (void)kmac_ctrl_str(kctx, "custom", "");
+    if (kctx->custom_len == 0) {
+        const OSSL_PARAM params[] = {
+            OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, "", 0),
+            OSSL_PARAM_END
+        };
+        (void)kmac_ctx_set_params(kctx, params);
+    }
 
     return bytepad(out, &out_len, kmac_string, sizeof(kmac_string),
                    kctx->custom, kctx->custom_len, block_len)
@@ -202,120 +275,120 @@ static int kmac_init(EVP_MAC_IMPL *kctx)
            && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
 }
 
-static size_t kmac_size(EVP_MAC_IMPL *kctx)
+static size_t kmac_size(void *vmacctx)
 {
+    struct kmac_data_st *kctx = vmacctx;
+
     return kctx->out_len;
 }
 
-static int kmac_update(EVP_MAC_IMPL *kctx, const unsigned char *data,
+static int kmac_update(void *vmacctx, const unsigned char *data,
                        size_t datalen)
 {
+    struct kmac_data_st *kctx = vmacctx;
+
     return EVP_DigestUpdate(kctx->ctx, data, datalen);
 }
 
-static int kmac_final(EVP_MAC_IMPL *kctx, unsigned char *out)
+static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl,
+                      size_t outsize)
 {
+    struct kmac_data_st *kctx = vmacctx;
     EVP_MD_CTX *ctx = kctx->ctx;
     int lbits, len;
     unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN];
+    int ok;
 
     /* KMAC XOF mode sets the encoded length to 0 */
     lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8));
 
-    return right_encode(encoded_outlen, &len, lbits)
-           && EVP_DigestUpdate(ctx, encoded_outlen, len)
-           && EVP_DigestFinalXOF(ctx, out, kctx->out_len);
+    ok = right_encode(encoded_outlen, &len, lbits)
+        && EVP_DigestUpdate(ctx, encoded_outlen, len)
+        && EVP_DigestFinalXOF(ctx, out, kctx->out_len);
+    if (ok && outl != NULL)
+        *outl = kctx->out_len;
+    return ok;
 }
 
-/*
- * The following Ctrl functions can be set any time before final():
- *     - EVP_MAC_CTRL_SET_SIZE: The requested output length.
- *     - EVP_MAC_CTRL_SET_XOF: If set, this indicates that right_encoded(0) is
- *                             part of the digested data, otherwise it uses
- *                             right_encoded(requested output length).
-
- * All other Ctrl functions should be set before init().
- */
-static int kmac_ctrl(EVP_MAC_IMPL *kctx, int cmd, va_list args)
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_DIGESTSIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *kmac_gettable_ctx_params(void)
 {
-    const unsigned char *p;
-    size_t len;
-    size_t size;
-
-    switch (cmd) {
-    case EVP_MAC_CTRL_SET_XOF:
-        kctx->xof_mode = va_arg(args, int);
-        return 1;
-
-    case EVP_MAC_CTRL_SET_SIZE:
-        size = va_arg(args, size_t);
-        kctx->out_len = size;
-        return 1;
-
-    case EVP_MAC_CTRL_SET_KEY:
-        p = va_arg(args, const unsigned char *);
-        len = va_arg(args, size_t);
-        if (len < 4 || len > KMAC_MAX_KEY) {
-            EVPerr(EVP_F_KMAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
-            return 0;
-        }
-        return kmac_bytepad_encode_key(kctx->key, &kctx->key_len, p, len,
-                                       EVP_MD_block_size(kctx->md));
-
-    case EVP_MAC_CTRL_SET_CUSTOM:
-        p = va_arg(args, const unsigned char *);
-        len = va_arg(args, size_t);
-        if (len > KMAC_MAX_CUSTOM) {
-            EVPerr(EVP_F_KMAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH);
-            return 0;
-        }
-        return encode_string(kctx->custom, &kctx->custom_len, p, len);
-
-    default:
-        return -2;
-    }
+    return known_gettable_ctx_params;
 }
 
-static int kmac_ctrl_int(EVP_MAC_IMPL *kctx, int cmd, ...)
+static int kmac_ctx_get_params(void *vmacctx, OSSL_PARAM params[])
 {
-    int rv;
-    va_list args;
+    OSSL_PARAM *p;
 
-    va_start(args, cmd);
-    rv = kmac_ctrl(kctx, cmd, args);
-    va_end(args);
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_DIGESTSIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, kmac_size(vmacctx));
 
-    return rv;
+    return 1;
 }
 
-static int kmac_ctrl_str_cb(void *kctx, int cmd, void *buf, size_t buflen)
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_int(OSSL_MAC_PARAM_XOF, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *kmac_settable_ctx_params(void)
 {
-    return kmac_ctrl_int(kctx, cmd, buf, buflen);
+    return known_settable_ctx_params;
 }
 
-static int kmac_ctrl_str(EVP_MAC_IMPL *kctx, const char *type,
-                         const char *value)
+/*
+ * The following params can be set any time before final():
+ *     - "outlen" or "size":    The requested output length.
+ *     - "xof":                 If set, this indicates that right_encoded(0)
+ *                              is part of the digested data, otherwise it
+ *                              uses right_encoded(requested output length).
+ *
+ * All other params should be set before init().
+ */
+static int kmac_ctx_set_params(void *vmacctx, const OSSL_PARAM *params)
 {
-    if (value == NULL)
-        return 0;
+    struct kmac_data_st *kctx = vmacctx;
+    const OSSL_PARAM *p;
 
-    if (strcmp(type, "outlen") == 0)
-        return kmac_ctrl_int(kctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value));
-    if (strcmp(type, "xof") == 0)
-        return kmac_ctrl_int(kctx, EVP_MAC_CTRL_SET_XOF, atoi(value));
-    if (strcmp(type, "key") == 0)
-        return EVP_str2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "hexkey") == 0)
-        return EVP_hex2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_KEY,
-                            value);
-    if (strcmp(type, "custom") == 0)
-        return EVP_str2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    if (strcmp(type, "hexcustom") == 0)
-        return EVP_hex2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_CUSTOM,
-                            value);
-    return -2;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_XOF)) != NULL
+        && !OSSL_PARAM_get_int(p, &kctx->xof_mode))
+        return 0;
+    if (((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+         ||
+         (p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        && !OSSL_PARAM_get_size_t(p, &kctx->out_len))
+        return 0;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_size < 4 || p->data_size > KMAC_MAX_KEY) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        if (!kmac_bytepad_encode_key(kctx->key, &kctx->key_len,
+                                     p->data, p->data_size,
+                                     EVP_MD_block_size(kctx->md)))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
+        != NULL) {
+        if (p->data_size > KMAC_MAX_CUSTOM) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
+            return 0;
+        }
+        if (!encode_string(kctx->custom, &kctx->custom_len,
+                           p->data, p->data_size))
+            return 0;
+    }
+    return 1;
 }
 
 /*
@@ -452,29 +525,34 @@ static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
     return bytepad(out, out_len, tmp, tmp_len, NULL, 0, w);
 }
 
-const EVP_MAC kmac128_meth = {
-    EVP_MAC_KMAC128,
-    kmac128_new,
-    kmac_dup,
-    kmac_free,
-    kmac_size,
-    kmac_init,
-    kmac_update,
-    kmac_final,
-    kmac_ctrl,
-    kmac_ctrl_str
+const OSSL_DISPATCH kmac128_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac128_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))kmac_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))kmac_ctx_set_params },
+    { 0, NULL }
 };
 
-const EVP_MAC kmac256_meth = {
-    EVP_MAC_KMAC256,
-    kmac256_new,
-    kmac_dup,
-    kmac_free,
-    kmac_size,
-    kmac_init,
-    kmac_update,
-    kmac_final,
-    kmac_ctrl,
-    kmac_ctrl_str
+const OSSL_DISPATCH kmac256_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac256_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))kmac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))kmac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))kmac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))kmac_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))kmac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))kmac_ctx_set_params },
+    { 0, NULL }
 };
-
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 7f07625a59..b7f90057d4 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -24,9 +24,16 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
     "failed to set parameter"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"},
-    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IVLEN), "invalid ivlen"},
-    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEYLEN), "invalid keylen"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CUSTOM_LENGTH),
+    "invalid custom length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IV_LENGTH), "invalid iv length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH), "invalid key length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
+    "invalid salt length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH),
+    "not xof or invalid length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL),
     "output buffer too small"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH),
diff --git a/providers/default/build.info b/providers/default/build.info
index 985d681b05..dd133388fc 100644
--- a/providers/default/build.info
+++ b/providers/default/build.info
@@ -1,4 +1,5 @@
-SUBDIRS=digests
+SUBDIRS=digests macs
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
         defltprov.c
+INCLUDE[../../libcrypto]=include
diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c
index 2a0893e038..535c05252a 100644
--- a/providers/default/defltprov.c
+++ b/providers/default/defltprov.c
@@ -9,6 +9,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <openssl/opensslconf.h>
 #include <openssl/core.h>
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
@@ -64,8 +65,12 @@ static const OSSL_ALGORITHM deflt_digests[] = {
     { "SHA3-384", "default=yes", sha3_384_functions },
     { "SHA3-512", "default=yes", sha3_512_functions },
 
-    { "KMAC128", "default=yes", keccak_kmac_128_functions },
-    { "KMAC256", "default=yes", keccak_kmac_256_functions },
+    /*
+     * KECCAK_KMAC128 and KECCAK_KMAC256 as hashes are mostly useful for
+     * the KMAC128 and KMAC256.
+     */
+    { "KECCAK_KMAC128", "default=yes", keccak_kmac_128_functions },
+    { "KECCAK_KMAC256", "default=yes", keccak_kmac_256_functions },
 
     { "SHAKE128", "default=yes", shake_128_functions },
     { "SHAKE256", "default=yes", shake_256_functions },
@@ -122,6 +127,27 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { NULL, NULL, NULL }
 };
 
+static const OSSL_ALGORITHM deflt_macs[] = {
+#ifndef OPENSSL_NO_BLAKE2
+    { "BLAKE2BMAC", "default=yes", blake2bmac_functions },
+    { "BLAKE2SMAC", "default=yes", blake2smac_functions },
+#endif
+#ifndef OPENSSL_NO_CMAC
+    { "CMAC", "default=yes", cmac_functions },
+#endif
+    { "GMAC", "default=yes", gmac_functions },
+    { "HMAC", "default=yes", hmac_functions },
+    { "KMAC128", "default=yes", kmac128_functions },
+    { "KMAC256", "default=yes", kmac256_functions },
+#ifndef OPENSSL_NO_SIPHASH
+    { "SipHash", "default=yes", siphash_functions },
+#endif
+#ifndef OPENSSL_NO_POLY1305
+    { "Poly1305", "default=yes", poly1305_functions },
+#endif
+    { NULL, NULL, NULL }
+};
+
 static const OSSL_ALGORITHM deflt_keyexch[] = {
 #ifndef OPENSSL_NO_DH
     { "dhKeyAgreement", "default=yes", dh_keyexch_functions },
@@ -146,6 +172,8 @@ static const OSSL_ALGORITHM *deflt_query(OSSL_PROVIDER *prov,
         return deflt_digests;
     case OSSL_OP_CIPHER:
         return deflt_ciphers;
+    case OSSL_OP_MAC:
+        return deflt_macs;
     case OSSL_OP_KEYMGMT:
         return deflt_keymgmt;
     case OSSL_OP_KEYEXCH:
diff --git a/include/internal/blake2.h b/providers/default/include/internal/blake2.h
similarity index 100%
rename from include/internal/blake2.h
rename to providers/default/include/internal/blake2.h
diff --git a/providers/default/macs/blake2_mac_impl.c b/providers/default/macs/blake2_mac_impl.c
new file mode 100644
index 0000000000..67643e8a6c
--- /dev/null
+++ b/providers/default/macs/blake2_mac_impl.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_BLAKE2
+
+# include <openssl/core_numbers.h>
+# include <openssl/core_names.h>
+# include <openssl/params.h>
+
+# include "internal/blake2.h"
+# include "internal/cryptlib.h"
+# include "internal/providercommonerr.h"
+# include "internal/provider_algs.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn blake2_mac_new;
+static OSSL_OP_mac_dupctx_fn blake2_mac_dup;
+static OSSL_OP_mac_freectx_fn blake2_mac_free;
+static OSSL_OP_mac_gettable_ctx_params_fn blake2_gettable_ctx_params;
+static OSSL_OP_mac_ctx_get_params_fn blake2_ctx_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn blake2_mac_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn blake2_mac_ctx_set_params;
+static OSSL_OP_mac_init_fn blake2_mac_init;
+static OSSL_OP_mac_update_fn blake2_mac_update;
+static OSSL_OP_mac_final_fn blake2_mac_final;
+
+struct blake2_mac_data_st {
+    BLAKE2_CTX ctx;
+    BLAKE2_PARAM params;
+    unsigned char key[BLAKE2_KEYBYTES];
+};
+
+static size_t blake2_mac_size(void *vmacctx);
+
+static void *blake2_mac_new(void *unused_provctx)
+{
+    struct blake2_mac_data_st *macctx = OPENSSL_zalloc(sizeof(*macctx));
+
+    if (macctx != NULL) {
+        BLAKE2_PARAM_INIT(&macctx->params);
+        /* ctx initialization is deferred to BLAKE2b_Init() */
+    }
+    return macctx;
+}
+
+static void *blake2_mac_dup(void *vsrc)
+{
+    struct blake2_mac_data_st *dst;
+    struct blake2_mac_data_st *src = vsrc;
+
+    dst = OPENSSL_zalloc(sizeof(*dst));
+    if (dst == NULL)
+        return NULL;
+
+    *dst = *src;
+    return dst;
+}
+
+static void blake2_mac_free(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    if (macctx != NULL) {
+        OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
+        OPENSSL_free(macctx);
+    }
+}
+
+static int blake2_mac_init(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    /* Check key has been set */
+    if (macctx->params.key_length == 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
+
+    return BLAKE2_INIT_KEY(&macctx->ctx, &macctx->params, macctx->key);
+}
+
+static int blake2_mac_update(void *vmacctx,
+                             const unsigned char *data, size_t datalen)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return BLAKE2_UPDATE(&macctx->ctx, data, datalen);
+}
+
+static int blake2_mac_final(void *vmacctx,
+                            unsigned char *out, size_t *outl,
+                            size_t outsize)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return BLAKE2_FINAL(out, &macctx->ctx);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *blake2_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int blake2_ctx_get_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, blake2_mac_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *blake2_mac_settable_ctx_params()
+{
+    return known_settable_ctx_params;
+}
+
+/*
+ * ALL parameters should be set before init().
+ */
+static int blake2_mac_ctx_set_params(void *vmacctx, const OSSL_PARAM params[])
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        ||
+        (p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
+        size_t size;
+
+        if (!OSSL_PARAM_get_size_t(p, &size)
+            || size < 1
+            || size > BLAKE2_OUTBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_DIGEST_LENGTH(&macctx->params, (uint8_t)size);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        size_t len;
+        void *key_p = macctx->key;
+
+        if (!OSSL_PARAM_get_octet_string(p, &key_p, BLAKE2_KEYBYTES, &len)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        /* Pad with zeroes at the end */
+        memset(macctx->key + len, 0, BLAKE2_KEYBYTES - len);
+
+        BLAKE2_PARAM_SET_KEY_LENGTH(&macctx->params, (uint8_t)len);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
+        != NULL) {
+        /*
+         * The OSSL_PARAM API doesn't provide direct pointer use, so we
+         * must handle the OSSL_PARAM structure ourselves here
+         */
+        if (p->data_size > BLAKE2_PERSONALBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_PERSONAL(&macctx->params, p->data, p->data_size);
+    }
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SALT)) != NULL) {
+        /*
+         * The OSSL_PARAM API doesn't provide direct pointer use, so we
+         * must handle the OSSL_PARAM structure ourselves here as well
+         */
+        if (p->data_size > BLAKE2_SALTBYTES) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
+            return 0;
+        }
+        BLAKE2_PARAM_SET_SALT(&macctx->params, p->data, p->data_size);
+    }
+    return 1;
+}
+
+static size_t blake2_mac_size(void *vmacctx)
+{
+    struct blake2_mac_data_st *macctx = vmacctx;
+
+    return macctx->params.digest_length;
+}
+
+const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))blake2_mac_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))blake2_mac_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))blake2_mac_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))blake2_mac_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))blake2_mac_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))blake2_mac_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))blake2_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))blake2_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))blake2_mac_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))blake2_mac_ctx_set_params },
+    { 0, NULL }
+};
+
+#endif
diff --git a/providers/default/macs/blake2b_mac.c b/providers/default/macs/blake2b_mac.c
new file mode 100644
index 0000000000..c020d2e106
--- /dev/null
+++ b/providers/default/macs/blake2b_mac.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_BLAKE2
+
+/* Constants */
+# define BLAKE2_CTX BLAKE2B_CTX
+# define BLAKE2_PARAM BLAKE2B_PARAM
+# define BLAKE2_KEYBYTES BLAKE2B_KEYBYTES
+# define BLAKE2_OUTBYTES BLAKE2B_OUTBYTES
+# define BLAKE2_PERSONALBYTES BLAKE2B_PERSONALBYTES
+# define BLAKE2_SALTBYTES BLAKE2B_SALTBYTES
+
+/* Function names */
+# define BLAKE2_PARAM_INIT blake2b_param_init
+# define BLAKE2_INIT_KEY blake2b_init_key
+# define BLAKE2_UPDATE blake2b_update
+# define BLAKE2_FINAL blake2b_final
+# define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2b_param_set_digest_length
+# define BLAKE2_PARAM_SET_KEY_LENGTH blake2b_param_set_key_length
+# define BLAKE2_PARAM_SET_PERSONAL blake2b_param_set_personal
+# define BLAKE2_PARAM_SET_SALT blake2b_param_set_salt
+
+/* OSSL_DISPATCH symbol */
+# define BLAKE2_FUNCTIONS blake2bmac_functions
+
+# include "blake2_mac_impl.c"
+
+#endif
diff --git a/providers/default/macs/blake2s_mac.c b/providers/default/macs/blake2s_mac.c
new file mode 100644
index 0000000000..67a68cfa8a
--- /dev/null
+++ b/providers/default/macs/blake2s_mac.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_BLAKE2
+
+/* Constants */
+# define BLAKE2_CTX BLAKE2S_CTX
+# define BLAKE2_PARAM BLAKE2S_PARAM
+# define BLAKE2_KEYBYTES BLAKE2S_KEYBYTES
+# define BLAKE2_OUTBYTES BLAKE2S_OUTBYTES
+# define BLAKE2_PERSONALBYTES BLAKE2S_PERSONALBYTES
+# define BLAKE2_SALTBYTES BLAKE2S_SALTBYTES
+
+/* Function names */
+# define BLAKE2_PARAM_INIT blake2s_param_init
+# define BLAKE2_INIT_KEY blake2s_init_key
+# define BLAKE2_UPDATE blake2s_update
+# define BLAKE2_FINAL blake2s_final
+# define BLAKE2_PARAM_SET_DIGEST_LENGTH blake2s_param_set_digest_length
+# define BLAKE2_PARAM_SET_KEY_LENGTH blake2s_param_set_key_length
+# define BLAKE2_PARAM_SET_PERSONAL blake2s_param_set_personal
+# define BLAKE2_PARAM_SET_SALT blake2s_param_set_salt
+
+/* OSSL_DISPATCH symbol */
+# define BLAKE2_FUNCTIONS blake2smac_functions
+
+# include "blake2_mac_impl.c"
+
+#endif
diff --git a/providers/default/macs/build.info b/providers/default/macs/build.info
new file mode 100644
index 0000000000..d7014e1009
--- /dev/null
+++ b/providers/default/macs/build.info
@@ -0,0 +1,4 @@
+LIBS=../../../libcrypto
+SOURCE[../../../libcrypto]=\
+        blake2b_mac.c blake2s_mac.c siphash_prov.c poly1305_prov.c
+INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/default/macs/poly1305_prov.c b/providers/default/macs/poly1305_prov.c
new file mode 100644
index 0000000000..c64c2b9e9a
--- /dev/null
+++ b/providers/default/macs/poly1305_prov.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_POLY1305
+
+# include <openssl/core_numbers.h>
+# include <openssl/core_names.h>
+# include <openssl/params.h>
+# include <openssl/evp.h>
+# include <openssl/err.h>
+
+# include "internal/poly1305.h"
+/*
+ * TODO(3.0) when poly1305 has moved entirely to our providers, this
+ * header should be moved to the provider include directory.  For the
+ * moment, crypto/poly1305/poly1305_ameth.c has us stuck.
+ */
+# include "../../../crypto/poly1305/poly1305_local.h"
+
+# include "internal/providercommonerr.h"
+# include "internal/provider_algs.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn poly1305_new;
+static OSSL_OP_mac_dupctx_fn poly1305_dup;
+static OSSL_OP_mac_freectx_fn poly1305_free;
+static OSSL_OP_mac_gettable_params_fn poly1305_gettable_params;
+static OSSL_OP_mac_get_params_fn poly1305_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn poly1305_settable_ctx_params;
+static OSSL_OP_mac_ctx_set_params_fn poly1305_ctx_set_params;
+static OSSL_OP_mac_init_fn poly1305_init;
+static OSSL_OP_mac_update_fn poly1305_update;
+static OSSL_OP_mac_final_fn poly1305_final;
+
+struct poly1305_data_st {
+    void *provctx;
+    POLY1305 poly1305;           /* Poly1305 data */
+};
+
+static size_t poly1305_size(void);
+
+static void *poly1305_new(void *provctx)
+{
+    struct poly1305_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void poly1305_free(void *vmacctx)
+{
+    OPENSSL_free(vmacctx);
+}
+
+static void *poly1305_dup(void *vsrc)
+{
+    struct poly1305_data_st *src = vsrc;
+    struct poly1305_data_st *dst = poly1305_new(src->provctx);
+
+    if (dst == NULL)
+        return NULL;
+
+    dst->poly1305 = src->poly1305;
+    return dst;
+}
+
+static size_t poly1305_size(void)
+{
+    return POLY1305_DIGEST_SIZE;
+}
+
+static int poly1305_init(void *vmacctx)
+{
+    /* initialize the context in MAC_ctrl function */
+    return 1;
+}
+
+static int poly1305_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+
+    /* poly1305 has nothing to return in its update function */
+    Poly1305_Update(&ctx->poly1305, data, datalen);
+    return 1;
+}
+
+static int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl,
+                          size_t outsize)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+
+    Poly1305_Final(&ctx->poly1305, out);
+    return 1;
+}
+
+static const OSSL_PARAM known_gettable_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *poly1305_gettable_params(void)
+{
+    return known_gettable_params;
+}
+
+static int poly1305_get_params(OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, poly1305_size());
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *poly1305_settable_ctx_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+static int poly1305_ctx_set_params(void *vmacctx, const OSSL_PARAM *params)
+{
+    struct poly1305_data_st *ctx = vmacctx;
+    const OSSL_PARAM *p = NULL;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING
+            || p->data_size != POLY1305_KEY_SIZE) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        Poly1305_Init(&ctx->poly1305, p->data);
+    }
+    return 1;
+}
+
+const OSSL_DISPATCH poly1305_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))poly1305_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))poly1305_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))poly1305_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))poly1305_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))poly1305_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))poly1305_final },
+    { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))poly1305_gettable_params },
+    { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))poly1305_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))poly1305_settable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))poly1305_ctx_set_params },
+    { 0, NULL }
+};
+
+#endif
diff --git a/providers/default/macs/siphash_prov.c b/providers/default/macs/siphash_prov.c
new file mode 100644
index 0000000000..f02834f082
--- /dev/null
+++ b/providers/default/macs/siphash_prov.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright 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 <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_SIPHASH
+
+# include <string.h>
+# include <openssl/core_numbers.h>
+# include <openssl/core_names.h>
+# include <openssl/params.h>
+# include <openssl/evp.h>
+# include <openssl/err.h>
+
+# include "internal/siphash.h"
+/*
+ * TODO(3.0) when siphash has moved entirely to our providers, this
+ * header should be moved to the provider include directory.  For the
+ * moment, crypto/siphash/siphash_ameth.c has us stuck.
+ */
+# include "../../../crypto/siphash/siphash_local.h"
+
+# include "internal/providercommonerr.h"
+# include "internal/provider_algs.h"
+
+/*
+ * Forward declaration of everything implemented here.  This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_mac_newctx_fn siphash_new;
+static OSSL_OP_mac_dupctx_fn siphash_dup;
+static OSSL_OP_mac_freectx_fn siphash_free;
+static OSSL_OP_mac_gettable_ctx_params_fn siphash_gettable_ctx_params;
+static OSSL_OP_mac_ctx_get_params_fn siphash_ctx_get_params;
+static OSSL_OP_mac_settable_ctx_params_fn siphash_settable_params;
+static OSSL_OP_mac_ctx_set_params_fn siphash_set_params;
+static OSSL_OP_mac_size_fn siphash_size;
+static OSSL_OP_mac_init_fn siphash_init;
+static OSSL_OP_mac_update_fn siphash_update;
+static OSSL_OP_mac_final_fn siphash_final;
+
+struct siphash_data_st {
+    void *provctx;
+    SIPHASH siphash;             /* Siphash data */
+};
+
+static void *siphash_new(void *provctx)
+{
+    struct siphash_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    ctx->provctx = provctx;
+    return ctx;
+}
+
+static void siphash_free(void *vmacctx)
+{
+    OPENSSL_free(vmacctx);
+}
+
+static void *siphash_dup(void *vsrc)
+{
+    struct siphash_data_st *ssrc = vsrc;
+    struct siphash_data_st *sdst = siphash_new(ssrc->provctx);
+
+    if (sdst == NULL)
+        return NULL;
+
+    sdst->siphash = ssrc->siphash;
+    return sdst;
+}
+
+static size_t siphash_size(void *vmacctx)
+{
+    struct siphash_data_st *ctx = vmacctx;
+
+    return SipHash_hash_size(&ctx->siphash);
+}
+
+static int siphash_init(void *vmacctx)
+{
+    /* Not much to do here, actual initialization happens through controls */
+    return 1;
+}
+
+static int siphash_update(void *vmacctx, const unsigned char *data,
+                       size_t datalen)
+{
+    struct siphash_data_st *ctx = vmacctx;
+
+    SipHash_Update(&ctx->siphash, data, datalen);
+    return 1;
+}
+
+static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl,
+                         size_t outsize)
+{
+    struct siphash_data_st *ctx = vmacctx;
+    size_t hlen = siphash_size(ctx);
+
+    if (outsize < hlen)
+        return 0;
+
+    *outl = hlen;
+    return SipHash_Final(&ctx->siphash, out, hlen);
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_DIGESTSIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *siphash_gettable_ctx_params(void)
+{
+    return known_gettable_ctx_params;
+}
+
+static int siphash_ctx_get_params(void *vmacctx, OSSL_PARAM params[])
+{
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL
+        || (p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_DIGESTSIZE)) != NULL)
+        return OSSL_PARAM_set_size_t(p, siphash_size(vmacctx));
+
+    return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_OUTLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_size_t(OSSL_MAC_PARAM_DIGESTSIZE, NULL), /* Same as "outlen" */
+    OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *siphash_settable_params(void)
+{
+    return known_settable_ctx_params;
+}
+
+static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params)
+{
+    struct siphash_data_st *ctx = vmacctx;
+    const OSSL_PARAM *p = NULL;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_OUTLEN)) != NULL
+        || ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_DIGESTSIZE))
+            != NULL)
+        || ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE))
+            != NULL)) {
+        size_t size;
+
+        if (!OSSL_PARAM_get_size_t(p, &size)
+            || !SipHash_set_hash_size(&ctx->siphash, size))
+            return 0;
+    }
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
+        if (p->data_type != OSSL_PARAM_OCTET_STRING
+            || p->data_size != SIPHASH_KEY_SIZE
+            || !SipHash_Init(&ctx->siphash, p->data, 0, 0))
+            return 0;
+    return 1;
+}
+
+const OSSL_DISPATCH siphash_functions[] = {
+    { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new },
+    { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup },
+    { OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free },
+    { OSSL_FUNC_MAC_INIT, (void (*)(void))siphash_init },
+    { OSSL_FUNC_MAC_UPDATE, (void (*)(void))siphash_update },
+    { OSSL_FUNC_MAC_FINAL, (void (*)(void))siphash_final },
+    { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+      (void (*)(void))siphash_gettable_ctx_params },
+    { OSSL_FUNC_MAC_CTX_GET_PARAMS, (void (*)(void))siphash_ctx_get_params },
+    { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+      (void (*)(void))siphash_settable_params },
+    { OSSL_FUNC_MAC_CTX_SET_PARAMS, (void (*)(void))siphash_set_params },
+    { 0, NULL }
+};
+
+#endif
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index a59ebce239..d2d3e6044a 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -252,8 +252,12 @@ static const OSSL_ALGORITHM fips_digests[] = {
     { "SHA3-256", "fips=yes", sha3_256_functions },
     { "SHA3-384", "fips=yes", sha3_384_functions },
     { "SHA3-512", "fips=yes", sha3_512_functions },
-    { "KMAC128", "fips=yes", keccak_kmac_128_functions },
-    { "KMAC256", "fips=yes", keccak_kmac_256_functions },
+    /*
+     * KECCAK_KMAC128 and KECCAK_KMAC256 as hashes are mostly useful for
+     * the KMAC128 and KMAC256.
+     */
+    { "KECCAK_KMAC128", "fips=yes", keccak_kmac_128_functions },
+    { "KECCAK_KMAC256", "fips=yes", keccak_kmac_256_functions },
 
     { NULL, NULL, NULL }
 };
@@ -274,6 +278,15 @@ static const OSSL_ALGORITHM fips_ciphers[] = {
     { NULL, NULL, NULL }
 };
 
+static const OSSL_ALGORITHM fips_macs[] = {
+    { "CMAC", "fips=yes", cmac_functions },
+    { "GMAC", "fips=yes", gmac_functions },
+    { "HMAC", "fips=yes", hmac_functions },
+    { "KMAC128", "fips=yes", kmac128_functions },
+    { "KMAC256", "fips=yes", kmac256_functions },
+    { NULL, NULL, NULL }
+};
+
 static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
                                          int operation_id,
                                          int *no_cache)
@@ -284,6 +297,8 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
         return fips_digests;
     case OSSL_OP_CIPHER:
         return fips_ciphers;
+    case OSSL_OP_MAC:
+        return fips_macs;
     }
     return NULL;
 }
diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c
index 0451d19046..86296136d6 100644
--- a/ssl/ssl_init.c
+++ b/ssl/ssl_init.c
@@ -181,8 +181,7 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
     }
 
     opts |= OPENSSL_INIT_ADD_ALL_CIPHERS
-         |  OPENSSL_INIT_ADD_ALL_DIGESTS
-         |  OPENSSL_INIT_ADD_ALL_MACS;
+         |  OPENSSL_INIT_ADD_ALL_DIGESTS;
 #ifndef OPENSSL_NO_AUTOLOAD_CONFIG
     if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) == 0)
         opts |= OPENSSL_INIT_LOAD_CONFIG;
diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c
index e7c1381a6a..b3d1648c0d 100644
--- a/test/evp_kdf_test.c
+++ b/test/evp_kdf_test.c
@@ -260,7 +260,6 @@ static int test_kdf_ss_hmac(void)
 {
     int ret;
     EVP_KDF_CTX *kctx;
-    const EVP_MAC *mac;
     unsigned char out[16];
     static const unsigned char z[] = {
         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
@@ -279,8 +278,7 @@ static int test_kdf_ss_hmac(void)
 
     ret =
         TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS))
-        && TEST_ptr(mac = EVP_get_macbyname("HMAC"))
-        && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, mac), 0)
+        && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, "HMAC"), 0)
         && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD,  EVP_sha256()), 0)
         && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)), 0)
         && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
@@ -299,7 +297,6 @@ static int test_kdf_ss_kmac(void)
     int ret;
     EVP_KDF_CTX *kctx;
     unsigned char out[64];
-    const EVP_MAC *mac;
     static const unsigned char z[] = {
         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
     };
@@ -320,8 +317,7 @@ static int test_kdf_ss_kmac(void)
 
     ret =
         TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS))
-        && TEST_ptr(mac = EVP_get_macbyname("KMAC128"))
-        && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, mac), 0)
+        && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, "KMAC128"), 0)
         && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z,
                                     sizeof(z)), 0)
         && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
diff --git a/test/evp_test.c b/test/evp_test.c
index 2ae2c023a2..029738f296 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -18,7 +18,10 @@
 #include <openssl/x509v3.h>
 #include <openssl/pkcs12.h>
 #include <openssl/kdf.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
 #include "internal/numbers.h"
+#include "internal/nelem.h"
 #include "testutil.h"
 #include "evp_test.h"
 
@@ -865,7 +868,7 @@ static const EVP_TEST_METHOD cipher_test_method = {
 
 typedef struct mac_data_st {
     /* MAC type in one form or another */
-    const EVP_MAC *mac;          /* for mac_test_run_mac */
+    EVP_MAC *mac;                /* for mac_test_run_mac */
     int type;                    /* for mac_test_run_pkey */
     /* Algorithm string for this MAC */
     char *alg;
@@ -892,11 +895,11 @@ typedef struct mac_data_st {
 
 static int mac_test_init(EVP_TEST *t, const char *alg)
 {
-    const EVP_MAC *mac = NULL;
+    EVP_MAC *mac = NULL;
     int type = NID_undef;
     MAC_DATA *mdat;
 
-    if ((mac = EVP_get_macbyname(alg)) == NULL) {
+    if ((mac = EVP_MAC_fetch(NULL, alg, NULL)) == NULL) {
         /*
          * Since we didn't find an EVP_MAC, we check for known EVP_PKEY methods
          * For debugging purposes, we allow 'NNNN by EVP_PKEY' to force running
@@ -964,6 +967,7 @@ static void mac_test_cleanup(EVP_TEST *t)
 {
     MAC_DATA *mdat = t->data;
 
+    EVP_MAC_free(mdat->mac);
     sk_OPENSSL_STRING_pop_free(mdat->controls, openssl_free);
     OPENSSL_free(mdat->alg);
     OPENSSL_free(mdat->key);
@@ -1114,11 +1118,14 @@ static int mac_test_run_mac(EVP_TEST *t)
 {
     MAC_DATA *expected = t->data;
     EVP_MAC_CTX *ctx = NULL;
-    const void *algo = NULL;
-    int algo_ctrl = 0;
     unsigned char *got = NULL;
     size_t got_len;
-    int rv, i;
+    int i;
+    OSSL_PARAM params[21];
+    size_t params_n = 0;
+    size_t params_n_allocstart = 0;
+    const OSSL_PARAM *defined_params =
+        EVP_MAC_CTX_settable_params(expected->mac);
 
     if (expected->alg == NULL)
         TEST_info("Trying the EVP_MAC %s test", EVP_MAC_name(expected->mac));
@@ -1134,97 +1141,74 @@ static int mac_test_run_mac(EVP_TEST *t)
     }
 #endif
 
-    if ((ctx = EVP_MAC_CTX_new(expected->mac)) == NULL) {
-        t->err = "MAC_CREATE_ERROR";
-        goto err;
-    }
+    if (expected->alg != NULL)
+        params[params_n++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
+                                             expected->alg,
+                                             strlen(expected->alg) + 1);
+    if (expected->key != NULL)
+        params[params_n++] =
+            OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                              expected->key,
+                                              expected->key_len);
+    if (expected->custom != NULL)
+        params[params_n++] =
+            OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM,
+                                              expected->custom,
+                                              expected->custom_len);
+    if (expected->salt != NULL)
+        params[params_n++] =
+            OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_SALT,
+                                              expected->salt,
+                                              expected->salt_len);
+    if (expected->iv != NULL)
+        params[params_n++] =
+            OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
+                                              expected->iv,
+                                              expected->iv_len);
 
-    if (expected->alg != NULL
-        && ((algo_ctrl = EVP_MAC_CTRL_SET_CIPHER,
-             algo = EVP_get_cipherbyname(expected->alg)) == NULL
-            && (algo_ctrl = EVP_MAC_CTRL_SET_MD,
-                algo = EVP_get_digestbyname(expected->alg)) == NULL)) {
-        t->err = "MAC_BAD_ALGORITHM";
+    /*
+     * Unknown controls.  They must match parameters that the MAC recognises
+     */
+    if (params_n + sk_OPENSSL_STRING_num(expected->controls)
+        >= OSSL_NELEM(params)) {
+        t->err = "MAC_TOO_MANY_PARAMETERS";
         goto err;
     }
+    params_n_allocstart = params_n;
+    for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++) {
+        char *tmpkey, *tmpval;
+        char *value = sk_OPENSSL_STRING_value(expected->controls, i);
 
-
-    if (algo_ctrl != 0) {
-        rv = EVP_MAC_ctrl(ctx, algo_ctrl, algo);
-        if (rv == -2) {
-            t->err = "MAC_CTRL_INVALID";
-            goto err;
-        } else if (rv <= 0) {
-            t->err = "MAC_CTRL_ERROR";
+        if (!TEST_ptr(tmpkey = OPENSSL_strdup(value))) {
+            t->err = "MAC_PARAM_ERROR";
             goto err;
         }
-    }
-
-    rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY,
-                      expected->key, expected->key_len);
-    if (rv == -2) {
-        t->err = "MAC_CTRL_INVALID";
-        goto err;
-    } else if (rv <= 0) {
-        t->err = "MAC_CTRL_ERROR";
-        goto err;
-    }
-    if (expected->custom != NULL) {
-        rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_CUSTOM,
-                          expected->custom, expected->custom_len);
-        if (rv == -2) {
-            t->err = "MAC_CTRL_INVALID";
-            goto err;
-        } else if (rv <= 0) {
-            t->err = "MAC_CTRL_ERROR";
+        tmpval = strchr(tmpkey, ':');
+        if (tmpval != NULL)
+            *tmpval++ = '\0';
+
+        if (!OSSL_PARAM_allocate_from_text(&params[params_n], defined_params,
+                                           tmpkey, tmpval,
+                                           strlen(tmpval))) {
+            OPENSSL_free(tmpkey);
+            t->err = "MAC_PARAM_ERROR";
             goto err;
         }
-    }
+        params_n++;
 
-    if (expected->salt != NULL) {
-        rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_SALT,
-                          expected->salt, expected->salt_len);
-        if (rv == -2) {
-            t->err = "MAC_CTRL_INVALID";
-            goto err;
-        } else if (rv <= 0) {
-            t->err = "MAC_CTRL_ERROR";
-            goto err;
-        }
+        OPENSSL_free(tmpkey);
     }
+    params[params_n] = OSSL_PARAM_construct_end();
 
-    if (expected->iv != NULL) {
-        rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_IV,
-                          expected->iv, expected->iv_len);
-        if (rv == -2) {
-            t->err = "MAC_CTRL_INVALID";
-            goto err;
-        } else if (rv <= 0) {
-            t->err = "MAC_CTRL_ERROR";
-            goto err;
-        }
+    if ((ctx = EVP_MAC_CTX_new(expected->mac)) == NULL) {
+        t->err = "MAC_CREATE_ERROR";
+        goto err;
     }
 
-    for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++) {
-        char *p, *tmpval;
-        char *value = sk_OPENSSL_STRING_value(expected->controls, i);
-
-        if (!TEST_ptr(tmpval = OPENSSL_strdup(value))) {
-            t->err = "MAC_CTRL_ERROR";
-            goto err;
-        }
-        p = strchr(tmpval, ':');
-        if (p != NULL)
-            *p++ = '\0';
-        rv = EVP_MAC_ctrl_str(ctx, tmpval, p);
-        OPENSSL_free(tmpval);
-        if (rv == -2) {
-            t->err = "MAC_CTRL_INVALID";
-            goto err;
-        } else if (rv <= 0) {
-            t->err = "MAC_CTRL_ERROR";
-            goto err;
-        }
+    if (!EVP_MAC_CTX_set_params(ctx, params)) {
+        t->err = "MAC_BAD_PARAMS";
+        goto err;
     }
     if (!EVP_MAC_init(ctx)) {
         t->err = "MAC_INIT_ERROR";
@@ -1234,7 +1218,7 @@ static int mac_test_run_mac(EVP_TEST *t)
         t->err = "MAC_UPDATE_ERROR";
         goto err;
     }
-    if (!EVP_MAC_final(ctx, NULL, &got_len)) {
+    if (!EVP_MAC_final(ctx, NULL, &got_len, 0)) {
         t->err = "MAC_FINAL_LENGTH_ERROR";
         goto err;
     }
@@ -1242,7 +1226,7 @@ static int mac_test_run_mac(EVP_TEST *t)
         t->err = "TEST_FAILURE";
         goto err;
     }
-    if (!EVP_MAC_final(ctx, got, &got_len)
+    if (!EVP_MAC_final(ctx, got, &got_len, got_len)
         || !memory_err_compare(t, "TEST_MAC_ERR",
                                expected->output, expected->output_len,
                                got, got_len)) {
@@ -1251,6 +1235,9 @@ static int mac_test_run_mac(EVP_TEST *t)
     }
     t->err = NULL;
  err:
+    while (params_n-- > params_n_allocstart) {
+        OPENSSL_free(params[params_n].data);
+    }
     EVP_MAC_CTX_free(ctx);
     OPENSSL_free(got);
     return 1;
diff --git a/test/recipes/30-test_evp_data/evpmac.txt b/test/recipes/30-test_evp_data/evpmac.txt
index ada1ae6767..5b24200673 100644
--- a/test/recipes/30-test_evp_data/evpmac.txt
+++ b/test/recipes/30-test_evp_data/evpmac.txt
@@ -157,7 +157,7 @@ Output = 5150d1772f50834a503e069a973fbd7c
 MAC = SipHash
 Ctrl = digestsize:13
 Key = 000102030405060708090A0B0C0D0E0F
-Result = MAC_CTRL_ERROR
+Result = MAC_BAD_PARAMS
 
 # SIPHASH - default values: 2,4 rounds, explicit 13-byte mac (invalid size)
 # by EVP_PKEY this time
@@ -325,7 +325,7 @@ Output = 233a6c732212f4813ec4c9f357e35297e59a652fd24155205f00363f7c54734ee1e8c73
 MAC = BLAKE2BMAC
 Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
 Ctrl = outlen:128
-Result = MAC_CTRL_ERROR
+Result = MAC_BAD_PARAMS
 
 MAC = BLAKE2BMAC
 Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
@@ -381,7 +381,7 @@ Output = e9f7704dfe5080a4aafe62a806f53ea7f98ffc24175164158f18ec5497b961f5
 MAC = BLAKE2SMAC
 Key = 000102030405060708090a0b0c0d0e0f
 Ctrl = outlen:64
-Result = MAC_CTRL_ERROR
+Result = MAC_BAD_PARAMS
 
 MAC = BLAKE2SMAC
 Key = 000102030405060708090a0b0c0d0e0f
@@ -595,7 +595,7 @@ MAC = HMAC
 Algorithm = SHAKE128
 Input = "Test that SHAKE128 fails"
 Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
-Result = MAC_CTRL_ERROR
+Result = MAC_BAD_PARAMS
 
 
 Title = CMAC tests (from FIPS module)
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 7d550ce016..ac1c110133 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4426,7 +4426,7 @@ EVP_MD_CTX_set_pkey_ctx                 4531	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_meth_set_digest_custom         4532	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_meth_get_digest_custom         4533	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_new                         4534	3_0_0	EXIST::FUNCTION:
-EVP_MAC_CTX_new_id                      4535	3_0_0	EXIST::FUNCTION:
+EVP_MAC_CTX_new_id                      4535	3_0_0	NOEXIST::FUNCTION:
 EVP_MAC_CTX_free                        4536	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_dup                         4537	3_0_0	EXIST::FUNCTION:
 EVP_MAC_CTX_mac                         4538	3_0_0	EXIST::FUNCTION:
@@ -4434,15 +4434,15 @@ EVP_MAC_size                            4539	3_0_0	EXIST::FUNCTION:
 EVP_MAC_init                            4540	3_0_0	EXIST::FUNCTION:
 EVP_MAC_update                          4541	3_0_0	EXIST::FUNCTION:
 EVP_MAC_final                           4542	3_0_0	EXIST::FUNCTION:
-EVP_MAC_ctrl                            4543	3_0_0	EXIST::FUNCTION:
-EVP_MAC_vctrl                           4544	3_0_0	EXIST::FUNCTION:
-EVP_MAC_ctrl_str                        4545	3_0_0	EXIST::FUNCTION:
-EVP_MAC_str2ctrl                        4546	3_0_0	EXIST::FUNCTION:
-EVP_MAC_hex2ctrl                        4547	3_0_0	EXIST::FUNCTION:
-EVP_MAC_nid                             4548	3_0_0	EXIST::FUNCTION:
-EVP_get_macbyname                       4549	3_0_0	EXIST::FUNCTION:
-EVP_MAC_do_all                          4550	3_0_0	EXIST::FUNCTION:
-EVP_MAC_do_all_sorted                   4551	3_0_0	EXIST::FUNCTION:
+EVP_MAC_ctrl                            4543	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_vctrl                           4544	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_ctrl_str                        4545	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_str2ctrl                        4546	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_hex2ctrl                        4547	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_nid                             4548	3_0_0	NOEXIST::FUNCTION:
+EVP_get_macbyname                       4549	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_do_all                          4550	3_0_0	NOEXIST::FUNCTION:
+EVP_MAC_do_all_sorted                   4551	3_0_0	NOEXIST::FUNCTION:
 EVP_str2ctrl                            4552	3_0_0	EXIST::FUNCTION:
 EVP_hex2ctrl                            4553	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_supports_digest_nid            4554	3_0_0	EXIST::FUNCTION:
@@ -4720,3 +4720,15 @@ EVP_CIPHER_gettable_params              4829	3_0_0	EXIST::FUNCTION:
 EVP_CIPHER_CTX_settable_params          4830	3_0_0	EXIST::FUNCTION:
 EVP_CIPHER_CTX_gettable_params          4831	3_0_0	EXIST::FUNCTION:
 EVP_MD_get_params                       4832	3_0_0	EXIST::FUNCTION:
+EVP_MAC_fetch                           4833	3_0_0	EXIST::FUNCTION:
+EVP_MAC_CTX_settable_params             4834	3_0_0	EXIST::FUNCTION:
+EVP_MAC_CTX_set_params                  4835	3_0_0	EXIST::FUNCTION:
+EVP_MAC_CTX_get_params                  4836	3_0_0	EXIST::FUNCTION:
+EVP_MAC_CTX_gettable_params             4837	3_0_0	EXIST::FUNCTION:
+EVP_MAC_free                            4838	3_0_0	EXIST::FUNCTION:
+EVP_MAC_up_ref                          4839	3_0_0	EXIST::FUNCTION:
+EVP_MAC_name                            4840	3_0_0	EXIST::FUNCTION:
+EVP_MAC_get_params                      4841	3_0_0	EXIST::FUNCTION:
+EVP_MAC_gettable_params                 4842	3_0_0	EXIST::FUNCTION:
+EVP_MAC_provider                        4843	3_0_0	EXIST::FUNCTION:
+EVP_MAC_do_all_ex                       4844	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list