From 2eeb8965edcada0de799ac2d563a297aa938b810 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 23 Jun 2026 14:35:36 +0200 Subject: [PATCH] pkcs11: Fix ECDH derivation The referenced commit moved the key derivation to `get_shared_secret()` and broke the handling of ECDH public value as the copied struct now referred to a buffer allocated on the stack. Also fixes potential session leaks if generating key pairs fails. Fixes: 26ca0c9f70ed ("pkcs11: Move shared secret calculation to get_shared_secret()") --- src/libstrongswan/plugins/pkcs11/pkcs11_dh.c | 38 +++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c index 892bb5b47..73a0b6573 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c @@ -100,9 +100,32 @@ static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other) other.ptr, other.len, }; + CK_ECDH1_DERIVE_PARAMS ecdh_params = { + CKD_NULL, + 0, + NULL, + other.len, + other.ptr, + }; CK_OBJECT_HANDLE secret; CK_RV rv; + switch (this->group) + { + case ECP_192_BIT: + case ECP_224_BIT: + case ECP_256_BIT: + case ECP_384_BIT: + case ECP_521_BIT: + { + mech.pParameter = &ecdh_params; + mech.ulParameterLen = sizeof(ecdh_params); + break; + } + default: + break; + } + rv = this->lib->f->C_DeriveKey(this->session, &mech, this->pri_key, attr, countof(attr), &secret); if (rv != CKR_OK) @@ -137,16 +160,7 @@ METHOD(key_exchange_t, set_public_key, bool, case ECP_521_BIT: { /* we expect the public value to just be the concatenated x and y * coordinates, so we tag the value as an uncompressed ECPoint */ - chunk_t tag = chunk_from_chars(0x04); - chunk_t pubkey = chunk_cata("cc", tag, value); - CK_ECDH1_DERIVE_PARAMS params = { - CKD_NULL, - 0, - NULL, - pubkey.len, - pubkey.ptr, - }; - this->other = chunk_clone(chunk_from_thing(params)); + this->other = chunk_cat("cc", chunk_from_chars(0x04), value); break; } default: @@ -368,7 +382,7 @@ static pkcs11_dh_t *create_ecp(key_exchange_method_t group, chunk_t ecparam) return &this->public; } chunk_free(&ecparam); - free(this); + destroy(this); } return NULL; } @@ -388,7 +402,7 @@ static pkcs11_dh_t *create_modp(key_exchange_method_t group, size_t exp_len, { return &this->public; } - free(this); + destroy(this); } return NULL; }