Skip to content

Commit

Permalink
crypto: Call EVP_MAC_fetch once at load and free at unload
Browse files Browse the repository at this point in the history
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: John Högberg <[email protected]>
Co-authored-by: William Yang <[email protected]>
  • Loading branch information
qzhuyan and jhogberg committed Dec 4, 2024
1 parent 9023fd6 commit fceb55c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
1 change: 1 addition & 0 deletions lib/crypto/c_src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ static void unload(ErlNifEnv* env, void* priv_data)
destroy_engine_mutex(env);

#ifdef HAS_3_0_API
fini_mac_types();
while (prov_cnt > 0) {
OSSL_PROVIDER_unload(prov[--prov_cnt]);
}
Expand Down
45 changes: 35 additions & 10 deletions lib/crypto/c_src/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
},

Expand All @@ -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
},

Expand All @@ -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
},

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
}
}

/*******************************************************************
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand All @@ -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);
Expand All @@ -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++] =
Expand All @@ -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))
Expand Down
1 change: 1 addition & 0 deletions lib/crypto/c_src/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit fceb55c

Please sign in to comment.