@@ -12271,6 +12271,35 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1227112271 return WOLFSSL_FAILURE;
1227212272 }
1227312273 }
12274+ #ifdef WOLFSSL_HAVE_MLDSA
12275+ else if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
12276+ /* ML-DSA does not use a separate hash; ignore md. */
12277+ switch (WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID)) {
12278+ case ML_DSA_44k:
12279+ sigType = CTC_ML_DSA_LEVEL2;
12280+ break;
12281+ case ML_DSA_65k:
12282+ sigType = CTC_ML_DSA_LEVEL3;
12283+ break;
12284+ case ML_DSA_87k:
12285+ sigType = CTC_ML_DSA_LEVEL5;
12286+ break;
12287+ #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
12288+ case DILITHIUM_LEVEL2k:
12289+ sigType = CTC_DILITHIUM_LEVEL2;
12290+ break;
12291+ case DILITHIUM_LEVEL3k:
12292+ sigType = CTC_DILITHIUM_LEVEL3;
12293+ break;
12294+ case DILITHIUM_LEVEL5k:
12295+ sigType = CTC_DILITHIUM_LEVEL5;
12296+ break;
12297+ #endif
12298+ default:
12299+ return WOLFSSL_FAILURE;
12300+ }
12301+ }
12302+ #endif /* WOLFSSL_HAVE_MLDSA */
1227412303 else
1227512304 return WOLFSSL_FAILURE;
1227612305 return sigType;
@@ -12752,6 +12781,10 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1275212781 int type = -1;
1275312782 int sigType;
1275412783 WC_RNG rng;
12784+ #if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
12785+ !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
12786+ MlDsaKey* mldsa = NULL;
12787+ #endif
1275512788
1275612789 (void)req;
1275712790 WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
@@ -12776,14 +12809,83 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1277612809 key = pkey->ecc->internal;
1277712810 }
1277812811 #endif
12812+ #if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
12813+ !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
12814+ if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
12815+ /* Decode the ML-DSA private key held as DER in pkey.ptr. */
12816+ word32 idx = 0;
12817+ byte level = 0;
12818+
12819+ mldsa = (MlDsaKey*)XMALLOC(sizeof(MlDsaKey), NULL,
12820+ DYNAMIC_TYPE_MLDSA);
12821+ if (mldsa == NULL)
12822+ return WOLFSSL_FATAL_ERROR;
12823+ if (wc_MlDsaKey_Init(mldsa, NULL, INVALID_DEVID) != 0) {
12824+ XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
12825+ return WOLFSSL_FATAL_ERROR;
12826+ }
12827+ if (wc_MlDsaKey_PrivateKeyDecode(mldsa,
12828+ (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
12829+ &idx) != 0 ||
12830+ wc_MlDsaKey_GetParams(mldsa, &level) != 0) {
12831+ wc_MlDsaKey_Free(mldsa);
12832+ XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
12833+ return WOLFSSL_FATAL_ERROR;
12834+ }
12835+ switch (level) {
12836+ case WC_ML_DSA_44:
12837+ type = ML_DSA_LEVEL2_TYPE;
12838+ break;
12839+ case WC_ML_DSA_65:
12840+ type = ML_DSA_LEVEL3_TYPE;
12841+ break;
12842+ case WC_ML_DSA_87:
12843+ type = ML_DSA_LEVEL5_TYPE;
12844+ break;
12845+ #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
12846+ case WC_ML_DSA_44_DRAFT:
12847+ type = DILITHIUM_LEVEL2_TYPE;
12848+ break;
12849+ case WC_ML_DSA_65_DRAFT:
12850+ type = DILITHIUM_LEVEL3_TYPE;
12851+ break;
12852+ case WC_ML_DSA_87_DRAFT:
12853+ type = DILITHIUM_LEVEL5_TYPE;
12854+ break;
12855+ #endif
12856+ default:
12857+ wc_MlDsaKey_Free(mldsa);
12858+ XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
12859+ return WOLFSSL_FATAL_ERROR;
12860+ }
12861+ key = mldsa;
12862+ }
12863+ #endif /* WOLFSSL_HAVE_MLDSA && WOLFSSL_MLDSA_PRIVATE_KEY &&
12864+ * !WOLFSSL_MLDSA_NO_ASN1 && !WOLFSSL_MLDSA_NO_SIGN */
1277912865
1278012866 /* Sign the certificate (request) body. */
1278112867 ret = wc_InitRng(&rng);
12782- if (ret != 0)
12868+ if (ret != 0) {
12869+ #if defined(WOLFSSL_HAVE_MLDSA) && \
12870+ defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
12871+ !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
12872+ if (mldsa != NULL) {
12873+ wc_MlDsaKey_Free(mldsa);
12874+ XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
12875+ }
12876+ #endif
1278312877 return ret;
12878+ }
1278412879 ret = wc_SignCert_ex(certBodySz, sigType, der, (word32)derSz, type, key,
1278512880 &rng);
1278612881 wc_FreeRng(&rng);
12882+ #if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
12883+ !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
12884+ if (mldsa != NULL) {
12885+ wc_MlDsaKey_Free(mldsa);
12886+ XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
12887+ }
12888+ #endif
1278712889 if (ret < 0) {
1278812890 WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
1278912891 return ret;
@@ -12850,7 +12952,13 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1285012952
1285112953#ifndef WC_MAX_X509_GEN
1285212954 /* able to override max size until dynamic buffer created */
12853- #define WC_MAX_X509_GEN 4096
12955+ #ifdef WOLFSSL_HAVE_MLDSA
12956+ /* ML-DSA public keys and signatures are large (ML-DSA-87:
12957+ * 2592 byte public key, 4627 byte signature). */
12958+ #define WC_MAX_X509_GEN 20480
12959+ #else
12960+ #define WC_MAX_X509_GEN 4096
12961+ #endif
1285412962#endif
1285512963
1285612964/* returns the size of signature on success */
@@ -16378,6 +16486,90 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
1637816486 }
1637916487 break;
1638016488#endif
16489+ #if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
16490+ !defined(WOLFSSL_MLDSA_NO_ASN1) && defined(WC_ENABLE_ASYM_KEY_EXPORT)
16491+ case WC_EVP_PKEY_DILITHIUM:
16492+ {
16493+ /* Decode key DER (private or public) and export public part. */
16494+ MlDsaKey* mldsa;
16495+ word32 idx = 0;
16496+ byte level = 0;
16497+ int decodeOk = 0;
16498+
16499+ mldsa = (MlDsaKey*)XMALLOC(sizeof(MlDsaKey), cert->heap,
16500+ DYNAMIC_TYPE_MLDSA);
16501+ if (mldsa == NULL)
16502+ return WOLFSSL_FAILURE;
16503+ if (wc_MlDsaKey_Init(mldsa, NULL, INVALID_DEVID) != 0) {
16504+ XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
16505+ return WOLFSSL_FAILURE;
16506+ }
16507+ #ifdef WOLFSSL_MLDSA_PRIVATE_KEY
16508+ if (wc_MlDsaKey_PrivateKeyDecode(mldsa,
16509+ (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
16510+ &idx) == 0) {
16511+ decodeOk = 1;
16512+ }
16513+ #endif
16514+ if (!decodeOk) {
16515+ idx = 0;
16516+ if (wc_MlDsaKey_PublicKeyDecode(mldsa,
16517+ (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
16518+ &idx) != 0) {
16519+ wc_MlDsaKey_Free(mldsa);
16520+ XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
16521+ return WOLFSSL_FAILURE;
16522+ }
16523+ }
16524+ if (wc_MlDsaKey_GetParams(mldsa, &level) != 0) {
16525+ wc_MlDsaKey_Free(mldsa);
16526+ XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
16527+ return WOLFSSL_FAILURE;
16528+ }
16529+
16530+ derSz = MLDSA_MAX_PUB_KEY_SIZE + MAX_ALGO_SZ + MAX_SEQ_SZ * 2;
16531+ p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16532+ if (p == NULL) {
16533+ wc_MlDsaKey_Free(mldsa);
16534+ XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
16535+ return WOLFSSL_FAILURE;
16536+ }
16537+ derSz = wc_MlDsaKey_PublicKeyToDer(mldsa, p, (word32)derSz, 1);
16538+ wc_MlDsaKey_Free(mldsa);
16539+ XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
16540+ if (derSz <= 0) {
16541+ XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16542+ return WOLFSSL_FAILURE;
16543+ }
16544+ switch (level) {
16545+ case WC_ML_DSA_44:
16546+ cert->pubKeyOID = ML_DSA_44k;
16547+ break;
16548+ case WC_ML_DSA_65:
16549+ cert->pubKeyOID = ML_DSA_65k;
16550+ break;
16551+ case WC_ML_DSA_87:
16552+ cert->pubKeyOID = ML_DSA_87k;
16553+ break;
16554+ #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
16555+ case WC_ML_DSA_44_DRAFT:
16556+ cert->pubKeyOID = DILITHIUM_LEVEL2k;
16557+ break;
16558+ case WC_ML_DSA_65_DRAFT:
16559+ cert->pubKeyOID = DILITHIUM_LEVEL3k;
16560+ break;
16561+ case WC_ML_DSA_87_DRAFT:
16562+ cert->pubKeyOID = DILITHIUM_LEVEL5k;
16563+ break;
16564+ #endif
16565+ default:
16566+ XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16567+ return WOLFSSL_FAILURE;
16568+ }
16569+ }
16570+ break;
16571+ #endif /* WOLFSSL_HAVE_MLDSA && WOLFSSL_MLDSA_PUBLIC_KEY &&
16572+ * !WOLFSSL_MLDSA_NO_ASN1 && WC_ENABLE_ASYM_KEY_EXPORT */
1638116573 default:
1638216574 return WOLFSSL_FAILURE;
1638316575 }
@@ -16727,8 +16919,8 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
1672716919 const WOLFSSL_EVP_MD *md)
1672816920{
1672916921 int ret;
16730- WC_DECLARE_VAR(der, byte, 2048 , 0);
16731- int derSz = 2048 ;
16922+ WC_DECLARE_VAR(der, byte, WC_MAX_X509_GEN , 0);
16923+ int derSz = WC_MAX_X509_GEN ;
1673216924
1673316925 if (req == NULL || pkey == NULL || md == NULL) {
1673416926 WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
@@ -16748,7 +16940,7 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
1674816940 return WOLFSSL_FAILURE;
1674916941 }
1675016942
16751- if (wolfSSL_X509_resign_cert(req, 1, der, 2048 , derSz,
16943+ if (wolfSSL_X509_resign_cert(req, 1, der, WC_MAX_X509_GEN , derSz,
1675216944 (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
1675316945 WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1675416946 return WOLFSSL_FAILURE;
0 commit comments