Skip to content

Add ML-KEM and ML-DSA support#399

Open
aidangarske wants to merge 16 commits into
wolfSSL:masterfrom
aidangarske:pqc-support
Open

Add ML-KEM and ML-DSA support#399
aidangarske wants to merge 16 commits into
wolfSSL:masterfrom
aidangarske:pqc-support

Conversation

@aidangarske
Copy link
Copy Markdown
Member

ML-KEM (FIPS 203) and ML-DSA (FIPS 204) via wolfSSL backend.

Algorithms: ML-KEM-512/768/1024, ML-DSA-44/65/87

Opt-in: ./scripts/build-wolfprovider.sh --enable-pqc (adds --enable-mlkem --enable-dilithium --enable-experimental to wolfSSL). wolfProvider auto-detects from wolfSSL's options.h macros; older wolfSSL builds skip the PQC paths cleanly with no code changes here.

Validation: three independent paths cross-checked, all pass.

  • Internal unit tests (11 functions x 3 levels = 33 assertions) in make test
  • wolfProvider <-> OpenSSL 3.5 default provider (12 cross-pairs)
  • wolfProvider <-> wolfSSL direct wc_* API (12 cross-pairs)

CI: new wolfssl-versions-pqc.yml runs three matrix rows -- pre-PQC wolfSSL, latest stable, master -- and the three-way interop validator on the PQC-enabled rows.

Test plan

  • make test passes (all 11 PQC tests + existing suite)
  • ./test/pqc_interop.test -- ALL PASS (24 cross-pairs)
  • Build against pre-PQC wolfSSL: PQC code paths skip, make test clean
  • CI green on all three matrix rows

Copilot AI review requested due to automatic review settings May 23, 2026 05:56

This comment was marked as resolved.

@aidangarske aidangarske self-assigned this May 23, 2026
@aidangarske aidangarske marked this pull request as ready for review May 26, 2026 17:13
Copy link
Copy Markdown

@Frauschi Frauschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some smaller findings. The biggest "issue" imo is the usage of the now old ML-DSA API instead of the new one. But moving this to the new one should be easy.

Comment thread docs/INTEGRATION_GUIDE.md
| `--openssl-dir=/path` | Use existing OpenSSL installation |
| `--replace-default` | Make wolfProvider the default provider |
| `--enable-replace-default-testing` | Enable unit testing with replace-default |
| `--enable-pqc` | Enable ML-KEM and ML-DSA post-quantum algorithms (adds `--enable-mlkem --enable-dilithium --enable-experimental` to wolfSSL). Requires wolfSSL post-v5.9.1-stable. |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use --enable-mldsa instead of --enable-dilithium going forward. Furthermore, both ML-KEM and ML-DSA don't require --enable-experimental anymore.

Comment thread docs/INTEGRATION_GUIDE.md
| `--enable-pwdbased` | PKCS#12 support |
| `--enable-hmac-copy` | Faster repeated HMAC with same key (wolfSSL 5.7.8+) |
| `--enable-sp=yes,asm --enable-sp-math-all` | SP Integer maths |
| `--enable-mlkem --enable-dilithium --enable-experimental` | ML-KEM and ML-DSA post-quantum algorithms (wolfSSL post-v5.9.1-stable). The `build-wolfprovider.sh --enable-pqc` flag sets these automatically. |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Comment thread docs/INTEGRATION_GUIDE.md

### Requirements

- **wolfSSL**: post-v5.9.1-stable (i.e. v5.9.2-stable or master). Older releases lack the `wc_MlDsaKey_*` and `wc_dilithium_sign_ctx_msg` API surface that wolfProvider's PQC code uses.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wc_dilithium_sign_ctx_msg() is already present in 5.9.1, only the new wc_MlDsaKey_SignCtx() is not.

Comment thread docs/INTEGRATION_GUIDE.md
./scripts/build-wolfprovider.sh --enable-pqc
```

This adds `--enable-mlkem --enable-dilithium --enable-experimental` to the wolfSSL configure step. wolfProvider auto-detects the resulting `WOLFSSL_HAVE_MLKEM` / `HAVE_DILITHIUM` macros via `include/wolfprovider/settings.h` (gated on `__has_include` of the corresponding wolfSSL headers) and registers the six PQC algorithms.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Comment thread docs/INTEGRATION_GUIDE.md
./scripts/build-wolfprovider.sh --enable-pqc
```

This adds `--enable-mlkem --enable-dilithium --enable-experimental` to the wolfSSL configure step. wolfProvider auto-detects the resulting `WOLFSSL_HAVE_MLKEM` / `HAVE_DILITHIUM` macros via `include/wolfprovider/settings.h` (gated on `__has_include` of the corresponding wolfSSL headers) and registers the six PQC algorithms.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WOLFSSL_HAVE_MLDSA instead of HAVE_DILITHIUM

Comment thread src/wp_mldsa_kmgmt.c
@@ -0,0 +1,1055 @@
/* wp_mldsa_kmgmt.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just saw it here, but probably applies to all new files: shouldn't the copyright year be 2026?

Comment thread src/wp_mldsa_kmgmt.c

#ifdef WP_HAVE_MLDSA

#include <wolfssl/wolfcrypt/dilithium.h>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the new wc_mldsa.h header with the new canonical wc_MlDsaKey naming.

Comment thread src/wp_mldsa_kmgmt.c
*/
struct wp_MlDsa {
/** wolfSSL ML-DSA key. */
MlDsaKey key;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the new wc_MlDsaKey naming. This applies to most of the API naming in this file. AI should be easily capable of moving this to the new final ML-DSA API without effort.

I won't flag it anymore in the following occurences.

Comment thread src/wp_mldsa_kmgmt.c

p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS);
if ((p != NULL) &&
!OSSL_PARAM_set_int(p, (int)mldsa->data->pubKeySize * 8)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Is this aligned with what native OpenSSL does for OSSL_PKEY_PARAM_BITS? I have never seen anyone using the public key size in bits for anything tbh..
But when this is the way OpenSSL does it, then it's fine, of course.

Comment thread src/wp_mlkem_kmgmt.c
}

p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS);
if ((p != NULL) && !OSSL_PARAM_set_int(p, (int)mlkem->data->pubKeySize * 8)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the ML-DSA path: is this aligned with native OpenSSL? Really looks strange to me...

@Frauschi
Copy link
Copy Markdown

Jenkins retest this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants