Skip to content

Fix PKCS11 object leak in Pkcs11ECDH#9780

Open
mattia-moffa wants to merge 2 commits intowolfSSL:masterfrom
mattia-moffa:20260216-pkcs-ecdh-fixes
Open

Fix PKCS11 object leak in Pkcs11ECDH#9780
mattia-moffa wants to merge 2 commits intowolfSSL:masterfrom
mattia-moffa:20260216-pkcs-ecdh-fixes

Conversation

@mattia-moffa
Copy link
Contributor

Description

Pkcs11ECDH leaked two PKCS11 objects per ECDH operation:

  • The derived secret via C_DeriveKey is never destroyed after its value is extracted via C_GetAttributeValue
  • Ephemeral private keys generated by Pkcs11EcKeyGen (e.g. for TLS ECDHE) is not cleaned up. Pkcs11EcKeyGen intentionally leaves the private key alive for the subsequent Pkcs11ECDH call, but Pkcs11ECDH only destroys private keys created from raw scalar data (if (sessionKey)), not keys found via Pkcs11FindEccKey.

Reported via ZD#20700

Testing

./configure --enable-pkcs11

@mattia-moffa mattia-moffa self-assigned this Feb 16, 2026
@dgarske dgarske self-requested a review February 16, 2026 18:18
@dgarske
Copy link
Contributor

dgarske commented Feb 16, 2026

Jenkins retest this please. FIPS v3 no history

dgarske
dgarske previously approved these changes Feb 16, 2026
if (secret != CK_INVALID_HANDLE)
session->func->C_DestroyObject(session->handle, secret);

if (sessionKey) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check against NULL.

else {
ret = Pkcs11FindEccKey(&privateKey, CKO_PRIVATE_KEY, session,
info->pk.ecdh.public_key, CKA_DERIVE);
if (ret == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The private key lifecycle should be bound to the ECC object.
I don't think the private key should be destroyed here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be the best option. But AFAICT, we currently don't have logic to handle that case in the ecc_free() method. Would be a great addition, as we will also face the same issue once ML-KEM is added to the PKCS#11 interface (private decapsulation key must also be deleted once the handshake is done on the client side — I'm currently working on that ML-KEM integration).


if (sessionKey)
if (secret != CK_INVALID_HANDLE)
session->func->C_DestroyObject(session->handle, secret);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want the secret held on the device!
When doing TLS on the device, you don't want the secret to leave it. Instead the secret is used to generate the TLS session keys.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, the lifetime of the secret key object should be bound to the handshake duration, shouldn't it? Then, we can still use it in the future for potential key derivations on the external token via PKCS#11.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But do we have a way of binding it to the handshake duration from the wolfCrypt side?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants