File 1321-crypto-Call-EVP_MAC_fetch-once-at-load-and-free-at-u.patch of Package erlang
From f2acfa01d99b70cb8bda79b7886b9a3262e3a2d4 Mon Sep 17 00:00:00 2001
From: William Yang <mscame@gmail.com>
Date: Wed, 27 Nov 2024 10:16:38 +0100
Subject: [PATCH] crypto: Call EVP_MAC_fetch once at load and free at unload
In the doc of EVP_MAC_fetch(), https://docs.openssl.org/3.0/man3/EVP_MAC
"The returned value must eventually be freed with EVP_MAC_free(3)."
Co-authored-by: Sverker Eriksson <sverker@erlang.org>
Co-authored-by: William Yang <mscame@gmail.com>
---
lib/crypto/c_src/crypto.c | 1 +
lib/crypto/c_src/mac.c | 45 ++++++++++++++++++++++++++++++---------
lib/crypto/c_src/mac.h | 1 +
3 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index f37bd14f45..ab69292ffd 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -393,6 +393,7 @@ static void unload(ErlNifEnv* env, void* priv_data)
destroy_engine_mutex(env);
#ifdef HAS_3_0_API
+ fini_mac_types();
# ifdef FIPS_SUPPORT
if (fips_provider) {
OSSL_PROVIDER_unload(fips_provider);
diff --git a/lib/crypto/c_src/mac.c b/lib/crypto/c_src/mac.c
index 407501c367..83c9dbda36 100644
--- a/lib/crypto/c_src/mac.c
+++ b/lib/crypto/c_src/mac.c
@@ -41,6 +41,10 @@ struct mac_type_t {
}alg;
int type;
size_t key_len; /* != 0 to also match on key_len */
+#if defined(HAS_3_0_API)
+ const char* fetch_name;
+ EVP_MAC *evp_mac;
+#endif
};
/* masks in the flags field if mac_type_t */
@@ -59,6 +63,9 @@ static struct mac_type_t mac_types[] =
{EVP_PKEY_POLY1305}, POLY1305_mac, 32
#else
{EVP_PKEY_NONE}, NO_mac, 0
+#endif
+#if defined(HAS_3_0_API)
+ ,"POLY1305"
#endif
},
@@ -68,6 +75,9 @@ static struct mac_type_t mac_types[] =
#else
/* HMAC is always supported, but possibly with low-level routines */
{EVP_PKEY_NONE}, HMAC_mac, 0
+#endif
+#if defined(HAS_3_0_API)
+ ,"HMAC"
#endif
},
@@ -77,6 +87,9 @@ static struct mac_type_t mac_types[] =
{EVP_PKEY_CMAC}, CMAC_mac, 0
#else
{EVP_PKEY_NONE}, NO_mac, 0
+#endif
+#if defined(HAS_3_0_API)
+ ,"CMAC"
#endif
},
@@ -114,10 +127,26 @@ void init_mac_types(ErlNifEnv* env)
for (p = mac_types; p->name.str; p++) {
p->name.atom = enif_make_atom(env, p->name.str);
+#if defined(HAS_3_0_API)
+ p->evp_mac = EVP_MAC_fetch(NULL, p->fetch_name, NULL);
+#endif
}
p->name.atom = atom_false; /* end marker */
}
+void fini_mac_types(void)
+{
+#if defined(HAS_3_0_API)
+ struct mac_type_t* p = mac_types;
+
+ for (p = mac_types; p->name.str; p++) {
+ EVP_MAC_free(p->evp_mac);
+ p->evp_mac = NULL;
+ }
+#endif
+}
+
+
ERL_NIF_TERM mac_types_as_list(ErlNifEnv* env)
{
@@ -529,12 +558,13 @@ static void mac_context_dtor(ErlNifEnv* env, struct mac_context *obj)
if (obj == NULL)
return;
- if (obj->ctx)
+ if (obj->ctx) {
#if defined(HAS_3_0_API)
EVP_MAC_CTX_free(obj->ctx);
#else
EVP_MD_CTX_free(obj->ctx);
#endif
+ }
}
/*******************************************************************
@@ -560,10 +590,8 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ErlNifBinary key_bin;
ERL_NIF_TERM return_term;
# if defined(HAS_3_0_API)
- const char *name = NULL;
const char *digest = NULL;
const char *cipher = NULL;
- EVP_MAC *mac = NULL;
OSSL_PARAM params[3];
size_t params_n = 0;
# else
@@ -623,7 +651,6 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
goto err;
}
# if defined(HAS_3_0_API)
- name = "HMAC";
digest = digp->str_v3;
# else
if (digp->md.p == NULL)
@@ -675,7 +702,6 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
# if defined(HAS_3_0_API)
- name = "CMAC";
cipher = cipherp->str_v3;
# else
/* Old style */
@@ -691,9 +717,7 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
************/
# ifdef HAVE_POLY1305
case POLY1305_mac:
-# if defined(HAS_3_0_API)
- name = "POLY1305";
-# else
+# if !defined(HAS_3_0_API)
/* Old style */
/* poly1305 implies that EVP_PKEY_new_raw_private_key exists */
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305, /*engine*/ NULL, key_bin.data, key_bin.size);
@@ -716,8 +740,9 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/*-----------------------------------------
Common computations when we have 3.0 API
*/
- if (!(mac = EVP_MAC_fetch(NULL, name, NULL)))
+ if (!macp->evp_mac) {
assign_goto(return_term, err, EXCP_NOTSUP_N(env, 0, "Unsupported mac algorithm"));
+ }
if (cipher != NULL)
params[params_n++] =
@@ -730,7 +755,7 @@ ERL_NIF_TERM mac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if ((obj = enif_alloc_resource(mac_context_rtype, sizeof(struct mac_context))) == NULL)
assign_goto(return_term, err, EXCP_ERROR(env, "Can't allocate mac_context_rtype"));
- if (!(obj->ctx = EVP_MAC_CTX_new(mac)))
+ if (!(obj->ctx = EVP_MAC_CTX_new(macp->evp_mac)))
assign_goto(return_term, err, EXCP_ERROR(env, "Can't create EVP_MAC_CTX"));
if (!EVP_MAC_init(obj->ctx, key_bin.data, key_bin.size, params))
diff --git a/lib/crypto/c_src/mac.h b/lib/crypto/c_src/mac.h
index 5580d54d4c..a1d7183e87 100644
--- a/lib/crypto/c_src/mac.h
+++ b/lib/crypto/c_src/mac.h
@@ -26,6 +26,7 @@
int init_mac_ctx(ErlNifEnv *env, ErlNifBinary* rt_buf);
void init_mac_types(ErlNifEnv* env);
+void fini_mac_types(void);
ERL_NIF_TERM mac_types_as_list(ErlNifEnv* env);
--
2.43.0