JDK-8349163 : Switch to latest ML-KEM private key encoding
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.crypto
  • Priority: P2
  • Status: Draft
  • Resolution: Unresolved
  • Submitted: 2025-01-31
  • Updated: 2025-05-15
Related Reports
CSR :  
Description
Summary
-------

Update the ML-KEM private key encoding to align with Section 6 of draft-ietf-lamps-kyber-certificates-10. Specifically, the `privateKey` field in `OneAsymmetricKey` will follow the DER-encoded CHOICE structure as defined: it must contain one of the three permitted alternatives described in the draft.

Problem
-------

When ML-KEM was initially implemented in OpenJDK, earlier versions of draft-ietf-lamps-kyber-certificates described the private key simply as β€œan opaque byte sequence,” without specifying a concrete format. Based on that, we adopted the encoding defined in NIST FIPS 203 β€” specifically, the private key output from the ML-KEM.KeyGen function (Section 7.1 of FIPS 203).

In the final revision of the draft, the private key format has been formally defined as a DER-encoded ASN.1 CHOICE. For ML-KEM-512, for example:

	ML-KEM-512-PrivateKey ::= CHOICE {
		seed [0] OCTET STRING (SIZE (64)),
		expandedKey OCTET STRING (SIZE (1632)),
		both SEQUENCE {
	  		seed OCTET STRING (SIZE (64)),
	  		expandedKey OCTET STRING (SIZE (1632))
	  	}
	}

Similar structures are defined for ML-KEM-768 and ML-KEM-1024.

Our current implementation corresponds to the second choice, `expandedKey OCTET STRING`. To comply with the updated specification, we must update our implementation to support the other two choices as well.

Solution
--------

Update the ML-KEM private key encoding to support the new CHOICE structure. A new security or system property will control which of the three CHOICE options is used by the JDK.

When `KeyPairGenerator::generateKey` or `KeyFactory::translateKey` is invoked, the returned ML-KEM private key will be encoded using the selected format.

Note: If `KeyFactory::translateKey` is used to convert a key that lacks a seed into a format that includes the seed, the operation will fail and an `InvalidKeyException` will be thrown.

Specification
-------------

A new security property, `jdk.mlkem.pkcs8.encoding`, is introduced to control the encoding format of ML-KEM private keys in PKCS #8.

The following entry is added to the `java.security` file:

	#
	# The privateKey field for newly created ML-KEM private keys in PKCS #8
	#
	# The draft-ietf-lamps-kyber-certificates specification defines three formats
	# for an ML-KEM private key: a 64-byte seed, an expanded private key,
	# or a sequence containing both.
	#
	# Valid values for this property are "seed", "expandedKey", and "both"
	# (case-insensitive). The default is "seed".
	#
	# This property determines the encoding format used when a new keypair is
	# generated using a KeyPairGenerator, as well as the output of the translateKey
	# method on an existing key using a KeyFactory.
	#
	# If a system property of the same name is also specified, it supersedes the
	# security property value defined here.
	#
	# Note: This property is currently used by the SunJCE provider in the JDK
	# Reference implementation. It is not guaranteed to be supported by other
	# SE implementations.
	#
	#jdk.mlkem.pkcs8.encoding = seed
Comments
Re-affirming Approval for 24-pool.
31-01-2025

Serving as reviewer and moving to Approved.
31-01-2025