Hybrid Public Key Encryption (HPKE) Functionality #866

Open
LeonieReichertABB wants to merge 2 commits from LeonieReichertABB/hpke-functionality into development
LeonieReichertABB commented 2026-08-06 07:18:12 -05:00 (Migrated from github.com)

Description

This PR adds Hybrid Public Key Encryption (HPKE), as specified in RFC 9180, as functionality.

The current implementation supports the base mode using the ciphersuite DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM. Tests have been added for the supported ciphersuite. Support for the remaining RFC-defined KEM, KDF, and AEAD combinations will be added in follow-up pull requests.

During development, AI assistance by Github Copilot was used to understand the migration from the Mbed TLS 3.6 APIs to version 4 APIs, for writing the changelog and for understanding what defines are required in crypto_adjust_config_enable_builtins.h.
The remainder of the implementation was written and verified manually.

PR checklist

Please remove the segment/s on either side of the | symbol as appropriate, and add any relevant link/s to the end of the line.
If the provided content is part of the present PR remove the # symbol.

  • changelog provided
  • framework PR not required because: no changes to framework
  • TF-PSA-Crypto development PR provided #
  • TF-PSA-Crypto 1.1 PR not required because: new feature
  • mbedtls development PR not required because: crypto only
  • mbedtls 4.1 PR not required because: crypto only
  • mbedtls 3.6 PR not required because: crypto only
  • tests provided
## Description This PR adds Hybrid Public Key Encryption (HPKE), as specified in RFC 9180, as functionality. The current implementation supports the base mode using the ciphersuite DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM. Tests have been added for the supported ciphersuite. Support for the remaining RFC-defined KEM, KDF, and AEAD combinations will be added in follow-up pull requests. During development, AI assistance by Github Copilot was used to understand the migration from the Mbed TLS 3.6 APIs to version 4 APIs, for writing the changelog and for understanding what defines are required in crypto_adjust_config_enable_builtins.h. The remainder of the implementation was written and verified manually. ## PR checklist Please remove the segment/s on either side of the | symbol as appropriate, and add any relevant link/s to the end of the line. If the provided content is part of the present PR remove the # symbol. - [x] **changelog** provided - [x] **framework PR** not required because: no changes to framework - [x] **TF-PSA-Crypto development PR** provided # - [x] **TF-PSA-Crypto 1.1 PR** not required because: new feature - [x] **mbedtls development PR** not required because: crypto only - [x] **mbedtls 4.1 PR** not required because: crypto only - [x] **mbedtls 3.6 PR** not required because: crypto only - **tests** provided
gilles-peskine-arm (Migrated from github.com) requested changes 2026-08-06 08:19:39 -05:00
gilles-peskine-arm (Migrated from github.com) left a comment

Thank you for offering this contribution. Before we start the review process, we're going to need to discuss the design and planning.

Due to a heavy security load (like many open source projects), we currently have extremely limited bandwidth for functionality. Due to the size of this feature, if Arm participates, we will need a business case to be discussed with our product manager. It is extremely unlikely that this would be prioritized over the basics of PQC support, and that already claims most of our 2027 bandwidth.

In terms of design, if the PSA Crypto API needs to be extended (but I think it doesn't), a discussion needs to happen in GlobalPlatform. Arm can drive the discussion on your behalf if you are not a member (once we have a business case for spending our bandwidth).

Then we need to have a discussion on the design of the software interface where not covered by PSA (e.g. higher-level functions, configuration mechanism), and on the design of the implementation. The discussion would be with a member of the TF-PSA-Crypto maintainer team, probably me.

Thank you for offering this contribution. Before we start the review process, we're going to need to discuss the design and planning. Due to a heavy security load (like many open source projects), we currently have extremely limited bandwidth for functionality. Due to the size of this feature, if Arm participates, we will need a business case to be discussed with our product manager. It is extremely unlikely that this would be prioritized over the basics of PQC support, and that already claims most of our 2027 bandwidth. In terms of design, if the PSA Crypto API needs to be extended (but I think it doesn't), a discussion needs to happen in GlobalPlatform. Arm can drive the discussion on your behalf if you are not a member (once we have a business case for spending our bandwidth). Then we need to have a discussion on the design of the software interface where not covered by PSA (e.g. higher-level functions, configuration mechanism), and on the design of the implementation. The discussion would be with a member of the TF-PSA-Crypto maintainer team, probably me.
@ -0,0 +1,16 @@
Features
* Add support for HPKE (RFC 9180) in the built-in PSA crypto driver.
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 08:03:49 -05:00

We wouldn't want to add code to the built-in driver for things that can be done generically above the standard PSA API. Are there any parts of HPKE that cannot be built on top of the PSA API?

If HPKE needs new primitives, these will need to be added to the API specification. We're ok with adopting a specification draft, but the discussion must at least be underway.

We wouldn't want to add code to the built-in driver for things that can be done generically above the standard PSA API. Are there any parts of HPKE that cannot be built on top of the PSA API? If HPKE needs new primitives, these will need to be [added to the API specification](https://github.com/GlobalPlatform/psa-api/issues). We're ok with adopting a specification draft, but the discussion must at least be underway.
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 08:06:18 -05:00

PSA_WANT_ALG_HPKE means that PSA_ALG_HPKE is enabled, but there is no such algorithm. And HKPE does not seem to fit the PSA algorithm paradigm anyway.

`PSA_WANT_ALG_HPKE` means that `PSA_ALG_HPKE` is enabled, but there is no such algorithm. And HKPE does not seem to fit the PSA algorithm paradigm anyway.
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 08:07:47 -05:00

It looks like PSA_WANT_ALG_HPKE enables all of the algorithms for one specific HKPE suite, which doesn't make sense: what if users want a different suite?

It looks like `PSA_WANT_ALG_HPKE` enables all of the algorithms for one specific HKPE suite, which doesn't make sense: what if users want a different suite?
@ -0,0 +8,4 @@
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
algorithms mechanisms so HPKE prerequisites are configured.
* Rework HPKE-related built-in selection in
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 08:04:53 -05:00

This is an internal detail and doesn't belong in a changelog entry.

This is an internal detail and doesn't belong in a changelog entry.
LeonieReichertABB (Migrated from github.com) reviewed 2026-08-06 09:15:51 -05:00
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
LeonieReichertABB (Migrated from github.com) commented 2026-08-06 09:15:51 -05:00

I assume, this would be defined in crypto_values.h ? I will add it there.

I assume, this would be defined in crypto_values.h ? I will add it there.
LeonieReichertABB (Migrated from github.com) reviewed 2026-08-06 09:16:43 -05:00
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
LeonieReichertABB (Migrated from github.com) commented 2026-08-06 09:16:42 -05:00

So far only one ciphersuite is implemented. I want to add support for the other ciphersuites later and would adapt the defines accordingly.

Would you prefer a different approach?

So far only one ciphersuite is implemented. I want to add support for the other ciphersuites later and would adapt the defines accordingly. Would you prefer a different approach?
gilles-peskine-arm (Migrated from github.com) reviewed 2026-08-06 09:37:03 -05:00
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 09:37:03 -05:00

What would PSA_ALG_HKPE do? What category of algorithms does it fit under? What functions perform operations using this algorithm?

What would `PSA_ALG_HKPE` do? What category of algorithms does it fit under? What functions perform operations using this algorithm?
gilles-peskine-arm (Migrated from github.com) reviewed 2026-08-06 09:37:58 -05:00
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
gilles-peskine-arm (Migrated from github.com) commented 2026-08-06 09:37:57 -05:00

PSA_WANT_ALG_HPKE should enable the generic functionality, not all the cipher suites. Like PSA_WANT_ALG_ECDH enables ECDH but not all the supported elliptic curves, which need to be enabled separately as desired.

`PSA_WANT_ALG_HPKE` should enable the generic functionality, not all the cipher suites. Like `PSA_WANT_ALG_ECDH` enables ECDH but not all the supported elliptic curves, which need to be enabled separately as desired.
LeonieReichertABB (Migrated from github.com) reviewed 2026-08-06 10:26:19 -05:00
@ -0,0 +1,16 @@
Features
* Add support for HPKE (RFC 9180) in the built-in PSA crypto driver.
LeonieReichertABB (Migrated from github.com) commented 2026-08-06 10:26:19 -05:00

HPKE relies on some mbedtls_mpi functionalities for deriving nonces and therefore requires private access. All other calls are function calls of the format psa_[function_name].

HPKE relies on some mbedtls_mpi functionalities for deriving nonces and therefore requires private access. All other calls are function calls of the format psa_[function_name].
LeonieReichertABB commented 2026-08-06 10:28:58 -05:00 (Migrated from github.com)

