Adapt diverse code to provider based MACs.
authorRichard Levitte <levitte@openssl.org>
Tue, 4 Jun 2019 16:00:04 +0000 (18:00 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 15 Aug 2019 20:12:25 +0000 (22:12 +0200)
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@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8877)

crypto/crmf/crmf_pbm.c
crypto/include/internal/modes_int.h
crypto/kdf/sskdf.c
crypto/kdf/tls1_prf.c
crypto/modes/siv128.c

index 7b291666108f07ac5b2b955c5e16e299b84ef479..40c12dd32af77bf50a1eb9b5ec8d7b8429f19c0b 100644 (file)
@@ -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;
     }
 
index 5230f08966dc6161f5d0c61eed73e96ebae96f5e..08e4ffae740edc1ad74c54a88e1b1d3b893bd169 100644 (file)
@@ -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;
index 62372a50ede867a69db7582a011d2de5f476caff..7e5a68be5ecdefe090acd3c224f2bff8bea04a3f 100644 (file)
 #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;
index b14ae6fee181f800308d7ced5b858c135b0faf93..1df201dd3ffa9dbddc1335a6980f0b9c61c3cbfe 100644 (file)
@@ -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;
 }
index 359252f196e22c2e122d98479e041526042e45d8..04abea25c10c02cbccdfb6e08b9f8b0e3a5643ff 100644 (file)
@@ -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;