Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8c37dc3
OpenSSL compat with ML-DSA
kojo1 Jul 21, 2026
4096b43
Add ML-DSA test coverage for X509_REQ_sign
kojo1 Jul 24, 2026
7d55fce
PRIVATE_KEY_UNLOCK to X509 sign/set_pubkey
kojo1 Jul 24, 2026
406a297
Dynamic buff size based on expected cert size
kojo1 Jul 24, 2026
f9a66fc
Explicit prePopulated flag for d2iTryMlDsaKey
kojo1 Jul 30, 2026
bfba0a8
Size X509 gen buffer from subject public key too
kojo1 Jul 30, 2026
6edb1b7
Allow NULL md for ML-DSA X509 signing, add test
kojo1 Jul 30, 2026
b66ba13
Single gate for ML-DSA X509 signing capability
kojo1 Jul 30, 2026
37a54dd
Reset MlDsaKey between decode attempts in X509_set_pubkey
kojo1 Jul 30, 2026
0bbb077
PKCS#8 algId check and DER-only typed d2i for ML-DSA
kojo1 Jul 30, 2026
429683d
Extend ML-DSA compat test coverage to all levels and untested paths
kojo1 Jul 30, 2026
6b81db2
Use mldsa_get_oid_sum for draft-aware OID in X509 signing
kojo1 Jul 30, 2026
bff9cfb
Consistency cleanups in new ML-DSA X509 code
kojo1 Jul 30, 2026
00a5cf4
Derive WC_MAX_X509_GEN_MLDSA from WC_MAX_X509_GEN
kojo1 Jul 31, 2026
d3e3696
Use canonical ML-DSA names in new X509/EVP code
kojo1 Jul 31, 2026
55b3214
Test X509_set_pubkey with seed and private-only ML-DSA keys
kojo1 Jul 31, 2026
25b1f5e
Guard ML-DSA key/RNG cleanup in tests against Expect short-circuit
kojo1 Jul 31, 2026
d21743d
Reset XFILE handle after every close in ML-DSA tests
kojo1 Jul 31, 2026
2f84186
Free previous algorithm object when d2i repurposes an EVP_PKEY
kojo1 Jul 31, 2026
0fd6544
Do not store failed sigType lookup in sigOID
kojo1 Jul 31, 2026
d03be2c
Zeroize pkey.ptr before freeing EVP_PKEY key data
kojo1 Jul 31, 2026
59521d5
Note deliberate md tolerance for ML-DSA X509 signing
kojo1 Jul 31, 2026
3823ac2
Fix error code check
kojo1 Aug 1, 2026
49fbde0
Cover X25519/X448/HKDF/CMAC in d2i_free_prev_key_obj
kojo1 Aug 5, 2026
41c760c
Use explicit prePopulated flag in Ed25519/Ed448 d2i helpers
kojo1 Aug 5, 2026
525ddda
Move multi-KB test buffers from stack to heap
kojo1 Aug 5, 2026
7438353
Use d2i_PUBKEY in Ed25519 reuse regression test
kojo1 Aug 5, 2026
359f84a
Use MLDSA_MAX_PUB_KEY_DER_SIZE for SPKI buffers
kojo1 Aug 6, 2026
d34c452
Cross-check cached mldsaOID against decoded signing key
kojo1 Aug 6, 2026
8a5b56b
Move the description
kojo1 Aug 6, 2026
e2681cf
Replace the macro with a small static helper
kojo1 Aug 6, 2026
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
24 changes: 24 additions & 0 deletions src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -6571,6 +6571,18 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
case ED448k:
type = WC_EVP_PKEY_ED448;
break;
#endif
#ifdef WOLFSSL_HAVE_MLDSA
case ML_DSA_44k:
case ML_DSA_65k:
case ML_DSA_87k:
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
case DILITHIUM_LEVEL2k:
case DILITHIUM_LEVEL3k:
case DILITHIUM_LEVEL5k:
#endif
type = WC_EVP_PKEY_DILITHIUM;
break;
#endif
default:
type = WOLFSSL_FATAL_ERROR;

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.

🟡 [Medium] PEM read reuse form leaves the caller's EVP_PKEY pointer dangling on failure
💡 SUGGEST bug

wolfSSL_d2i_PrivateKey -> d2i_evp_pkey unconditionally does wolfSSL_EVP_PKEY_free(*out); *out = NULL; (wolfcrypt/src/evp_pk.c:1588-1591) before building the replacement. If the subsequent decode fails, d2i_evp_pkey returns NULL, and wolfSSL_PEM_read_bio_PrivateKey sets its local pkey to NULL and skips the *key = pkey write because err is set. The caller's variable is left pointing at freed memory, and the caller's own EVP_PKEY_free() is a double free. The mechanism is pre-existing, but this PR is the first to route ML-DSA keys through wolfSSL_d2i_PrivateKey from the PEM readers, and its new test_wolfSSL_PEM_PrivateKey_mldsa explicitly asserts the 'out-parameter reuse form (documented OpenSSL semantics)' while only covering the success path.

Suggestion:

Suggested change
type = WOLFSSL_FATAL_ERROR;
pkey = NULL;
/* d2i freed the object the caller passed in; do not leave a
* dangling pointer behind. */
if (key != NULL) {
*key = NULL;
}
err = 1;

Recommendation: Write *key = NULL on the failure path (or make d2i_evp_pkey not free *out until it has a replacement), and extend test_wolfSSL_PEM_PrivateKey_mldsa with a negative case: read a valid ML-DSA key into pkey, then a corrupt PEM into the same &pkey, and assert the caller is not left with a freed pointer.

Expand Down Expand Up @@ -6728,6 +6740,18 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
case ED448k:
type = WC_EVP_PKEY_ED448;
break;
#endif
#ifdef WOLFSSL_HAVE_MLDSA
case ML_DSA_44k:
case ML_DSA_65k:
case ML_DSA_87k:
#ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
case DILITHIUM_LEVEL2k:
case DILITHIUM_LEVEL3k:
case DILITHIUM_LEVEL5k:
#endif
type = WC_EVP_PKEY_DILITHIUM;
break;
#endif
default:
type = WOLFSSL_FATAL_ERROR;
Expand Down
Loading
Loading