mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
The README described how to regenerate the ML-KEM certificates in prose, which amounts to "write a program". They are produced by certs/renewcerts.sh instead, using the same OpenSSL 3.5 or newer binary its ML-DSA section already requires. An ML-KEM key cannot sign, so it can sign neither a certificate nor a certificate request. Each certificate therefore comes from a throwaway request carrying only the subject name, with x509 -req -force_pubkey swapping in the ML-KEM public key before the ML-DSA-87 test CA signs it, and keyUsage marked critical asserting keyEncipherment and nothing else, per RFC 9935 Section 5. The keys are written in the priv-only PKCS#8 shape, which is the RFC 9935 Section 6 expandedKey form: that decodes in a build without key generation, which the seed form does not. ML-KEM is probed separately from ML-DSA so a binary carrying one provider and not the other still regenerates what it can. The MLKEM_TYPE certificate generation paths had no coverage, so mlkem_certgen_test drives wc_MakeCert_ex, wc_SignCert_ex and wc_SetSubjectKeyIdFromPublicKey_ex for all three parameter sets. It signs with ECDSA rather than ML-DSA, which is available in far more builds and which the paths under test do not care about.
ML-KEM (FIPS 203) test key material for wolfSSL tests.
Per level N in {512, 768, 1024}:
mlkem<N>-cert.der ML-KEM end-entity certificate, DER
mlkem<N>-key.der matching private key, PKCS#8 DER (expandedKey form)
A KEM cannot sign, so these certificates cannot be self-signed. Each is
issued by the ML-DSA-87 test key in certs/mldsa, so certs/mldsa/mldsa87-cert.der
is the issuer and certs/mldsa/mldsa87-key.der signed them.
The certificates follow the CNSA 2.0 profile for a key establishment
certificate: the keyUsage extension is marked critical and asserts
keyEncipherment alone. The subjectPublicKeyInfo algorithm is
2.16.840.1.101.3.4.4.N with the parameters field absent, and the signature
algorithm is 2.16.840.1.101.3.4.3.19 (ML-DSA-87).
Regenerate them with certs/renewcerts.sh, which needs an OpenSSL 3.5+ binary
with the built-in ML-DSA and ML-KEM providers. The ML-DSA section runs first
and produces the issuer; the ML-KEM section then builds each certificate from
a throwaway request whose public key is replaced with the ML-KEM one
("x509 -req -force_pubkey"), because ML-KEM cannot sign a request either.
The private keys are written with -provparam ml-kem.output_formats=priv-only,
which is the RFC 9935 section 6 expandedKey shape. That form decodes without
expanding a seed, so the tests pass in WOLFSSL_MLKEM_NO_MAKE_KEY builds too;
the OpenSSL default (seed and expanded key together) would not.
The keys are freshly generated on every run, so the bytes differ each time;
only the structure is reproducible. The files committed here were produced by
wolfSSL itself before renewcerts.sh could make them, so a regenerated
certificate also carries an authorityKeyIdentifier that the committed ones do
not. Nothing in the test suite depends on that.
These are shared test credentials. Never use them in production.