[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Wed Feb 6 09:31:22 UTC 2019


The branch master has been updated
       via  8269e44f9e40831a497fe9f31ba1d65aeb49a5c1 (commit)
       via  b215db236c6668c785bd99787b3fd07d5b2e6a10 (commit)
       via  33e113b0cbd9a0845f6f8a63e8aad558a897cac6 (commit)
       via  13b3cd7bc77d5d9297a755727100aee22d3e22b6 (commit)
       via  d1ad7c834e10543b3d1ecb36ccbd110384063b8f (commit)
       via  c3a261f8d31c1d04db01de36eccfe001b4ca0368 (commit)
       via  fc3c0223e8a70bfe8f8aefc98b819f7d852f3594 (commit)
       via  18568864169d970bcbda300e76f6fb1a1015a0d5 (commit)
      from  df4439186fb70ce72668d472943dbcd057df8f30 (commit)


- Log -----------------------------------------------------------------
commit 8269e44f9e40831a497fe9f31ba1d65aeb49a5c1
Author: Antoine Salon <asalon at vmware.com>
Date:   Mon Jan 7 15:09:55 2019 -0800

    blake2: avoid writing to output buffer when using default digest length
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit b215db236c6668c785bd99787b3fd07d5b2e6a10
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:36:40 2018 -0800

    blake2: add evpmac test vectors
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit 33e113b0cbd9a0845f6f8a63e8aad558a897cac6
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:36:07 2018 -0800

    blake2: backport changes to blake2s
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit 13b3cd7bc77d5d9297a755727100aee22d3e22b6
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:34:22 2018 -0800

    blake2: add EVP_MAC man page
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit d1ad7c834e10543b3d1ecb36ccbd110384063b8f
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:32:58 2018 -0800

    blake2: register MAC objects
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit c3a261f8d31c1d04db01de36eccfe001b4ca0368
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:28:10 2018 -0800

    blake2b: add EVP_MAC API
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit fc3c0223e8a70bfe8f8aefc98b819f7d852f3594
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:20:00 2018 -0800

    blake2b: add support for parameter setting and keyed hash
    
    The param block structure is used as a container for parameter values
    Added blake2b keyed init
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

commit 18568864169d970bcbda300e76f6fb1a1015a0d5
Author: Antoine Salon <asalon at vmware.com>
Date:   Thu Dec 20 15:08:23 2018 -0800

    blake2: add implementation support for variable digest length
    
    Signed-off-by: Antoine Salon <asalon at vmware.com>
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7726)

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

Summary of changes:
 crypto/blake2/blake2_locl.h                       |  27 ++-
 crypto/blake2/blake2b.c                           |  78 +++++++-
 crypto/blake2/blake2b_mac.c                       | 190 ++++++++++++++++++
 crypto/blake2/blake2s.c                           |  81 ++++++--
 crypto/blake2/blake2s_mac.c                       | 190 ++++++++++++++++++
 crypto/blake2/build.info                          |   2 +-
 crypto/blake2/m_blake2b.c                         |   8 +-
 crypto/blake2/m_blake2s.c                         |   8 +-
 crypto/err/openssl.txt                            |   5 +
 crypto/evp/c_allm.c                               |   4 +
 crypto/evp/evp_err.c                              |   6 +
 crypto/include/internal/evp_int.h                 |   2 +
 crypto/objects/obj_dat.h                          |  12 +-
 crypto/objects/obj_mac.num                        |   2 +
 crypto/objects/objects.txt                        |   2 +
 doc/man3/EVP_MAC.pod                              |  17 +-
 doc/man7/{EVP_MAC_KMAC.pod => EVP_MAC_BLAKE2.pod} |  52 +++--
 include/openssl/evp.h                             |   3 +
 include/openssl/evperr.h                          |   5 +
 include/openssl/obj_mac.h                         |   8 +
 test/evp_test.c                                   |  26 ++-
 test/recipes/30-test_evp_data/evpmac.txt          | 230 ++++++++++++++++++++++
 22 files changed, 897 insertions(+), 61 deletions(-)
 create mode 100644 crypto/blake2/blake2b_mac.c
 create mode 100644 crypto/blake2/blake2s_mac.c
 copy doc/man7/{EVP_MAC_KMAC.pod => EVP_MAC_BLAKE2.pod} (51%)

diff --git a/crypto/blake2/blake2_locl.h b/crypto/blake2/blake2_locl.h
index 892a1af..e8c86db 100644
--- a/crypto/blake2/blake2_locl.h
+++ b/crypto/blake2/blake2_locl.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -49,6 +49,7 @@ struct blake2s_ctx_st {
     uint32_t f[2];
     uint8_t  buf[BLAKE2S_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
 };
 
 struct blake2b_param_st {
@@ -73,6 +74,7 @@ struct blake2b_ctx_st {
     uint64_t f[2];
     uint8_t  buf[BLAKE2B_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
 };
 
 #define BLAKE2B_DIGEST_LENGTH 64
@@ -81,10 +83,29 @@ struct blake2b_ctx_st {
 typedef struct blake2s_ctx_st BLAKE2S_CTX;
 typedef struct blake2b_ctx_st BLAKE2B_CTX;
 
-int BLAKE2b_Init(BLAKE2B_CTX *c);
+int BLAKE2b_Init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P);
+int BLAKE2b_Init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key);
 int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen);
 int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c);
 
