]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix function pointer type mismatch when freeing ECX keys
author007bsd <22483432+007bsd@users.noreply.github.com>
Mon, 4 May 2026 17:07:29 +0000 (20:07 +0300)
committerNorbert Pocs <norbertp@openssl.org>
Thu, 14 May 2026 09:31:27 +0000 (11:31 +0200)
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)

providers/implementations/keymgmt/ecx_kmgmt.c

index 8489ce2248b55d5c1676d367c4b154cbefb2cd38..d63fdd406ae60857be428bac3aa3e7df492ded2d 100644 (file)
@@ -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 },           \