Skip to content

lib: ecdh1 derive: add support for CKD_SHA1_KDF key derivation function#918

Open
hnez wants to merge 6 commits into
tpm2-software:masterfrom
hnez:ecdh-kdf
Open

lib: ecdh1 derive: add support for CKD_SHA1_KDF key derivation function#918
hnez wants to merge 6 commits into
tpm2-software:masterfrom
hnez:ecdh-kdf

Conversation

@hnez

@hnez hnez commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for the CKD_SHA1_KDF key derivation function to the Elliptic Curve Diffie Helman functionality in tpm2-pkcs11.

This Fixes #914 (at least partially).

Some more work is required to get it fully working:

Comment thread test/integration/pkcs-ecdh.int.c Outdated
key[0].shr = malloc(shr_len);
key[1].shr = malloc(shr_len);
memset(key[0].shr, 0, shr_len);
memset(key[0].shr, 1, shr_len);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be key[1]?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, yes indeed. I have replaced the copied steps with a loop.

Comment thread test/integration/pkcs-ecdh.int.c Outdated
};

key[0].shr = malloc(shr_len);
key[1].shr = malloc(shr_len);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Check for malloc failures. Use the cmocka macros for null check. I just want an OOM failure to be obvious.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. I have added checks.

Comment thread src/lib/derive.c
shared_secret_attr.pValue = calloc(shared_secret_attr.ulValueLen,
sizeof(CK_BYTE));

EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This can return NULL, so we need a check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was not to sure about which error messages to return in that case. I hope the ones I chose make some sense.

Comment thread src/lib/derive.c
sizeof(CK_BYTE));

EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL);
EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could fail as well, so we need a check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ack

Comment thread src/lib/derive.c Outdated
EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL);
EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);

OSSL_PARAM params[4], *p = params;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do I need p here? Can't I just do something like parms[0] =, parms[1] =. This hides the underlying storage IMO. All those code paths succeed, so p always gets incremented, the constants I think will make that more clear as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This seems to be a common pattern in code that sets up OSSL_PARAM arrays, which I just copied.
I guess it makes sense when setting up an array in code with a lot of conditional expressions, because it becomes difficult to keep track of the current array index in that case.
Since the control flow is rather easy here I agree that we do not have to do it this way.
I have changed the code accordingly.

hnez added 2 commits May 29, 2026 10:23
This more closely matches the TPM2 ESAPI function it wraps in both name
and functionality. A complete derivation may involve running a key
derivation function on the output tpm_ec_ecdh_zgen().

Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
Move the check for which kdf function to run down to after the Z point
generation.

This requires some more cleanup if a non-supported KDF is used, but
makes it easier to add more KDFs (besides CKD_NULL).

Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
hnez added 4 commits June 1, 2026 10:46
This allows generating shared secrets of arbitrary length by using SHA1
as a key derivation function.
There are other possible KDFs, but this one is the default used by
`openssl cms -encrypt` and thus one of the most interesting ones to
implement.

Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
This is in preparation to adding other KDFs to the test suite.

Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
When a key derivation function is used the shared secret can have an
arbitrary length, independent from the elliptic curve key size.

Prepare for adding KDF support by making the shared secret size dynamic.

Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
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.

lib: ecdh1 derive: is missing non-null KDF

2 participants