-int BLAKE2s_Init(BLAKE2S_CTX *c);
+/*
+ * These setters are internal and do not check the validity of their parameters.
+ * See blake2b_mac_ctrl for validation logic.
+ */
+
+void blake2b_param_init(BLAKE2B_PARAM *P);
+void blake2b_param_set_digest_length(BLAKE2B_PARAM *P, uint8_t outlen);
+void blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen);
+void blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, size_t length);
+void blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, size_t length);
+
+int BLAKE2s_Init(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P);
+int BLAKE2s_Init_key(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P, const void *key);
 int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen);
 int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c);
+
+void blake2s_param_init(BLAKE2S_PARAM *P);
+void blake2s_param_set_digest_length(BLAKE2S_PARAM *P, uint8_t outlen);
+void blake2s_param_set_key_length(BLAKE2S_PARAM *P, uint8_t keylen);
+void blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, size_t length);
+void blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t length);
diff --git a/crypto/blake2/blake2b.c b/crypto/blake2/blake2b.c
index d4e5326..73ba0b6 100644
--- a/crypto/blake2/blake2b.c
+++ b/crypto/blake2/blake2b.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -62,12 +62,14 @@ static ossl_inline void blake2b_init0(BLAKE2B_CTX *S)
     }
 }
 
-/* init xors IV with input parameter block */
+/* init xors IV with input parameter block and sets the output length */
 static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
 {
     size_t i;
     const uint8_t *p = (const uint8_t *)(P);
+
     blake2b_init0(S);
+    S->outlen = P->digest_length;
 
     /* The param struct is carefully hand packed, and should be 64 bytes on
      * every platform. */
@@ -78,10 +80,9 @@ static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
     }
 }
 
-/* Initialize the hashing context.  Always returns 1. */
-int BLAKE2b_Init(BLAKE2B_CTX *c)
+/* Initialize the parameter block with default values */
+void blake2b_param_init(BLAKE2B_PARAM *P)
 {
-    BLAKE2B_PARAM P[1];
     P->digest_length = BLAKE2B_DIGEST_LENGTH;
     P->key_length    = 0;
     P->fanout        = 1;
@@ -93,10 +94,60 @@ int BLAKE2b_Init(BLAKE2B_CTX *c)
     memset(P->reserved, 0, sizeof(P->reserved));
     memset(P->salt,     0, sizeof(P->salt));
     memset(P->personal, 0, sizeof(P->personal));
+}
+
+void blake2b_param_set_digest_length(BLAKE2B_PARAM *P, uint8_t outlen)
+{
+    P->digest_length = outlen;
+}
+
+void blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen)
+{
+    P->key_length = keylen;
+}
+
+void blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, size_t len)
+{
+    memcpy(P->personal, personal, len);
+    memset(P->personal + len, 0, BLAKE2B_PERSONALBYTES - len);
+}
+
+void blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, size_t len)
+{
+    memcpy(P->salt, salt, len);
+    memset(P->salt + len, 0, BLAKE2B_SALTBYTES - len);
+}
+
+/*
+ * Initialize the hashing context with the given parameter block.
+ * Always returns 1.
+ */
+int BLAKE2b_Init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P)
+{
     blake2b_init_param(c, P);
     return 1;
 }
 
+/*
+ * Initialize the hashing context with the given parameter block and key.
+ * Always returns 1.
+ */
+int BLAKE2b_Init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key)
+{
+    blake2b_init_param(c, P);
+
+    /* Pad the key to form first data block */
+    {
+        uint8_t block[BLAKE2B_BLOCKBYTES] = {0};
+
+        memcpy(block, key, P->key_length);
+        BLAKE2b_Update(c, block, BLAKE2B_BLOCKBYTES);
+        OPENSSL_cleanse(block, BLAKE2B_BLOCKBYTES);
+    }
+
+    return 1;
+}
+
 /* Permute the state while xoring in the block of data. */
 static void blake2b_compress(BLAKE2B_CTX *S,
                             const uint8_t *blocks,
@@ -252,17 +303,26 @@ int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen)
  */
 int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c)
 {
+    uint8_t outbuffer[BLAKE2B_OUTBYTES] = {0};
+    uint8_t *target = outbuffer;
+    int iter = (c->outlen + 7) / 8;
     int i;
 
+    /* Avoid writing to the temporary buffer if possible */
+    if ((c->outlen % sizeof(c->h[0])) == 0)
+        target = md;
+
     blake2b_set_lastblock(c);
     /* Padding */
     memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
     blake2b_compress(c, c->buf, c->buflen);
 
-    /* Output full hash to message digest */
-    for (i = 0; i < 8; ++i) {
-        store64(md + sizeof(c->h[i]) * i, c->h[i]);
-    }
+    /* Output full hash to buffer */
+    for (i = 0; i < iter; ++i)
+        store64(target + sizeof(c->h[i]) * i, c->h[i]);
+
+    if (target != md)
+        memcpy(md, target, c->outlen);
 
     OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX));
     return 1;
diff --git a/crypto/blake2/blake2b_mac.c b/crypto/blake2/blake2b_mac.c
new file mode 100644
index 0000000..71b8517
--- /dev/null
+++ b/crypto/blake2/blake2b_mac.c
@@ -0,0 +1,190 @@
+/*
+ * 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 "blake2_locl.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 int blake2b_mac_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src)
+{
+    *dst = *src;
+    return 1;
+}
+
+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_copy,
+    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.c b/crypto/blake2/blake2s.c
index c0f0f26..121f0d1 100644
--- a/crypto/blake2/blake2s.c
+++ b/crypto/blake2/blake2s.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -58,27 +58,26 @@ static ossl_inline void blake2s_init0(BLAKE2S_CTX *S)
     }
 }
 
-/* init2 xors IV with input parameter block */
+/* init xors IV with input parameter block and sets the output length */
 static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)
 {
-    const uint8_t *p = (const uint8_t *)(P);
     size_t i;
+    const uint8_t *p = (const uint8_t *)(P);
+
+    blake2s_init0(S);
+    S->outlen = P->digest_length;
 
     /* The param struct is carefully hand packed, and should be 32 bytes on
      * every platform. */
     assert(sizeof(BLAKE2S_PARAM) == 32);
-    blake2s_init0(S);
     /* IV XOR ParamBlock */
     for (i = 0; i < 8; ++i) {
         S->h[i] ^= load32(&p[i*4]);
     }
 }
 
-/* Initialize the hashing context.  Always returns 1. */
-int BLAKE2s_Init(BLAKE2S_CTX *c)
+void blake2s_param_init(BLAKE2S_PARAM *P)
 {
-    BLAKE2S_PARAM P[1];
-
     P->digest_length = BLAKE2S_DIGEST_LENGTH;
     P->key_length    = 0;
     P->fanout        = 1;
@@ -89,10 +88,59 @@ int BLAKE2s_Init(BLAKE2S_CTX *c)
     P->inner_length  = 0;
     memset(P->salt,     0, sizeof(P->salt));
     memset(P->personal, 0, sizeof(P->personal));
+}
+
+void blake2s_param_set_digest_length(BLAKE2S_PARAM *P, uint8_t outlen)
+{
+    P->digest_length = outlen;
+}
+
+void blake2s_param_set_key_length(BLAKE2S_PARAM *P, uint8_t keylen)
+{
+    P->key_length = keylen;
+}
+
+void blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, size_t len)
+{
+    memcpy(P->personal, personal, len);
+    memset(P->personal + len, 0, BLAKE2S_PERSONALBYTES - len);
+}
+
+void blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t len)
+{
+    memcpy(P->salt, salt, len);
+    memset(P->salt + len, 0, BLAKE2S_SALTBYTES - len);}
+
+/*
+ * Initialize the hashing context with the given parameter block.
+ * Always returns 1.
+ */
+int BLAKE2s_Init(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P)
+{
     blake2s_init_param(c, P);
     return 1;
 }
 
+/*
+ * Initialize the hashing context with the given parameter block and key.
+ * Always returns 1.
+ */
+int BLAKE2s_Init_key(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P, const void *key)
+{
+    blake2s_init_param(c, P);
+
+    /* Pad the key to form first data block */
+    {
+        uint8_t block[BLAKE2S_BLOCKBYTES] = {0};
+
+        memcpy(block, key, P->key_length);
+        BLAKE2s_Update(c, block, BLAKE2S_BLOCKBYTES);
+        OPENSSL_cleanse(block, BLAKE2S_BLOCKBYTES);
+    }
+
+    return 1;
+}
+
 /* Permute the state while xoring in the block of data. */
 static void blake2s_compress(BLAKE2S_CTX *S,
                             const uint8_t *blocks,
@@ -246,17 +294,26 @@ int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen)
  */
 int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c)
 {
+    uint8_t outbuffer[BLAKE2S_OUTBYTES] = {0};
+    uint8_t *target = outbuffer;
+    int iter = (c->outlen + 3) / 4;
     int i;
 
+    /* Avoid writing to the temporary buffer if possible */
+    if ((c->outlen % sizeof(c->h[0])) == 0)
+        target = md;
+
     blake2s_set_lastblock(c);
     /* Padding */
     memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
     blake2s_compress(c, c->buf, c->buflen);
 
-    /* Output full hash to temp buffer */
-    for (i = 0; i < 8; ++i) {
-        store32(md + sizeof(c->h[i]) * i, c->h[i]);
-    }
+    /* Output full hash to buffer */
+    for (i = 0; i < iter; ++i)
+        store32(target + sizeof(c->h[i]) * i, c->h[i]);
+
+    if (target != md)
+        memcpy(md, target, c->outlen);
 
     OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));
     return 1;
diff --git a/crypto/blake2/blake2s_mac.c b/crypto/blake2/blake2s_mac.c
new file mode 100644
index 0000000..d40778c
--- /dev/null
+++ b/crypto/blake2/blake2s_mac.c
@@ -0,0 +1,190 @@
+/*
+ * 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 "blake2_locl.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 int blake2s_mac_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src)
+{
+    *dst = *src;
+    return 1;
+}
+
+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_copy,
+    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 0036f08..ab72ef2 100644
--- a/crypto/blake2/build.info
+++ b/crypto/blake2/build.info
@@ -1,3 +1,3 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
-        blake2b.c blake2s.c m_blake2b.c m_blake2s.c
+        blake2b.c blake2s.c blake2b_mac.c blake2s_mac.c m_blake2b.c m_blake2s.c
diff --git a/crypto/blake2/m_blake2b.c b/crypto/blake2/m_blake2b.c
index a37ab89..2fb80f8 100644
--- a/crypto/blake2/m_blake2b.c
+++ b/crypto/blake2/m_blake2b.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -25,7 +25,9 @@
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return BLAKE2b_Init(EVP_MD_CTX_md_data(ctx));
+    BLAKE2B_PARAM P;
+    blake2b_param_init(&P);
+    return BLAKE2b_Init(EVP_MD_CTX_md_data(ctx), &P);
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
@@ -49,7 +51,7 @@ static const EVP_MD blake2b_md = {
     NULL,
     NULL,
     BLAKE2B_BLOCKBYTES,
-    sizeof(EVP_MD *) + sizeof(BLAKE2B_CTX),
+    sizeof(BLAKE2B_CTX),
 };
 
 const EVP_MD *EVP_blake2b512(void)
diff --git a/crypto/blake2/m_blake2s.c b/crypto/blake2/m_blake2s.c
index 2c5f42b..8ff1727 100644
--- a/crypto/blake2/m_blake2s.c
+++ b/crypto/blake2/m_blake2s.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -25,7 +25,9 @@
 
 static int init(EVP_MD_CTX *ctx)
 {
-    return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx));
+    BLAKE2S_PARAM P;
+    blake2s_param_init(&P);
+    return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx), &P);
 }
 
 static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
@@ -49,7 +51,7 @@ static const EVP_MD blake2s_md = {
     NULL,
     NULL,
     BLAKE2S_BLOCKBYTES,
-    sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX),
+    sizeof(BLAKE2S_CTX),
 };
 
 const EVP_MD *EVP_blake2s256(void)
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 0e133d6..aaea598 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -730,6 +730,10 @@ 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
@@ -2263,6 +2267,7 @@ EVP_R_INVALID_FIPS_MODE:168:invalid fips mode
 EVP_R_INVALID_KEY:163:invalid key
 EVP_R_INVALID_KEY_LENGTH:130:invalid key length
 EVP_R_INVALID_OPERATION:148:invalid operation
+EVP_R_INVALID_SALT_LENGTH:186:invalid salt length
 EVP_R_KEYGEN_FAILURE:120:keygen failure
 EVP_R_KEY_SETUP_FAILED:180:key setup failed
 EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
diff --git a/crypto/evp/c_allm.c b/crypto/evp/c_allm.c
index 2cc0694..f5442df 100644
--- a/crypto/evp/c_allm.c
+++ b/crypto/evp/c_allm.c
@@ -12,6 +12,10 @@
 
 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
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index 14e5ed6..a4dd97b 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -27,6 +27,10 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_CTRL, 0), "blake2b_mac_ctrl"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_INIT, 0), "blake2b_mac_init"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_CTRL, 0), "blake2s_mac_ctrl"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_INIT, 0), "blake2s_mac_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0),
      "chacha20_poly1305_ctrl"},
@@ -226,6 +230,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
+    "invalid salt length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index 82d1a6b..189d8aa 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -128,6 +128,8 @@ struct evp_mac_st {
     int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value);
 };
 
+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;
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 859795f..78a9e7a 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -1079,7 +1079,7 @@ static const unsigned char so[7767] = {
     0x28,0xCC,0x45,0x03,0x04,                      /* [ 7761] OBJ_gmac */
 };
 
-#define NUM_NID 1201
+#define NUM_NID 1203
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2282,9 +2282,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"AES-128-SIV", "aes-128-siv", NID_aes_128_siv},
     {"AES-192-SIV", "aes-192-siv", NID_aes_192_siv},
     {"AES-256-SIV", "aes-256-siv", NID_aes_256_siv},