Thank you for all the detailed comments! I will address them one after another and adapt the PR accordingly.
This is my first time contributing to MbedTLS, I am sorry for any inconveniences.

Thank you for all the detailed comments! I will address them one after another and adapt the PR accordingly. This is my first time contributing to MbedTLS, I am sorry for any inconveniences.
LeonieReichertABB (Migrated from github.com) reviewed 2026-08-06 12:10:32 -05:00
@ -0,0 +1,16 @@
Features
* Add support for HPKE (RFC 9180) in the built-in PSA crypto driver.
LeonieReichertABB (Migrated from github.com) commented 2026-08-06 12:10:32 -05:00

Maybe my phrasing of built-in is wrong here?

Maybe my phrasing of built-in is wrong here?
LeonieReichertABB (Migrated from github.com) reviewed 2026-08-06 12:51:45 -05:00
@ -0,0 +6,4 @@
DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and AES-128-GCM.
Changes
* When PSA_WANT_ALG_HPKE is enabled, automatically request the dependent
LeonieReichertABB (Migrated from github.com) commented 2026-08-06 12:51:44 -05:00

HPKE uses a set of building bocks like a KEM, a hash function and a block cipher to build an encryption scheme that simplifies sending large blocks of data if only a public key of the receiver is available.
HPKE has its own key schedule, that's why private access is required.

I am new to this, so I looked at a some PSA_WANT_ALG_* definitions as a blueprint of how to define the algorithm.

Following that logic (and assuming that HPKE belongs with the built-in functions), this would mean the following changes have to be made.

  1. The defines in crypto_adust_config_enalbe_buitins.h need to look as follows:
#if defined(PSA_WANT_ALG_HPKE)
#define PSA_HPKE_C

#if defined(PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCM)
#define PSA_WANT_ALG_ECDH
#define PSA_WANT_ECC_MONTGOMERY_255
.....
#endif /* PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCM */
#endif /* PSA_WANT_ALG_HPKE *
  1. Both PSA_WANT_ALG_HPKE and PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCMneed to be defined in include/psa/crypto_config.h.

  2. Correctness checks of enabled features are required in core/check_crypto_config.h.

Is this correct?

HPKE uses a set of building bocks like a KEM, a hash function and a block cipher to build an encryption scheme that simplifies sending large blocks of data if only a public key of the receiver is available. HPKE has its own key schedule, that's why private access is required. I am new to this, so I looked at a some PSA_WANT_ALG_* definitions as a blueprint of how to define the algorithm. Following that logic (and assuming that HPKE belongs with the built-in functions), this would mean the following changes have to be made. 1) The defines in _crypto_adust_config_enalbe_buitins.h_ need to look as follows: ``` #if defined(PSA_WANT_ALG_HPKE) #define PSA_HPKE_C #if defined(PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCM) #define PSA_WANT_ALG_ECDH #define PSA_WANT_ECC_MONTGOMERY_255 ..... #endif /* PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCM */ #endif /* PSA_WANT_ALG_HPKE * ``` 2) Both PSA_WANT_ALG_HPKE and PSA_WANT_ALG_HPKE_DHKEM_X25519_HKDF_SHA256_AES_128_GCMneed to be defined in _include/psa/crypto_config.h_. 3) Correctness checks of enabled features are required in _core/check_crypto_config.h._ Is this correct?
This pull request is broken due to missing fork information.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 'LeonieReichertABB/hpke-functionality:LeonieReichertABB/hpke-functionality'
git switch 'LeonieReichertABB/hpke-functionality'

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch 'development'
git merge --no-ff 'LeonieReichertABB/hpke-functionality'
git switch 'LeonieReichertABB/hpke-functionality'
git rebase 'development'
git switch 'development'
git merge --ff-only 'LeonieReichertABB/hpke-functionality'
git switch 'LeonieReichertABB/hpke-functionality'
git rebase 'development'
git switch 'development'
git merge --no-ff 'LeonieReichertABB/hpke-functionality'
git switch 'development'
git merge --squash 'LeonieReichertABB/hpke-functionality'
git switch 'development'
git merge --ff-only 'LeonieReichertABB/hpke-functionality'
git switch 'development'
git merge 'LeonieReichertABB/hpke-functionality'
git push origin 'development'
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Mbed-TLS/TF-PSA-Crypto!866
No description provided.