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 },           \