Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8349163

Switch to latest ML-KEM private key encoding

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P2 P2
    • None
    • security-libs
    • None
    • behavioral
    • minimal
    • ML-KEM is new in JDK 24.
    • File or wire format
    • Implementation

      Summary

      Update the ML-KEM and ML-DSA private key encodings to align with Section 6 of draft-ietf-lamps-kyber-certificates-11 and Section 6 of draft-ietf-lamps-dilithium-certificates-12. Specifically, the privateKey field inside the PKCS #8 encoding will follow the DER-encoded CHOICE structure as defined. All 3 CHOICEs will be supported at encoding and decoding.

      Problem

      When ML-KEM and ML-DSA were initially introduced in OpenJDK, earlier versions of draft-ietf-lamps-kyber-certificates and draft-ietf-lamps-dilithium-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), and NIST FIPS 204 β€” specifically, the private key part of the return value from the ML-DSA.KeyGen function (Section 5.1 of FIPS 204).

      In the latest revision of the drafts, the private key format is 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, ML-KEM-1024, ML-DSA-44, ML-DSA-65, and ML-DSA-87.

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

      Solution

      For reading, all three CHOICEs are accepted when parsing an existing PKCS #8 encoded private key.

      For writing, two security properties control which of the three CHOICEs is used when creating a new private key:

      When KeyPairGenerator::generateKey or KeyFactory::translateKey is called, the resulting private key will be encoded using the selected format.

      Note: If KeyFactory::translateKey is used to convert a key that does not contain a seed into a format that requires the seed, the operation will fail with an InvalidKeyException.

      Specification

      New security properties, jdk.mlkem.pkcs8.encoding and jdk.mldsa.pkcs8.encoding, are introduced to control the PKCS #8 encoding of newly created ML-KEM and ML-DSA private keys.

      The following is added to the java.security file:

      #
      # Newly created ML-KEM and ML-DSA private key formats in PKCS #8
      #
      # The draft-ietf-lamps-kyber-certificates and draft-ietf-lamps-dilithium-certificates
      # specifications define three formats for a private key: a seed (64 bytes for ML-KEM,
      # 32 bytes for ML-DSA), an expanded private key, or a sequence containing both.
      #
      # Valid values for these properties are "seed", "expandedKey", and "both"
      # (case-insensitive). The default is "seed".
      #
      # These properties determine 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 ML-KEM or ML-DSA KeyFactory.
      #
      # If a system property of the same name is also specified, it supersedes the
      # security property value defined here.
      #
      # Note: These properties are currently used by the SunJCE (for ML-KEM) and SUN
      # (for ML-DSA) providers in the JDK Reference implementation. They are not guaranteed
      # to be supported by other SE implementations or third-party security providers.
      #
      #jdk.mlkem.pkcs8.encoding = seed
      #jdk.mldsa.pkcs8.encoding = seed

            weijun Weijun Wang
            weijun Weijun Wang
            Joe Darcy
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: