Encapsulation - ECIES
Added key encapsulation functions as a precursor for PQC. So far the only method is ECIES Need to confirm the value for the ECIES macro
Considering this API design in light of what we will need for ML-KEM (FIPS 203 - see #95): these might require different APIs?
The protocol for ML-KEM looks a bit like this:
Here, the key-pair is used something vaguely like a PKE key-pair: Bob uses Alice's encapsulation (public) key to encrypt some information that can be used to derive a shared secret. Alice can decrypt that information to derive the same secret. In this exchange, Bob could use a copy of Alice's kencaps provided in a trusted certificate, thus ensuring that only the real Alice (who has protected kdecaps, of course) will be able to correct derive the shared secret. But there is no authentication of Bob.
There is no concept of both parties having their own pair of keys, and using both their own private and the other participants public key for the encapsulation and decapsulation procedures - which is what the API for ECIES does above.
So, it does not seem possible that we can use the same API for ECIES and ML-KEM?
I've had a more detailed read-through of the ECIES definition (from SEC1 §5.1), and it seems that the shared secret construction is more similar to ML-KEM than I first thought.
Note that the proposal does not implement the whole of ECIES, purely the key establishment mechanism. The full definition of ECIES requires the participants to agree on a suite of parameters and choices with respect to encryption and authentication of the message to transmit (e.g. SharedInfo1/2, choice of encryption and MAC algorithms, etc.). In keeping with the low-level design of the Crypto API, this seems appropriate: the application can use the appropriate key derivation, encryption and MAC operations as required.
Summary of ECIES:
- In ECIES, one participant (A) creates a long term key pair, and publishes the public key (or provides it to the other participant, B).
- When transmitting an encrypted message to A, B uses A's public key and an ephemeral key-pair to create the shared secret - from which the keys for encrypting and authenticating the message are derived.
- B then sends the ephemeral public key, the encrypted message, and the authentication tag to A.
- A can then also construct the shared secret to verify and decrypt the message.
Here is a generalised version of the sequence diagram above:
Then for ECIES:
- kencaps and kdecaps are the public and private ECC keys for Alice.
- When Bob invokes Encaps() using kencaps, this creates the ephemeral key pair, computes the ECDH shared secret, and returns the ephemeral public key as the encaps-text, and the ECDH result as Kshared.
- When Alice invokes Decaps() with the provided encaps-text from Bob, and kdecaps, this copmutes the ECDH shared secret and returns this as Kshared.
- The use of the shared secret to construct keys for encryption and authentication of the message, or verifying and decrypting the ciphertext is up to the applications.
Thus, if we could adjust the proposed API to align it with what ML-KEM would require, the API could be common for the two algorithms:
-
psa_encapsulate_key()does not take a private key, but only a public key and generates the ephemeral key pair, providing the public part as the output buffer -
psa_decapsulate_key()takes a private key, and the buffer (sent from the other participant), and decodes the buffer as the other party's public key.
If this makes sense, then psa_encapsulate_key() will need to take the public key as a key handle (not as a key data buffer) - as this indicates the EC group over which the ECDH computation must happen.
From API perspective, KEM is very similiar to PKE (like ECIES or RSA.PKE), wouldn't be sufficient to extend the API around psa_asymmetric_encrypt and psa_asymmetric_decrypt to support all, ECIES, ML-KEM and FrodoKEM? The only problem seems to be with keys, ML-KEM in opposition to other schemes, consider decapsulation key as both, secret and public key due to the FO-Transformation, but due to usage of key handler in the API, only key_attributes needs to be set properly, no?
From API perspective, KEM is very similiar to PKE (like ECIES or RSA.PKE), wouldn't be sufficient to extend the API around
psa_asymmetric_encryptandpsa_asymmetric_decryptto support all, ECIES, ML-KEM and FrodoKEM?
There is a difference in the application expectation:
- With
psa_asymmetric_encrypt()the application supplies data to encrypt for transfer to the recipient. - KEM internally generates the shared secret (or its seed), and encrypts (encapsulates) that for transfer, there is no application data involved at this step.
From an application perspective, ECIES looks similar to asymmetric encryption, but uses public-key cryptography only to establish a shared secret for use in encryption of the message. This is difficult to encode within the PSA API for asymmetric encryption, as the algorithm specification has to include the the KDF used to derived the encryption/MAC keys from the shared secret, the cipher algorithm, and the MAC algorithm. Combined key agreement with key derivation we already have, but we cannot also flexibly specify the cipher and MAC components required for ECIES in a single algorithm id.
However, a lower level API for ECIES seems to fit well with the PSA Crypto API design, as suggested above. This provides the flexibility for application selection of cipher suites for the encryption/authentication, and aligns with the behavior of KEM algorithms.
Hopefully this check in addresses Andrew's comment from March, apologies for the delay.