+    {"BLAKE2BMAC", "blake2bmac", NID_blake2bmac},
+    {"BLAKE2SMAC", "blake2smac", NID_blake2smac},
 };
 
-#define NUM_SN 1192
+#define NUM_SN 1194
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -2362,6 +2364,8 @@ static const unsigned int sn_objs[NUM_SN] = {
       93,    /* "BF-CFB" */
       92,    /* "BF-ECB" */
       94,    /* "BF-OFB" */
+    1201,    /* "BLAKE2BMAC" */
+    1202,    /* "BLAKE2SMAC" */
     1056,    /* "BLAKE2b512" */
     1057,    /* "BLAKE2s256" */
       14,    /* "C" */
@@ -3480,7 +3484,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1093,    /* "x509ExtAdmission" */
 };
 
-#define NUM_LN 1192
+#define NUM_LN 1194
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -3782,7 +3786,9 @@ static const unsigned int ln_objs[NUM_LN] = {
       92,    /* "bf-ecb" */
       94,    /* "bf-ofb" */
     1056,    /* "blake2b512" */
+    1201,    /* "blake2bmac" */
     1057,    /* "blake2s256" */
+    1202,    /* "blake2smac" */
      921,    /* "brainpoolP160r1" */
      922,    /* "brainpoolP160t1" */
      923,    /* "brainpoolP192r1" */
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 021875d..8779020 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -1198,3 +1198,5 @@ kmac256		1197
 aes_128_siv		1198
 aes_192_siv		1199
 aes_256_siv		1200
+blake2bmac		1201
+blake2smac		1202
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index fc32606..344b67b 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -17,6 +17,8 @@ iso 0 9797 3 4                          : GMAC          : gmac
 # There are no OIDs for these yet...
             : KMAC128   : kmac128
             : KMAC256   : kmac256
+            : BLAKE2BMAC	: blake2bmac
+            : BLAKE2SMAC   	: blake2smac
 
 # HMAC OIDs
 identified-organization 6 1 5 5 8 1 1	: HMAC-MD5	: hmac-md5
diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod
index 0e0d749..32bf589 100644
--- a/doc/man3/EVP_MAC.pod
+++ b/doc/man3/EVP_MAC.pod
@@ -87,9 +87,6 @@ through diverse controls.
 This should be called before calling EVP_MAC_update() and
 EVP_MAC_final().
 
-EVP_MAC_reset() resets the computation for the given context.
-This may not be supported by the MAC implementation.
-
 EVP_MAC_update() adds C<datalen> bytes from C<data> to the MAC input.
 
 EVP_MAC_final() does the final computation and stores the result in
@@ -171,18 +168,23 @@ Some MAC implementations require an IV, this control sets the IV.
 
 =item B<EVP_MAC_CTRL_SET_CUSTOM>
 
-This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
+This control expects two arguments: C<unsigned char *custom>, C<size_t customlen>
 
-Some MAC implementations (KMAC) require an Customization 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 control expects two arguments: C<unsigned char *salt>, C<size_t saltlen>
+
+This option is used by BLAKE2 MAC.
+
 =item B<EVP_MAC_CTRL_SET_XOF>
 
 This control expects one argument: C<int xof>
 
 This option is used by KMAC.
 
-
 =item B<EVP_MAC_CTRL_SET_FLAGS>
 
 This control expects one argument: C<unsigned long flags>
@@ -231,7 +233,7 @@ created EVP_MAC_CTX, or NULL if allocation failed.
 
 EVP_MAC_CTX_free() returns nothing at all.
 
-EVP_MAC_CTX_copy(), EVP_MAC_reset(), EVP_MAC_init(), EVP_MAC_update(),
+EVP_MAC_CTX_copy(), EVP_MAC_init(), EVP_MAC_update(),
 and EVP_MAC_final() return 1 on success, 0 on error.
 
 EVP_MAC_ctrl(), EVP_MAC_ctrl_str(), EVP_MAC_str2ctrl() and
@@ -346,6 +348,7 @@ F<./foo>)
 
 =head1 SEE ALSO
 
+L<EVP_MAC_BLAKE2(7)>,
 L<EVP_MAC_CMAC(7)>,
 L<EVP_MAC_GMAC(7)>,
 L<EVP_MAC_HMAC(7)>,
diff --git a/doc/man7/EVP_MAC_KMAC.pod b/doc/man7/EVP_MAC_BLAKE2.pod
similarity index 51%
copy from doc/man7/EVP_MAC_KMAC.pod
copy to doc/man7/EVP_MAC_BLAKE2.pod
index 4ccaabe..58b4f99 100644
--- a/doc/man7/EVP_MAC_KMAC.pod
+++ b/doc/man7/EVP_MAC_BLAKE2.pod
@@ -2,15 +2,15 @@
 
 =head1 NAME
 
