Use of the Elliptic Curve Diffie-Hellman Key Agreement Algorithm with X25519 and X448 in the Cryptographic Message Syntax (CMS)
Extracted elements (21)
Two KDF options are provided—ANSI-X9.63-KDF (for compatibility with existing CMS ECC usage) and HKDF (a more robust modern construction)—allowing implementors to choose based on interoperability needs versus cryptographic strength preference.
CMS requires implementations to accept a KeyAgreeRecipientInfo SEQUENCE that includes the ukm field, ensuring interoperability whether the ukm is present or absent.
The conventions in this document cover X25519 and X448 specifically; other elliptic curves used with ECDH in CMS are covered by RFC 5753 and are not deprecated by this document.
A content-encryption key MUST be randomly generated for each instance of an enveloped-data content type, and similarly an authentication key MUST be randomly generated for each authenticated-data instance.
Conforming implementations MUST check whether the computed Diffie-Hellman shared secret is the all-zero value and abort if so, as described in Section 6 of RFC 7748.
For recipients that use X25519 or X448, the RecipientInfo kari (KeyAgreeRecipientInfo) choice MUST be used in EnvelopedData, AuthenticatedData, and AuthEnvelopedData.
If an alternative implementation of X25519/X448 is employed (other than as documented in Section 6 of RFC 7748), the additional checks specified in Section 7 of RFC 7748 SHOULD be performed.
The KeyAgreeRecipientInfo version MUST be 3, the originatorKey alternative MUST be used, the originatorKey algorithm field MUST contain id-X25519 or id-X448, and the originator's ephemeral public key MUST be encoded as an OCTET STRING.
The originator MUST use an ephemeral public/private key pair generated on the same elliptic curve as the recipient's public key, and the ephemeral key pair MUST be used for a single CMS-protected content type and then discarded.
The RecipientEncryptedKey KeyAgreeRecipientIdentifier MUST contain either the issuerAndSerialNumber or the RecipientKeyIdentifier (subject key identifier) from the recipient's certificate, which contains the recipient's static X25519 or X448 public key.
When the ukm field is present, it MUST be selected in a manner that provides, with very high probability, a unique value; however there is no security benefit to using a ukm value longer than the KEK produced by the KDF.
When there is more than one recipient in enveloped-data, authenticated-data, or authenticated-enveloped-data, the same content-encryption (or authentication) key MUST be wrapped for each recipient.
A sending agent MAY announce X25519/X448 ECDH support via the SMIMECapabilities signed attribute; the capability value is a DER-encoded OID identifying the ECDH+KDF combination with a parameter naming the key wrap algorithm.
The ANSI-X9.63-KDF produces the KEK by hashing K || INT32(counter) || DER(ECC-CMS-SharedInfo), incrementing the counter from 0x00000001 for each KM block and concatenating results until sufficient keying material is obtained.
The ECC-CMS-SharedInfo structure used for KDF input contains three fields: keyInfo (key-encryption algorithm OID and parameters), entityUInfo (optional additional keying material / ukm), and suppPubInfo (KEK length in bits as a 32-bit network-byte-order value).
The HKDF variant uses HKDF-Extract(salt=ukm, K) to produce PRK, then HKDF-Expand(PRK, DER(ECC-CMS-SharedInfo), SizeInOctets(KEK)) to produce the KEK; if no ukm is provided, HKDF uses an all-zero salt.
Three new HKDF-based key agreement algorithm OIDs are defined under smime-alg: dhSinglePass-stdDH-hkdf-sha256-scheme (smime-alg 19), dhSinglePass-stdDH-hkdf-sha384-scheme (smime-alg 20), and dhSinglePass-stdDH-hkdf-sha512-scheme (smime-alg 21).
Three OIDs for HKDF-based ECDH schemes (dhSinglePass-stdDH-hkdf-sha256/384/512-scheme) were registered in the 'SMI Security for S/MIME Algorithms (1.2.840.113549.1.9.16.3)' registry, and one OID (id-mod-cms-ecdh-alg-2017) was registered in the S/MIME Module Identifiers registry.
Implementations MUST support processing of the KeyAgreeRecipientInfo ukm field; when present, the ukm ensures a different KEK is generated even if the originator's ephemeral private key is improperly reused.
The originator's ephemeral key pair is used for a single CMS protected content type and then discarded; if the originator wants to decrypt (or verify authentication of) the content, the originator must treat themselves as a recipient.
When using X25519 the public key is exactly 32 octets, encoded as an OCTET STRING under id-X25519 { 1 3 101 110 }; when using X448 the public key is exactly 56 octets under id-X448 { 1 3 101 111 }.