Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
- '--enable-wolfclu --enable-smallstack'
- '--enable-wolfclu --enable-experimental --enable-dilithium'
- '--enable-wolfclu --enable-smallstack --enable-experimental --enable-dilithium'
- '--enable-wolfclu --enable-experimental --enable-mldsa'
- '--enable-wolfclu --enable-smallstack --enable-experimental --enable-mldsa'
- '--enable-all'
sanitize: ['CC="cc -fsanitize=address"']
include:
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ man_MANS+= manpages/wolfssl-sign_verify.1
man_MANS+= manpages/wolfssl-ecc.1
man_MANS+= manpages/wolfssl-ed25519.1
man_MANS+= manpages/wolfssl-dilithium.1
man_MANS+= manpages/wolfssl-ml-dsa.1
man_MANS+= manpages/wolfssl-xmss.1
man_MANS+= manpages/wolfssl-xmssmt.1
man_MANS+= manpages/wolfssl-rand.1
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ uqGDApXWYuBdjheL4Ysoq6YXtt6dnm8DkBVrnt+gAMCBFbBNPXxy2MODBDqya907
iky6IRTUzkBy1fssv3Gr/jOsyN8J565NST3RpQ==
-----END CERTIFICATE-----
```
A self-signed certificate can also be generated with post-quantum ML-DSA (FIPS 204) key. `ml-dsa` and `dilithium` are interchangeable command aliases, and the level (`2`/`3`/`5`) selects ML-DSA-44/65/87. This needs wolfSSL built with `--enable-dilithium --enable-experimental`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We will need to update enable-dilithium to enable-mldsa, but that can be in a separate PR.

```
wolfssl req -x509 -newkey ml-dsa:2 -keyout ml-dsa-key -days 3650 \
-subj /CN=wolfSSL -out ml-dsa.cert
```

### DGST Sign and Verify

The commands below sign this README then verify it with the resulting signature.
Expand All @@ -166,7 +172,7 @@ wolfssl dgst -sha256 -verify mykey.pub -signature readme.sig ./README.md

The following demonstrates how to create a root CA and use it to sign other certificates. This example uses ECC, but steps are similar for RSA.

In this scenario there are three entities A, B, and C, where A is meant to function as a root CA.
In this scenario there are three entities A, B, and C, where A is meant to function as a root CA.

The following steps demonstrate how to generate keys and certificates for A, B, and C, where A is self-signed and B and C are signed by A

Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ AC_CHECK_FUNC([wolfSSL_X509_REQ_print],
AC_CHECK_FUNC([wc_EncodeObjectId],
[],
[AM_CFLAGS="$AM_CFLAGS -DNO_WC_ENCODE_OBJECT_ID"])
AC_CHECK_FUNC([wc_MlDsaKey_Init],
[AM_CFLAGS="$AM_CFLAGS -DWOLFCLU_HAVE_MLDSA -DWOLFCLU_MLDSA_CHECKED"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFCLU_MLDSA_CHECKED"])


###############################################
Expand Down
2 changes: 2 additions & 0 deletions ide/winvs/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@
#define HAVE_OCSP
#define HAVE_OCSP_RESPONDER

#define WOLFSSL_HAVE_ERROR_QUEUE

#endif /* _WIN_USER_SETTINGS_H_ */
21 changes: 16 additions & 5 deletions manpages/wolfssl-ca.1
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ the configuration file (see -config).
-out file output file for the signed certificate.
.br
.LP
-keyfile file private key used to sign the certificate.
-keyfile file private key used to sign the certificate (RSA, ECDSA, or
.br
ML-DSA). For ML-DSA, the companion public key must
.br
co-exist and is loaded automatically (e.g. <name>.pub
.br
for <name>.priv, or <stem>Pub.pem for <stem>.pem).
.br
The key may also be set via [CA_default] private_key.
.br
.LP
-cert file CA certificate to issue from.
Expand All @@ -32,11 +40,9 @@ the configuration file (see -config).
-inform PEM|DER input format of the CSR.
.br
.LP
-outform PEM|DER output format of the certificate. The normal signing
-outform PEM|DER output format of the issued certificate. Defaults to
.br
path always writes PEM; -outform der is currently
.br
ignored.
PEM.
.br
.LP
-md digest signing digest to use, e.g. sha256.
Expand Down Expand Up @@ -78,6 +84,11 @@ Sign a CSR as a CA with your CA certificate and key:
wolfssl ca -in csr.pem -out cert.pem -keyfile ca-key.pem -cert ca-cert.pem -days 365 -md sha256
.RE
.LP
Sign a CSR with an ML-DSA CA key:
.RS
wolfssl ca -in csr.pem -out cert.pem -keyfile ca-key.priv -cert ca-cert.pem -days 365
.RE
.LP
View the certificate details after signing:
.RS
wolfssl x509 -in cert.pem -text -noout
Expand Down
5 changes: 5 additions & 0 deletions manpages/wolfssl-genkey.1
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ Generate a Dilithium key pair:
wolfssl genkey dilithium -level 3 -out mykey -outform der -output KEYPAIR
.br
.LP
Generate an ML-DSA-65 key pair (ML-DSA OIDs, not interchangeable with dilithium keys):
.br
wolfssl genkey ml-dsa -level 3 -out mykey -outform der -output KEYPAIR
.br
.LP
Generate an XMSS key pair:
.br
wolfssl genkey xmss -height 10 -out mykey -outform raw -output KEYPAIR
Expand Down
5 changes: 5 additions & 0 deletions manpages/wolfssl-ml-dsa.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.\" Alias page: ml-dsa sign/verify is documented in wolfssl-sign_verify(1).
.TH wolfSSL SSL1 "June 2026" "0.2.0" "wolfssl ml-dsa man page"
.SH NAME
wolfssl-ml-dsa, ml-dsa \- ML-DSA raw signing and verification
.so man1/wolfssl-sign_verify.1
17 changes: 15 additions & 2 deletions manpages/wolfssl-req.1
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ key is written to stdout.
.LP
-newkey type:bits generate the private key to use with the request.
.br
RSA: rsa:2048. Dilithium (with -x509 and certgen):
RSA: rsa:2048. ML-DSA: ml-dsa:N (or dilithium:N),
.br
dilithium:2, dilithium:3, dilithium:5, or ml-dsa:N.
where N is 2, 3, or 5 (requires HAVE_DILITHIUM).
.br
For ECC keys, generate with ecparam first.
.br
Expand Down Expand Up @@ -98,11 +98,24 @@ View a CSR in human-readable format:
.RS
wolfssl req -in mycsr.pem -text -noout
.RE
.LP
Generate an ML-DSA-65 CSR with a new key:
.RS
wolfssl req -new -newkey ml-dsa:3 -keyout ml-dsa -out my.csr.pem -subj "/CN=example.com"
.RE
.LP
Create a self-signed ML-DSA-44 CA certificate:
.RS
wolfssl req -x509 -newkey ml-dsa:2 -keyout ca-ml-dsa -out ca-ml-dsa.pem -days 3650 -subj "/CN=ML-DSA Root CA"
.RE
Comment thread
stenslae marked this conversation as resolved.
.SH SEE ALSO
.BR wolfssl-genkey(1) ", " wolfssl-ca(1) ", " wolfssl-x509(1)
.SH NOTES
Available only when wolfSSL is built with certificate request support
(WOLFSSL_CERT_REQ) and filesystem support.
.LP
For ML-DSA keys, -config and -extensions are ignored (only the subject DN is
carried), and -text and -verify are not supported.
.SH BUGS
No known bugs at this time.
.SH AUTHOR
Expand Down
14 changes: 13 additions & 1 deletion manpages/wolfssl-sign_verify.1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ command.
.br
-ed25519 Ed25519 signing and verification (requires HAVE_ED25519).
.br
-dilithium Dilithium (ML-DSA) signing and verification (requires HAVE_DILITHIUM).
-ml-dsa ML-DSA (Dilithium) signing and verification (requires HAVE_DILITHIUM).
.br
-dilithium is accepted as an alias for -ml-dsa.
.br
-xmss XMSS signing and verification (requires WOLFSSL_HAVE_XMSS).
.br
Expand Down Expand Up @@ -73,6 +75,16 @@ wolfssl -rsa -verify -inkey pub.pem -inform pem -sigfile message.sig -out verify
Verify with an ECC public key:
.br
wolfssl -ecc -verify -inkey pub.pem -inform pem -sigfile message.sig -in message.txt -pubin
.br
.LP
Sign a file with an ML-DSA private key:
.br
wolfssl -ml-dsa -sign -inkey mykey.priv -inform der -in message.bin -out message.sig
.br
.LP
Verify with an ML-DSA public key:
.br
wolfssl -ml-dsa -verify -inkey mykey.pub -inform der -sigfile message.sig -in message.bin -pubin
.SH NOTES
Available only when wolfSSL is built with filesystem support. The set of
usable key types depends on the wolfSSL configure options.
Expand Down
24 changes: 15 additions & 9 deletions manpages/wolfssl-verify.1
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ revocation.
.SH OPTIONS
-CAfile file trusted CA certificate to verify against (PEM only).
.br
Must be a self-signed root CA unless \-partial_chain
May be a bundle; must contain a self-signed root CA
.br
is given; an intermediate CA causes "CA file is not
.br
root CA".
unless \-partial_chain is given. See NOTES.
.br
.LP
-untrusted file intermediate certificate file. Only one intermediate
Expand Down Expand Up @@ -52,11 +50,19 @@ wolfssl verify -CAfile ca-and-crl.pem -crl_check server-cert.pem
.BR wolfssl-x509(1) ", " wolfssl-crl(1)
.SH NOTES
The certificate to verify is given as the final argument. -CAfile must be
a PEM file. Unless -partial_chain is given, -CAfile must be a self-signed
root CA; supplying an intermediate CA without -partial_chain fails with
"CA file is not root CA". With -crl_check, revocation data must already be
present in -CAfile (for example by concatenating the CRL PEM after the CA
certificate). Available only when wolfSSL is built with filesystem support.
a PEM file, and may contain a bundle of multiple certificates; the bundle
is scanned in any order for a self-signed root CA. Every candidate CA
certificate, including the self-signed root, must assert basicConstraints
CA:TRUE; certificates without it are skipped when searching for a root
unless -partial_chain is given. This is intentional hardening versus
older wolfssl-clu releases, which accepted a self-signed root lacking
basicConstraints. Unless -partial_chain is given, the bundle must contain
a self-signed root CA; if none is found, verification fails with "CA file
does not contain a self-signed root CA (use -partial_chain to trust an
intermediate)". With -crl_check, revocation
data must already be present in -CAfile (for example by concatenating the
CRL PEM after the CA certificate). Available only when wolfSSL is built
with filesystem support.
.SH BUGS
No known bugs at this time.
.SH AUTHOR
Expand Down
7 changes: 7 additions & 0 deletions manpages/wolfssl-x509.1
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ Unless both -req and -signkey are used, -extfile and -extensions are
silently ignored on output: the (re-encoded) certificate is written from
the original input DER, not from any in-memory changes made while parsing
extensions.
.LP
When -text is used on a certificate containing an ML-DSA SubjectPublicKey,
the standard field-by-field dump (subject, issuer, validity, serial number,
key bytes, and most extensions) is replaced with a short placeholder line
noting that full ML-DSA decoding is not yet supported, plus a
basicConstraints CA:TRUE line when the certificate is a CA, due to library
limitations.
.SH EXAMPLES
View certificate details in human-readable format:
.RS
Expand Down
28 changes: 14 additions & 14 deletions src/crypto/clu_crypto_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static int wolfCLU_loadHexKeyInto(byte* keyOut, int keyBytes,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
wolfCLU_ForceZero(hexCopy, hexLen);
wc_ForceZero(hexCopy, hexLen);
XFREE(hexCopy, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);

if (ret != WOLFCLU_SUCCESS) {
Expand All @@ -76,7 +76,7 @@ static int wolfCLU_loadHexKeyInto(byte* keyOut, int keyBytes,
}

XMEMCPY(keyOut, tmp, keyBytes);
wolfCLU_ForceZero(tmp, tmpSz);
wc_ForceZero(tmp, tmpSz);
/* tmp was allocated by wolfCLU_hexToBin with a NULL heap hint
* (see src/tools/clu_hex_to_bin.c); free it with the same hint. */
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Expand Down Expand Up @@ -322,13 +322,13 @@ int wolfCLU_setup(int argc, char** argv, char action)
WOLFCLU_LOG(WOLFCLU_E0,
"IV length mismatch: expected %d bytes, got %u",
block, (unsigned int)ivTmpSz);
wolfCLU_ForceZero(ivTmp, ivTmpSz);
wc_ForceZero(ivTmp, ivTmpSz);
XFREE(ivTmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);
return WOLFCLU_FATAL_ERROR;
}
XMEMCPY(iv, ivTmp, ivTmpSz);
wolfCLU_ForceZero(ivTmp, ivTmpSz);
wc_ForceZero(ivTmp, ivTmpSz);
/* hexToBin allocates with NULL heap hint; free with same. */
XFREE(ivTmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ivCheck = 1;
Expand Down Expand Up @@ -413,7 +413,7 @@ int wolfCLU_setup(int argc, char** argv, char action)

if (wolfSSL_BIO_read(keyBio, fileBuf, fileLen) != fileLen) {
wolfCLU_LogError("failed to read key file '%s'", optarg);
wolfCLU_ForceZero(fileBuf, fileLen);
wc_ForceZero(fileBuf, fileLen);
XFREE(fileBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_BIO_free(keyBio);
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);
Expand Down Expand Up @@ -445,7 +445,7 @@ int wolfCLU_setup(int argc, char** argv, char action)
keyString = (char*)XMALLOC(fileLen + 1, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (keyString == NULL) {
wolfCLU_ForceZero(fileBuf, fileLen);
wc_ForceZero(fileBuf, fileLen);
XFREE(fileBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);
return MEMORY_E;
Expand All @@ -463,9 +463,9 @@ int wolfCLU_setup(int argc, char** argv, char action)

ret = wolfCLU_loadHexKeyInto(key, keyBytes,
keyString, (word32)j);
wolfCLU_ForceZero(keyString, j);
wc_ForceZero(keyString, j);
XFREE(keyString, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfCLU_ForceZero(fileBuf, fileLen);
wc_ForceZero(fileBuf, fileLen);
XFREE(fileBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (ret != WOLFCLU_SUCCESS) {
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);
Expand All @@ -483,13 +483,13 @@ int wolfCLU_setup(int argc, char** argv, char action)
keySize);
WOLFCLU_LOG(WOLFCLU_E0,
"Invalid Key. Must match algorithm key size.");
wolfCLU_ForceZero(fileBuf, fileLen);
wc_ForceZero(fileBuf, fileLen);
XFREE(fileBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);
return WOLFCLU_FATAL_ERROR;
}
XMEMCPY(key, fileBuf, fileLen);
wolfCLU_ForceZero(fileBuf, fileLen);
wc_ForceZero(fileBuf, fileLen);
XFREE(fileBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}

Expand Down Expand Up @@ -603,7 +603,7 @@ int wolfCLU_setup(int argc, char** argv, char action)
}

if (pwdKeyChk == 1 && keyCheck == 1) {
XMEMSET(pwdKey, 0, keySize + block);
wc_ForceZero(pwdKey, keySize + block);
}

/* encryption function call */
Expand Down Expand Up @@ -663,9 +663,9 @@ int wolfCLU_setup(int argc, char** argv, char action)
* the cipher key length doesn't leak material across XFREE.
* ForceZero (not XMEMSET) so the compiler can't drop the wipe of these
* soon-to-be-freed key buffers. */
wolfCLU_ForceZero(key, keySize);
wolfCLU_ForceZero(pwdKey, keySize + block);
wolfCLU_ForceZero(iv, block);
wc_ForceZero(key, keySize);
wc_ForceZero(pwdKey, keySize + block);
wc_ForceZero(iv, block);
wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL);

if (mode != NULL)
Expand Down
Loading
Loading