-EVP_MAC_KMAC - The KMAC EVP_MAC implementation
+EVP_MAC_BLAKE2 - The BLAKE2 EVP_MAC implementation
 
 =head1 DESCRIPTION
 
-Support for computing KMAC MACs through the B<EVP_MAC> API.
+Support for computing BLAKE2 MACs through the B<EVP_MAC> API.
 
 =head2 Numeric identity
 
-B<EVP_MAC_KMAC128> and B<EVP_MAC_KMAC256> are the numeric identities for this
+B<EVP_MAC_BLAKE2B> and B<EVP_MAC_BLAKE2S> are the numeric identities for this
 implementation, and can be used in functions like EVP_MAC_CTX_new_id() and
 EVP_get_macbynid().
 
@@ -22,6 +22,8 @@ The supported controls are:
 
 =item B<EVP_MAC_CTRL_SET_KEY>
 
+This is a string value of at most 64 bytes for EVP_MAC_BLAKE2B
+or 32 for EVP_MAC_BLAKE2S and at least 1 byte in both cases.
 This must be set before calling EVP_MAC_init().
 
 EVP_MAC_ctrl_str() takes two type strings for this control:
@@ -41,8 +43,9 @@ decoded before passing on as control value.
 
 =item B<EVP_MAC_CTRL_SET_CUSTOM>
 
-This is an optional string value that can be set before calling EVP_MAC_init().
-If it is not set it uses the default value "".
+This is an optional string value of at most 16 bytes for EVP_MAC_BLAKE2B
+or 8 for EVP_MAC_BLAKE2S, set to all-NULL by default.
+If used this must be set before calling EVP_MAC_init().
 
 EVP_MAC_ctrl_str() takes two type strings for this control:
 
@@ -59,22 +62,35 @@ decoded before passing on as control value.
 
 =back
 
-=item B<EVP_MAC_CTRL_SET_SIZE>
+=item B<EVP_MAC_CTRL_SET_SALT>
 
-EVP_MAC_ctrl_str() type string: "outlen"
+This is an optional string value of at most 16 bytes for EVP_MAC_BLAKE2B
+or 8 for EVP_MAC_BLAKE2S, set to all-NULL by default.
+If used this must be set before calling EVP_MAC_init().
+
+EVP_MAC_ctrl_str() takes two type strings for this control:
+
+=over 4
+
+=item "salt"
+
+The value string is used as is.
 
-This is an optional value string containing a decimal number. If it is not set
-it uses the default value of 32 for EVP_MAC_KMAC128 and 64 for EVP_MAC_KMAC256.
-This can be called any time before EVP_MAC_final().
+=item "hexsalt"
 
-=item B<EVP_MAC_CTRL_SET_XOF>
+The value string is expected to be a hexadecimal number, which will be
+decoded before passing on as control value.
 
-EVP_MAC_ctrl_str() type string: "xof"
+=back
 
-The value string is expected to be an integer value of 1 or 0. Use 1 to enable
-XOF mode. If XOF is enabled then the output len that is encoded as part of the
-input stream is set to zero.
-This can be called any time before EVP_MAC_final().
+=item B<EVP_MAC_CTRL_SET_SIZE>
+
+EVP_MAC_ctrl_str() type string: "outlen"
+
+This is an optional value string containing a decimal number between 1 and
+32 for EVP_MAC_BLAKE2S or 64 for EVP_MAC_BLAKE2B.
+If it is not set it uses the default digest size of 32 and 64 respectively.
+If used this must be set before calling EVP_MAC_init().
 
 =back
 
@@ -82,6 +98,10 @@ This can be called any time before EVP_MAC_final().
 
 L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
 
