Commit 012cc567d0 for openssl.org
commit 012cc567d00ab6e899cf3dc7c2845ec4cd68c1ff
Author: 007bsd <22483432+007bsd@users.noreply.github.com>
Date: Mon May 4 20:07:29 2026 +0300
Fix function pointer type mismatch when freeing ECX keys
ossl_ecx_key_free is declared as void(ECX_KEY *) but registered
directly in the X25519/X448/Ed25519/Ed448 keymgmt OSSL_DISPATCH
tables for OSSL_FUNC_KEYMGMT_FREE, which is invoked through a
void(*)(void *) pointer in evp_keymgmt_freedata. Calling a function
through a pointer to an incompatible function type is undefined
behavior and is reported by UndefinedBehaviorSanitizer on every
ECX key free:
crypto/evp/keymgmt_meth.c:392:5: runtime error: call to function
ossl_ecx_key_free through pointer to incorrect function type
'void (*)(void *)'
crypto/ec/ecx_key.c:65: note: ossl_ecx_key_free defined here
All four algorithms share the same MAKE_KEYMGMT_FUNCTIONS dispatch
macro, so they hit the same UB; UBSan just deduplicates the report
on the first call.
Mirror the wrapper pattern used by ml_kem_free_key, ml_dsa_free_key,
slh_dsa_free_key, dsa_freedata, ec_freedata, and lms_free_key: add
a small static ecx_free_key with the correct OSSL_FUNC_keymgmt_free_fn
signature that forwards to ossl_ecx_key_free, and register the
wrapper in the dispatch macro. The existing direct callers of
ossl_ecx_key_free in ecx_kmgmt.c are unchanged since they pass a
typed ECX_KEY *.
CLA: trivial
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Paul Yang <paulyang.inf@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu May 14 09:31:58 2026
(Merged from https://github.com/openssl/openssl/pull/31078)
diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index 8489ce2248..d63fdd406a 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -35,6 +35,7 @@ static OSSL_FUNC_keymgmt_new_fn x25519_new_key;
static OSSL_FUNC_keymgmt_new_fn x448_new_key;
static OSSL_FUNC_keymgmt_new_fn ed25519_new_key;
static OSSL_FUNC_keymgmt_new_fn ed448_new_key;
+static OSSL_FUNC_keymgmt_free_fn ecx_free_key;
static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init;
static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init;
static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init;
@@ -993,10 +994,15 @@ static int ed448_validate(const void *keydata, int selection, int checktype)
return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
}
+static void ecx_free_key(void *keydata)
+{
+ ossl_ecx_key_free((ECX_KEY *)keydata);
+}
+
#define MAKE_KEYMGMT_FUNCTIONS(alg) \
const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
- { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
+ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_free_key }, \
{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))alg##_get_params }, \
{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))alg##_gettable_params }, \
{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))alg##_set_params }, \