nss/nss-3.118-ml-dsa-tls.patch
2026-08-19 19:37:08 -04:00

643 lines
25 KiB
Diff

diff --git a/automation/abi-check/expected-report-libssl3.so.txt b/automation/abi-check/expected-report-libssl3.so.txt
--- a/automation/abi-check/expected-report-libssl3.so.txt
+++ b/automation/abi-check/expected-report-libssl3.so.txt
@@ -0,0 +1,24 @@
+
+1 function with some indirect sub-type change:
+
+ [C]'function SECStatus SSL_ConfigServerCert(PRFileDesc*, CERTCertificate*, SECKEYPrivateKey*, const SSLExtraServerCertData*, unsigned int)' at sslcert.c:662:1 has some indirect sub-type changes:
+ parameter 4 of type 'const SSLExtraServerCertData*' has sub-type changes:
+ in pointed to type 'const SSLExtraServerCertData':
+ in unqualified underlying type 'typedef SSLExtraServerCertData' at sslt.h:310:1:
+ underlying type 'struct SSLExtraServerCertDataStr' at sslt.h:269:1 changed:
+ type size hasn't changed
+ 1 data member change:
+ type of 'SSLAuthType SSLExtraServerCertDataStr::authType' changed:
+ underlying type 'enum __anonymous_enum__' at sslt.h:176:1 changed:
+ type size hasn't changed
+ 3 enumerator insertions:
+ '__anonymous_enum__::ssl_auth_mldsa44' value '11'
+ '__anonymous_enum__::ssl_auth_mldsa65' value '12'
+ '__anonymous_enum__::ssl_auth_mldsa87' value '13'
+
+ 1 enumerator change:
+ '__anonymous_enum__::ssl_auth_size' from value '11' to '14' at sslt.h:180:1
+
+
+
+
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -69,10 +69,11 @@
static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash);
PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme);
PRBool ssl_IsRsaeSignatureScheme(SSLSignatureScheme scheme);
PRBool ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme);
PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme);
+PRBool ssl_IsMldsaSignatureScheme(SSLSignatureScheme scheme);
static SECStatus ssl3_UpdateDefaultHandshakeHashes(sslSocket *ss,
const unsigned char *b,
unsigned int l);
const PRUint32 kSSLSigSchemePolicy =
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_ANY_SIGNATURE;
@@ -203,11 +204,14 @@
ssl_sig_rsa_pkcs1_sha512,
ssl_sig_rsa_pkcs1_sha1,
ssl_sig_dsa_sha256,
ssl_sig_dsa_sha384,
ssl_sig_dsa_sha512,
- ssl_sig_dsa_sha1
+ ssl_sig_dsa_sha1,
+ ssl_sig_mldsa44,
+ ssl_sig_mldsa65,
+ ssl_sig_mldsa87,
};
PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureSchemes) <=
MAX_SIGNATURE_SCHEMES);
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
@@ -361,11 +365,14 @@
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_rsa */
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_ecdsa */
CKM_RSA_PKCS, /* ssl_auth_rsa_sign */
CKM_RSA_PKCS_PSS, /* ssl_auth_rsa_pss */
CKM_HKDF_DATA, /* ssl_auth_psk (just check for HKDF) */
- CKM_INVALID_MECHANISM /* ssl_auth_tls13_any */
+ CKM_INVALID_MECHANISM, /* ssl_auth_tls13_any */
+ CKM_ML_DSA, /* ssl_auth_mldsa44 */
+ CKM_ML_DSA, /* ssl_auth_mldsa65 */
+ CKM_ML_DSA, /* ssl_auth_mldsa87 */
};
PR_STATIC_ASSERT(PR_ARRAY_SIZE(auth_alg_defs) == ssl_auth_size);
static const CK_MECHANISM_TYPE kea_alg_defs[] = {
CKM_INVALID_MECHANISM, /* ssl_kea_null */
@@ -917,10 +924,18 @@
{
PRCList *cursor;
if (authType == ssl_auth_null || authType == ssl_auth_psk || authType == ssl_auth_tls13_any) {
return PR_TRUE;
}
+ /* mldsa is only supported in TLS 1.3 or greater */
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ (authType == ssl_auth_mldsa44 ||
+ authType == ssl_auth_mldsa65 ||
+ authType == ssl_auth_mldsa87)) {
+ return PR_FALSE;
+ }
+
for (cursor = PR_NEXT_LINK(&ss->serverCerts);
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor;
if (!cert->serverKeyPair ||
@@ -989,19 +1004,28 @@
}
/* Check that a signature scheme is accepted.
* Both by policy and by having a token that supports it. */
static PRBool
-ssl_SignatureSchemeAccepted(PRUint16 minVersion,
+ssl_SignatureSchemeAccepted(PRUint16 maxVersion,
+ PRUint16 minVersion,
SSLSignatureScheme scheme,
PRBool forCert)
{
/* Disable RSA-PSS schemes if there are no tokens to verify them. */
if (ssl_IsRsaPssSignatureScheme(scheme)) {
if (!PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) {
return PR_FALSE;
}
+ } else if (ssl_IsMldsaSignatureScheme(scheme)) {
+ /* ML-DSA: only in TLS 1.3 and later. */
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return PR_FALSE;
+ }
+ if (!PK11_TokenExists(auth_alg_defs[ssl_auth_mldsa44])) {
+ return PR_FALSE;
+ }
} else if (!forCert && ssl_IsRsaPkcs1SignatureScheme(scheme)) {
/* Disable PKCS#1 signatures if we are limited to TLS 1.3.
* We still need to advertise PKCS#1 signatures in CH and CR
* for certificate signatures.
*/
@@ -1046,11 +1070,11 @@
}
}
/* Ensure that there is a signature scheme that can be accepted.*/
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
- if (ssl_SignatureSchemeAccepted(ss->vrange.min,
+ if (ssl_SignatureSchemeAccepted(ss->vrange.max, ss->vrange.min,
ss->ssl3.signatureSchemes[i],
PR_FALSE /* forCert */)) {
return SECSuccess;
}
}
@@ -1077,11 +1101,12 @@
SSLSignatureScheme scheme = ss->ssl3.signatureSchemes[i];
SSLAuthType schemeAuthType = ssl_SignatureSchemeToAuthType(scheme);
PRBool acceptable = authType == schemeAuthType ||
(schemeAuthType == ssl_auth_rsa_pss &&
authType == ssl_auth_rsa_sign);
- if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme, PR_FALSE /* forCert */)) {
+ if (acceptable && ssl_SignatureSchemeAccepted(ss->version, ss->version,
+ scheme, PR_FALSE /* forCert */)) {
return PR_TRUE;
}
}
return PR_FALSE;
}
@@ -3569,10 +3594,11 @@
case ssl_hash_none:
/* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
return CKM_SHA256;
case ssl_hash_sha1:
return CKM_SHA_1;
+ /* don't return a mechansim for ml_dsa hashes */
default:
PORT_Assert(0);
}
return CKM_SHA256;
}
@@ -4525,10 +4551,16 @@
return SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
case ssl_auth_ecdsa:
return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
case ssl_auth_dsa:
return SEC_OID_ANSIX9_DSA_SIGNATURE;
+ case ssl_auth_mldsa44:
+ return SEC_OID_ML_DSA_44;
+ case ssl_auth_mldsa65:
+ return SEC_OID_ML_DSA_65;
+ case ssl_auth_mldsa87:
+ return SEC_OID_ML_DSA_87;
default:
break;
}
/* shouldn't ever get there */
PORT_Assert(0);
@@ -4561,10 +4593,14 @@
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_dsa_sha512:
return ssl_hash_sha512;
case ssl_sig_rsa_pkcs1_sha1md5:
return ssl_hash_none; /* Special for TLS 1.0/1.1. */
+ case ssl_sig_mldsa44:
+ case ssl_sig_mldsa65:
+ case ssl_sig_mldsa87:
+ return ssl_hash_none; /* ml_dsa does no hashing */
case ssl_sig_none:
case ssl_sig_ed25519:
case ssl_sig_ed448:
break;
}
@@ -4613,14 +4649,38 @@
return PR_FALSE;
}
/* With TLS 1.3, EC keys should have been selected based on calling
* ssl_SignatureSchemeFromSpki(), reject them otherwise. */
return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY;
+ } else {
+ if (ssl_IsMldsaSignatureScheme(scheme)) {
+ return PR_FALSE;
+ }
}
return PR_TRUE;
}
+/* some schmemes match 1 for 1 to oids, for those schemes, we
+ * can return the oid directly. If this function return ssl_sig_none,
+ * it means the oid doesn't match a scheme or matches more than one
+ * scheme */
+SSLSignatureScheme
+ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag)
+{
+ switch (tag) {
+ case SEC_OID_ML_DSA_44:
+ return ssl_sig_mldsa44;
+ case SEC_OID_ML_DSA_65:
+ return ssl_sig_mldsa65;
+ case SEC_OID_ML_DSA_87:
+ return ssl_sig_mldsa87;
+ default:
+ break;
+ }
+ return ssl_sig_none;
+}
+
static SECStatus
ssl_SignatureSchemeFromPssSpki(const CERTSubjectPublicKeyInfo *spki,
SSLSignatureScheme *scheme)
{
SECKEYRSAPSSParams pssParam = { 0 };
@@ -4709,22 +4769,27 @@
ssl_SignatureSchemeFromSpki(const CERTSubjectPublicKeyInfo *spki,
PRBool isTls13, SSLSignatureScheme *scheme)
{
SECOidTag spkiOid = SECOID_GetAlgorithmTag(&spki->algorithm);
- if (spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
- return ssl_SignatureSchemeFromPssSpki(spki, scheme);
- }
-
- /* Only do this lookup for TLS 1.3, where the scheme can be determined from
- * the SPKI alone because the ECDSA key size determines the hash. Earlier
- * TLS versions allow the same EC key to be used with different hashes. */
- if (isTls13 && spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
- return ssl_SignatureSchemeFromEcSpki(spki, scheme);
- }
-
*scheme = ssl_sig_none;
+ switch (spkiOid) {
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ return ssl_SignatureSchemeFromPssSpki(spki, scheme);
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ /* Only do this lookup for TLS 1.3, where the scheme can be
+ * determined from the SPKI alone because the ECDSA key size
+ * determines the hash. Earlier TLS versions allow the same
+ * EC key to be used with different hashes. */
+ if (isTls13) {
+ return ssl_SignatureSchemeFromEcSpki(spki, scheme);
+ }
+ break;
+ default:
+ *scheme = ssl_SignatureSchemeFromPublicKeyOid(spkiOid);
+ break;
+ }
return SECSuccess;
}
/* Check that a signature scheme is enabled by configuration. */
PRBool
@@ -4826,10 +4891,13 @@
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
+ case ssl_sig_mldsa44:
+ case ssl_sig_mldsa65:
+ case ssl_sig_mldsa87:
case ssl_sig_dsa_sha1:
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
case ssl_sig_ecdsa_sha1:
@@ -4908,10 +4976,25 @@
return PR_FALSE;
}
return PR_FALSE;
}
+PRBool
+ssl_IsMldsaSignatureScheme(SSLSignatureScheme scheme)
+{
+ switch (scheme) {
+ case ssl_sig_mldsa44:
+ case ssl_sig_mldsa65:
+ case ssl_sig_mldsa87:
+ return PR_TRUE;
+
+ default:
+ return PR_FALSE;
+ }
+ return PR_FALSE;
+}
+
SSLAuthType
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha1:
@@ -4936,10 +5019,21 @@
case ssl_sig_dsa_sha1:
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
return ssl_auth_dsa;
+ /* while there is one mechanism for ML-DSA,
+ * server cert selection depends on which
+ * flavor (paramset) is being used, so
+ * we need one auth foreach param set.
+ */
+ case ssl_sig_mldsa44:
+ return ssl_auth_mldsa44;
+ case ssl_sig_mldsa65:
+ return ssl_auth_mldsa65;
+ case ssl_sig_mldsa87:
+ return ssl_auth_mldsa87;
default:
PORT_Assert(0);
}
return ssl_auth_null;
@@ -10490,17 +10584,18 @@
return SECFailure;
}
SECStatus
-ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
- PRBool grease, sslBuffer *buf)
+ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
+ PRBool forCert, PRBool grease, sslBuffer *buf)
{
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
unsigned int filteredCount = 0;
- SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, PR_FALSE, forCert,
+ SECStatus rv = ssl3_FilterSigAlgs(ss, maxVersion, minVersion,
+ PR_FALSE, forCert,
PR_ARRAY_SIZE(filtered),
filtered, &filteredCount);
if (rv != SECSuccess) {
return SECFailure;
}
@@ -10573,12 +10668,12 @@
* requires that PKCS#1 schemes are placed last in the list if they
* are present. This sorting can be removed once we support
* signature_algorithms_cert.
*/
SECStatus
-ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
- PRBool forCert,
+ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
+ PRBool disableRsae, PRBool forCert,
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
unsigned int *numFilteredSchemes)
{
PORT_Assert(filteredSchemes);
PORT_Assert(numFilteredSchemes);
@@ -10591,25 +10686,25 @@
PRBool allowUnsortedPkcs1 = forCert && minVersion < SSL_LIBRARY_VERSION_TLS_1_3;
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
continue;
}
- if (ssl_SignatureSchemeAccepted(minVersion,
+ if (ssl_SignatureSchemeAccepted(maxVersion, minVersion,
ss->ssl3.signatureSchemes[i],
allowUnsortedPkcs1)) {
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
}
}
if (forCert && !allowUnsortedPkcs1) {
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
continue;
}
- if (!ssl_SignatureSchemeAccepted(minVersion,
+ if (!ssl_SignatureSchemeAccepted(maxVersion, minVersion,
ss->ssl3.signatureSchemes[i],
PR_FALSE) &&
- ssl_SignatureSchemeAccepted(minVersion,
+ ssl_SignatureSchemeAccepted(maxVersion, minVersion,
ss->ssl3.signatureSchemes[i],
PR_TRUE)) {
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
}
}
@@ -10648,11 +10743,11 @@
certTypes = certificate_types;
certTypesLength = sizeof certificate_types;
length = 1 + certTypesLength + 2 + calen;
if (isTLS12) {
- rv = ssl3_EncodeSigAlgs(ss, ss->version, PR_TRUE /* forCert */,
+ rv = ssl3_EncodeSigAlgs(ss, ss->version, ss->version, PR_TRUE /* forCert */,
PR_FALSE /* GREASE */, &sigAlgsBuf);
if (rv != SECSuccess) {
return rv;
}
length += SSL_BUFFER_LEN(&sigAlgsBuf);
@@ -11854,10 +11949,15 @@
/* Don't check EC strength here on the understanding that we
* only support curves we like. */
minKey = ss->sec.authKeyBits;
}
break;
+ case mldsaKey:
+ /* ML DSA has fixed sizes per param set and are handled by
+ * separate policy oids for each param set */
+ minKey = ss->sec.authKeyBits;
+ break;
default:
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c
--- a/lib/ssl/ssl3exthandle.c
+++ b/lib/ssl/ssl3exthandle.c
@@ -1653,17 +1653,21 @@
if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_2) {
return SECSuccess;
}
PRUint16 minVersion;
+ PRUint16 maxVersion;
if (ss->sec.isServer) {
+ maxVersion = ss->version; /* CertificateRequest */
minVersion = ss->version; /* CertificateRequest */
} else {
+ maxVersion = ss->vrange.max; /* ClientHello */
minVersion = ss->vrange.min; /* ClientHello */
}
- SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, PR_TRUE /* forCert */,
+ SECStatus rv = ssl3_EncodeSigAlgs(ss, maxVersion, minVersion,
+ PR_TRUE /* forCert */,
ss->opt.enableGrease, buf);
if (rv != SECSuccess) {
return SECFailure;
}
diff --git a/lib/ssl/sslcert.c b/lib/ssl/sslcert.c
--- a/lib/ssl/sslcert.c
+++ b/lib/ssl/sslcert.c
@@ -568,10 +568,27 @@
if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
authTypes |= 1 << ssl_GetEcdhAuthType(cert);
}
break;
+ case SEC_OID_ML_DSA_44:
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ authTypes |= 1 << ssl_auth_mldsa44;
+ }
+ break;
+
+ case SEC_OID_ML_DSA_65:
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ authTypes |= 1 << ssl_auth_mldsa65;
+ }
+ break;
+
+ case SEC_OID_ML_DSA_87:
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ authTypes |= 1 << ssl_auth_mldsa87;
+ }
+
default:
break;
}
/* Check that we successfully picked an authType */
@@ -729,10 +746,19 @@
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
mask |= 1 << ssl_auth_ecdsa;
mask |= 1 << ssl_auth_ecdh_rsa;
mask |= 1 << ssl_auth_ecdh_ecdsa;
break;
+ case SEC_OID_ML_DSA_44:
+ mask |= 1 << ssl_auth_mldsa44;
+ break;
+ case SEC_OID_ML_DSA_65:
+ mask |= 1 << ssl_auth_mldsa65;
+ break;
+ case SEC_OID_ML_DSA_87:
+ mask |= 1 << ssl_auth_mldsa87;
+ break;
default:
break;
}
PORT_Assert(authTypes);
/* Simply test that no inappropriate auth types are set. */
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -1746,16 +1746,18 @@
SECStatus ssl_SetAuthKeyBits(sslSocket *ss, const SECKEYPublicKey *pubKey);
SECStatus ssl3_HandleServerSpki(sslSocket *ss);
SECStatus ssl3_AuthCertificate(sslSocket *ss);
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
PRUint32 length);
-SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
+SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 maxVersion,
+ PRUint16 minVersion, PRBool forCert,
PRBool grease, sslBuffer *buf);
SECStatus ssl3_EncodeFilteredSigAlgs(const sslSocket *ss,
const SSLSignatureScheme *schemes,
PRUint32 numSchemes, PRBool grease, sslBuffer *buf);
-SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae, PRBool forCert,
+SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
+ PRBool disableRsae, PRBool forCert,
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
unsigned int *numFilteredSchemes);
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
unsigned int *calenp,
const SECItem **namesp,
@@ -1821,10 +1823,11 @@
SECStatus ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
SSLContentType contentType, sslBuffer *wrBuf,
PRBool *needsLength);
PRBool ssl_SignatureSchemeValid(SSLSignatureScheme scheme, SECOidTag spkiOid,
PRBool isTls13);
+SSLSignatureScheme ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag);
/* Pull in DTLS functions */
#include "dtlscon.h"
/* Pull in TLS 1.3 functions */
diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
--- a/lib/ssl/sslt.h
+++ b/lib/ssl/sslt.h
@@ -154,10 +154,14 @@
ssl_sig_dsa_sha256 = 0x0402,
ssl_sig_dsa_sha384 = 0x0502,
ssl_sig_dsa_sha512 = 0x0602,
ssl_sig_ecdsa_sha1 = 0x0203,
+ ssl_sig_mldsa44 = 0x0904,
+ ssl_sig_mldsa65 = 0x0905,
+ ssl_sig_mldsa87 = 0x0906,
+
/* The following value (which can't be used in the protocol), represents
* the RSA signature using SHA-1 and MD5 that is used in TLS 1.0 and 1.1.
* This is reported as a signature scheme when TLS 1.0 or 1.1 is used.
* This should not be passed to SSL_SignatureSchemePrefSet(); this
* signature scheme is always used and cannot be disabled. */
@@ -183,10 +187,13 @@
ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature. */
ssl_auth_rsa_sign = 7, /* RSA signing with an rsaEncryption key. */
ssl_auth_rsa_pss = 8, /* RSA signing with a PSS key. */
ssl_auth_psk = 9,
ssl_auth_tls13_any = 10,
+ ssl_auth_mldsa44 = 11, /* use separate auth for each paramset */
+ ssl_auth_mldsa65 = 12, /* so we can properly identify the certs */
+ ssl_auth_mldsa87 = 13,
ssl_auth_size /* number of authentication types */
} SSLAuthType;
typedef enum {
ssl_psk_none = 0,
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
--- a/lib/ssl/tls13exthandle.c
+++ b/lib/ssl/tls13exthandle.c
@@ -1450,11 +1450,11 @@
* the "advertised" list, then encode them to be sent. If we receive
* a DC in response, validate that it matches one of the advertised
* schemes. */
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
unsigned int filteredCount = 0;
- SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max,
+ SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max, ss->vrange.max,
PR_TRUE /* disableRsae */,
PR_FALSE /* forCert */,
MAX_SIGNATURE_SCHEMES,
filtered,
&filteredCount);
diff --git a/lib/ssl/tls13signature.c b/lib/ssl/tls13signature.c
--- a/lib/ssl/tls13signature.c
+++ b/lib/ssl/tls13signature.c
@@ -55,10 +55,24 @@
break;
case ssl_sig_ecdsa_secp521r1_sha512:
algTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
hashAlgTag = SEC_OID_SHA512;
break;
+ /* ML-DSA fully defines the hash and sign algorithm,
+ * we set the hash alg to the same as the sign alg. */
+ case ssl_sig_mldsa44:
+ algTag = SEC_OID_ML_DSA_44;
+ hashAlgTag = SEC_OID_ML_DSA_44;
+ break;
+ case ssl_sig_mldsa65:
+ algTag = SEC_OID_ML_DSA_65;
+ hashAlgTag = SEC_OID_ML_DSA_65;
+ break;
+ case ssl_sig_mldsa87:
+ algTag = SEC_OID_ML_DSA_87;
+ hashAlgTag = SEC_OID_ML_DSA_87;
+ break;
/* the following is unsupported in tls 1.3 and greater, just break.
* We include them here explicitly so we get the compiler warning about
* missing enums in the switch statement. default would be a break anyway.
* That way we'll know to update this table when new algorithms are
diff --git a/lib/ssl/tls13subcerts.c b/lib/ssl/tls13subcerts.c
--- a/lib/ssl/tls13subcerts.c
+++ b/lib/ssl/tls13subcerts.c
@@ -649,11 +649,17 @@
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return NULL;
}
return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
}
-
+ case mldsaKey:
+ if (ssl_SignatureSchemeFromPublicKeyOid(dcPub->u.mldsa.paramSet)
+ != dcCertVerifyAlg) {
+ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
+ return NULL;
+ }
+ return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
default:
break;
}
PORT_SetError(SEC_ERROR_INVALID_KEY);