+=head1 HISTORY
+
+The macros and functions described here were added to OpenSSL 3.0.0.
+
 =head1 COPYRIGHT
 
 Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 940a4b1..23f07ea 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -993,6 +993,8 @@ void EVP_MD_do_all_sorted(void (*fn)
 
 /* 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
@@ -1037,6 +1039,7 @@ void EVP_MAC_do_all_sorted(void (*fn)
 # 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 */
 
 /* PKEY stuff */
 int EVP_PKEY_decrypt_old(unsigned char *dec_key,
diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h
index 0f78d36..d3ed5b5 100644
--- a/include/openssl/evperr.h
+++ b/include/openssl/evperr.h
@@ -32,6 +32,10 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_ARIA_GCM_INIT_KEY                          176
 # define EVP_F_ARIA_INIT_KEY                              185
 # define EVP_F_B64_NEW                                    198
+# define EVP_F_BLAKE2B_MAC_CTRL                           220
+# define EVP_F_BLAKE2B_MAC_INIT                           221
+# define EVP_F_BLAKE2S_MAC_CTRL                           222
+# define EVP_F_BLAKE2S_MAC_INIT                           223
 # define EVP_F_CAMELLIA_INIT_KEY                          159
 # define EVP_F_CHACHA20_POLY1305_CTRL                     182
 # define EVP_F_CMLL_T4_INIT_KEY                           179
@@ -168,6 +172,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_INVALID_KEY                                163
 # define EVP_R_INVALID_KEY_LENGTH                         130
 # define EVP_R_INVALID_OPERATION                          148
+# define EVP_R_INVALID_SALT_LENGTH                        186
 # define EVP_R_KEYGEN_FAILURE                             120
 # define EVP_R_KEY_SETUP_FAILED                           180
 # define EVP_R_MEMORY_LIMIT_EXCEEDED                      172
diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
index 242eaeb..97b2204 100644
--- a/include/openssl/obj_mac.h
+++ b/include/openssl/obj_mac.h
@@ -57,6 +57,14 @@
 #define LN_kmac256              "kmac256"
 #define NID_kmac256             1197
 
+#define SN_blake2bmac           "BLAKE2BMAC"
+#define LN_blake2bmac           "blake2bmac"
+#define NID_blake2bmac          1201
+
+#define SN_blake2smac           "BLAKE2SMAC"
+#define LN_blake2smac           "blake2smac"
+#define NID_blake2smac          1202
+
 #define SN_hmac_md5             "HMAC-MD5"
 #define LN_hmac_md5             "hmac-md5"
 #define NID_hmac_md5            780
diff --git a/test/evp_test.c b/test/evp_test.c
index eaedab2..932b03c 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -864,6 +864,9 @@ typedef struct mac_data_st {
     size_t output_len;
     unsigned char *custom;
     size_t custom_len;
+    /* MAC salt (blake2) */
+    unsigned char *salt;
+    size_t salt_len;
     /* Collection of controls */
     STACK_OF(OPENSSL_STRING) *controls;
 } MAC_DATA;
@@ -947,6 +950,7 @@ static void mac_test_cleanup(EVP_TEST *t)
     OPENSSL_free(mdat->key);
     OPENSSL_free(mdat->iv);
     OPENSSL_free(mdat->custom);
+    OPENSSL_free(mdat->salt);
     OPENSSL_free(mdat->input);
     OPENSSL_free(mdat->output);
 }
@@ -962,6 +966,8 @@ static int mac_test_parse(EVP_TEST *t,
         return parse_bin(value, &mdata->iv, &mdata->iv_len);
     if (strcmp(keyword, "Custom") == 0)
         return parse_bin(value, &mdata->custom, &mdata->custom_len);
+    if (strcmp(keyword, "Salt") == 0)
+        return parse_bin(value, &mdata->salt, &mdata->salt_len);
     if (strcmp(keyword, "Algorithm") == 0) {
         mdata->alg = OPENSSL_strdup(value);
         if (!mdata->alg)
@@ -1156,6 +1162,18 @@ static int mac_test_run_mac(EVP_TEST *t)
         }
     }
 
+    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;
+        }
+    }
+
     if (expected->iv != NULL) {
         rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_IV,
                           expected->iv, expected->iv_len);
@@ -1168,10 +1186,6 @@ static int mac_test_run_mac(EVP_TEST *t)
         }
     }
 
-    if (!EVP_MAC_init(ctx)) {
-        t->err = "MAC_INIT_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);
@@ -1193,6 +1207,10 @@ static int mac_test_run_mac(EVP_TEST *t)
             goto err;
         }
     }
+    if (!EVP_MAC_init(ctx)) {
+        t->err = "MAC_INIT_ERROR";
+        goto err;
+    }
     if (!EVP_MAC_update(ctx, expected->input, expected->input_len)) {
         t->err = "MAC_UPDATE_ERROR";
         goto err;
diff --git a/test/recipes/30-test_evp_data/evpmac.txt b/test/recipes/30-test_evp_data/evpmac.txt
index ba691c5..732c8c4 100644
--- a/test/recipes/30-test_evp_data/evpmac.txt
+++ b/test/recipes/30-test_evp_data/evpmac.txt
@@ -167,6 +167,236 @@ Ctrl = digestsize:13
 Key = 000102030405060708090A0B0C0D0E0F
 Result = EVPPKEYCTXCTRL_ERROR
 
+Title = Keyed BLAKE2 tests (Test vectors from reference implementation)
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input =
+Output = 10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 00
+Output = 961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 0001
+Output = da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102
+Output = 33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 00010203
+Output = beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 0001020304
+Output = 098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9
+Output = 1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa
+Output = 4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb
+Output = 695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc
+Output = a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd
+Output = d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe
+Output = 142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input =
+Output = 48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 00
+Output = 40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 0001
+Output = 6bb71300644cd3991b26ccd4d274acd1adeab8b1d7914546c1198bbe9fc9d803
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102
+Output = 1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 00010203
+Output = f6c3fbadb4cc687a0064a5be6e791bec63b868ad62fba61b3757ef9ca52e05b2
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 0001020304
+Output = 49c1f21188dfd769aea0e911dd6b41f14dab109d2b85977aa3088b5c707e8598
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9
+Output = 9fc5450109e1b779f6c7ae79d56c27635c8dd426c5a9d54e2578db989b8c3b4e
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa
+Output = d12bf3732ef4af5c22fa90356af8fc50fcb40f8f2ea5c8594737a3b3d5abdbd7
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb
+Output = 11030b9289bba5af65260672ab6fee88b87420acef4a1789a2073b7ec2f2a09e
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc
+Output = 69cb192b8444005c8c0ceb12c846860768188cda0aec27a9c8a55cdee2123632
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd
+Output = db444c15597b5f1a03d1f9edd16e4a9f43a667cc275175dfa2b704e3bb1a9b83
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe
+Output = 3fb735061abc519dfe979e54c1ee5bfad0a9d858b3315bad34bde999efd724dd
+
+Title = Custom keyed BLAKE2 tests
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Custom = "email"
+Input = "Sample input for keylen<blocklen and custom"
+Output = fb7abee8f585b0d844a3c7db211b8f50a3a5de9bb20a560eb095d05430a60e83f3d44a84c84e8a8ef79eef694551418a05c7495d10aae051e9c63822dfa59e7c
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Custom = "blockchain"
+Input = "Sample input for keylen<blocklen and custom"
+Output = b971503ceebaa26c98cb7722abaf019d74138d92ff5d82f91a7473ec641ae6811148bc1edbe9db9030fd9a8a965d7f35492d79f602be81f6e2d9b84abc819c62
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Salt = a3a5de9b8fcccd0a560eb095a3638bb1
+Input = "Sample input for keylen<blocklen and salt"
+Output = a57e6f23123be251f4e8cd04d4313e50bfa2ed5a28a3685dc86398da78503d54a169faabcc186037418636af20718f20797fb883b83ab98f5b2d17ce185b615e
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Salt = b4a5b8cd0a009561
+Input = "Sample input for keylen<blocklen and salt"
+Output = 709ee3733b179658d326fda6692e6761068d0044895252615bd2a19a14ad4da1ee6ddf613bdf1ae805f97809a140837640c4ce2fece1831b3ccd07544b0d36ab
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Custom = "application"
+Salt = 000102030405060708090a0b0c0d0e0f
+Input = "Sample input for keylen<blocklen, salt and custom"
+Output = 233a6c732212f4813ec4c9f357e35297e59a652fd24155205f00363f7c54734ee1e8c7329d92116cbec62db35ebb5d51f9e5c2ba41789b84ac9ebc266918e524
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Ctrl = outlen:128
+Result = MAC_CTRL_ERROR
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = "Sample input for outlen<digest_length"
+Ctrl = outlen:1
+Output = 2a
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = "Sample input for outlen<digest_length"
+Ctrl = outlen:32
+Output = 7fa43c7735fcacad9fce2b44bef37dba6501ab48c9397bedb5562a682e519793
+
+MAC = BLAKE2BMAC
+Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+Input = "Combo input with outlen, custom and salt"
+Custom = "application"
+Salt = 000102030405060708090a0b0c0d0e0f
+Ctrl = outlen:32
+Output = 51742fc491171eaf6b9459c8b93a44bbf8f44a0b4869a17fa178c8209918ad96
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Custom = "email"
+Input = "Sample input for keylen<blocklen and custom"
+Output = 099619607617f8767b278d6d76216b91794ea372c9fd3733a4a36e995a767987
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Custom = "database"
+Input = "Sample input for keylen<blocklen and custom"
+Output = afa468ff12d922c1bfdfe26b7d74f1041e7708e83ee7e128ce878f93e2852ad0
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Salt = a205819e78d6d762
+Input = "Sample input for keylen<blocklen and salt"
+Output = 29f7d780009ef8f001ec44088622f0752f6c360cda40e3c2181c4f7eacdd9dc6
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Salt = d6e437b2
+Input = "Sample input for keylen<blocklen and salt"
+Output = aa9dbb8bbad89ea35467f1ff995521121989eb6439f1263e04e87d63a9c2ef28
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Custom = "app"
+Salt = a205819e78d6d762
+Input = "Sample input for keylen<blocklen, salt and custom"
+Output = e9f7704dfe5080a4aafe62a806f53ea7f98ffc24175164158f18ec5497b961f5
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Ctrl = outlen:64
+Result = MAC_CTRL_ERROR
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Ctrl = outlen:16
+Input = "Sample input for outlen<digest_length"
+Output = a09fb3d513efc3ed58dd1264de3c59f5
+
+MAC = BLAKE2SMAC
+Key = 000102030405060708090a0b0c0d0e0f
+Ctrl = outlen:16
+Custom = "app"
+Salt = 0001020304050607
+Input = "Combo input with outlen, custom and salt"
+Output = 6808d8daae537a16bf00e837010969a4
+
 Title = HMAC tests (from RFC2104 and others)
 
 MAC = HMAC


More information about the openssl-commits mailing list