Skip to content

Commit

Permalink
Fixes for ML-DSA in TLS handshake
Browse files Browse the repository at this point in the history
After wolfSSL#8016 enabled support for both the final and the draft versions of
ML-DSA simultaneously, the commit adds necessary changes to properly use
both in the TLS handshake for authentication.

Signed-off-by: Tobias Frauenschläger <[email protected]>
  • Loading branch information
Frauschi committed Jan 28, 2025
1 parent c48ba69 commit f11bb73
Show file tree
Hide file tree
Showing 6 changed files with 428 additions and 91 deletions.
206 changes: 177 additions & 29 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3283,6 +3283,22 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo,
else
#endif /* HAVE_FALCON */
#ifdef HAVE_DILITHIUM
if (sigAlgo == ml_dsa_44_sa_algo) {
ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx,
ML_DSA_44_SA_MAJOR, ML_DSA_44_SA_MINOR);
}
else
if (sigAlgo == ml_dsa_65_sa_algo) {
ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx,
ML_DSA_65_SA_MAJOR, ML_DSA_65_SA_MINOR);
}
else
if (sigAlgo == ml_dsa_87_sa_algo) {
ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx,
ML_DSA_87_SA_MAJOR, ML_DSA_87_SA_MINOR);
}
else
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
if (sigAlgo == dilithium_level2_sa_algo) {
ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx,
DILITHIUM_LEVEL2_SA_MAJOR, DILITHIUM_LEVEL2_SA_MINOR);
Expand All @@ -3298,6 +3314,7 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo,
DILITHIUM_LEVEL5_SA_MAJOR, DILITHIUM_LEVEL5_SA_MINOR);
}
else
#endif
#endif /* HAVE_DILITHIUM */
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
Expand Down Expand Up @@ -3369,12 +3386,20 @@ void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2,
#endif /* HAVE_FALCON */
#ifdef HAVE_DILITHIUM
if (haveSig & SIG_DILITHIUM) {
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, ml_dsa_44_sa_algo,
keySz, &idx);
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, ml_dsa_65_sa_algo,
keySz, &idx);
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, ml_dsa_87_sa_algo,
keySz, &idx);
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level2_sa_algo,
keySz, &idx);
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level3_sa_algo,
keySz, &idx);
AddSuiteHashSigAlgo(hashSigAlgo, no_mac, dilithium_level5_sa_algo,
keySz, &idx);
#endif
}
#endif /* HAVE_DILITHIUM */
if (haveSig & SIG_RSA) {
Expand Down Expand Up @@ -4582,8 +4607,26 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
}
break;
#endif
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)
#if defined(HAVE_DILITHIUM)
case PQC_SA_MAJOR:
/* Hash performed as part of sign/verify operation. */
if (input[1] == ML_DSA_44_SA_MINOR) {
*hsType = ml_dsa_44_sa_algo;
*hashAlgo = sha256_mac;
}
else if (input[1] == ML_DSA_65_SA_MINOR) {
*hsType = ml_dsa_65_sa_algo;
*hashAlgo = sha384_mac;
}
else if (input[1] == ML_DSA_87_SA_MINOR) {
*hsType = ml_dsa_87_sa_algo;
*hashAlgo = sha512_mac;
}
break;
#endif /* HAVE_DILITHIUM */
#if defined(HAVE_FALCON) || \
(defined(HAVE_DILITHIUM) && defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT))
case PQC_DEV_SA_MAJOR:
/* Hash performed as part of sign/verify operation.
* However, if we want a dual alg signature with a
* classic algorithm as alternative, we need an explicit
Expand All @@ -4599,7 +4642,7 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
*hashAlgo = sha512_mac;
}
#endif /* HAVE_FALCON */
#ifdef HAVE_DILITHIUM
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT)
if (input[1] == DILITHIUM_LEVEL2_SA_MINOR) {
*hsType = dilithium_level2_sa_algo;
*hashAlgo = sha256_mac;
Expand All @@ -4612,7 +4655,7 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
*hsType = dilithium_level5_sa_algo;
*hashAlgo = sha512_mac;
}
#endif /* HAVE_DILITHIUM */
#endif /* HAVE_DILITHIUM && WOLFSSL_DILITHIUM_FIPS204_DRAFT */
break;
#endif
default:
Expand Down Expand Up @@ -29309,9 +29352,15 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length)
else if ((ssl->buffers.keyType == falcon_level1_sa_algo) ||
(ssl->buffers.keyType == falcon_level5_sa_algo))
ssl->hsType = DYNAMIC_TYPE_FALCON;
else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) ||
else if (
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
(ssl->buffers.keyType == dilithium_level2_sa_algo) ||
(ssl->buffers.keyType == dilithium_level3_sa_algo) ||
(ssl->buffers.keyType == dilithium_level5_sa_algo))
(ssl->buffers.keyType == dilithium_level5_sa_algo) ||
#endif
(ssl->buffers.keyType == ml_dsa_44_sa_algo) ||
(ssl->buffers.keyType == ml_dsa_65_sa_algo) ||
(ssl->buffers.keyType == ml_dsa_87_sa_algo))
ssl->hsType = DYNAMIC_TYPE_DILITHIUM;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
Expand Down Expand Up @@ -29405,9 +29454,15 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length)
ret = NOT_COMPILED_IN;
#endif
}
else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) ||
else if (
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
(ssl->buffers.keyType == dilithium_level2_sa_algo) ||
(ssl->buffers.keyType == dilithium_level3_sa_algo) ||
(ssl->buffers.keyType == dilithium_level5_sa_algo)) {
(ssl->buffers.keyType == dilithium_level5_sa_algo) ||
#endif
(ssl->buffers.keyType == ml_dsa_44_sa_algo) ||
(ssl->buffers.keyType == ml_dsa_65_sa_algo) ||
(ssl->buffers.keyType == ml_dsa_87_sa_algo)) {
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN)
if (ssl->buffers.keyLabel) {
ret = wc_dilithium_init_label((dilithium_key*)ssl->hsKey,
Expand All @@ -29421,15 +29476,32 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length)
ssl->buffers.keyDevId);
}
if (ret == 0) {
if (ssl->buffers.keyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_44);
if (ssl->buffers.keyType == ml_dsa_44_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_44);
}
else if (ssl->buffers.keyType == ml_dsa_65_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_65);
}
else if (ssl->buffers.keyType == ml_dsa_87_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_87);
}
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
else if (ssl->buffers.keyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_44_DRAFT);
}
else if (ssl->buffers.keyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_65);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_65_DRAFT);
}
else if (ssl->buffers.keyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_87);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_87_DRAFT);
}
#endif
}
if (ret == 0) {
if (ssl->buffers.keySz < ssl->options.minDilithiumKeySz) {
Expand Down Expand Up @@ -29750,9 +29822,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length)
FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
#endif

if (ssl->buffers.keyType == dilithium_level2_sa_algo ||
if (ssl->buffers.keyType == ml_dsa_44_sa_algo ||
ssl->buffers.keyType == ml_dsa_65_sa_algo ||
ssl->buffers.keyType == ml_dsa_87_sa_algo ||
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
ssl->buffers.keyType == dilithium_level2_sa_algo ||
ssl->buffers.keyType == dilithium_level3_sa_algo ||
ssl->buffers.keyType == dilithium_level5_sa_algo ||
#endif
ssl->buffers.keyType == 0) {

ssl->hsType = DYNAMIC_TYPE_DILITHIUM;
Expand All @@ -29761,15 +29838,32 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length)
goto exit_dpk;
}

if (ssl->buffers.keyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_44);
if (ssl->buffers.keyType == ml_dsa_44_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_44);
}
else if (ssl->buffers.keyType == ml_dsa_65_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_65);
}
else if (ssl->buffers.keyType == ml_dsa_87_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_87);
}
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
else if (ssl->buffers.keyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_44_DRAFT);
}
else if (ssl->buffers.keyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_65);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_65_DRAFT);
}
else if (ssl->buffers.keyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_87);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey,
WC_ML_DSA_87_DRAFT);
}
#endif
else {
/* What if ssl->buffers.keyType is 0? We might want to do something
* more graceful here. */
Expand Down Expand Up @@ -29861,9 +29955,15 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
else if ((ssl->buffers.altKeyType == falcon_level1_sa_algo) ||
(ssl->buffers.altKeyType == falcon_level5_sa_algo))
ssl->hsAltType = DYNAMIC_TYPE_FALCON;
else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
else if (
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
(ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level3_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level5_sa_algo))
(ssl->buffers.altKeyType == dilithium_level5_sa_algo) ||
#endif
(ssl->buffers.altKeyType == ml_dsa_44_sa_algo) ||
(ssl->buffers.altKeyType == ml_dsa_65_sa_algo) ||
(ssl->buffers.altKeyType == ml_dsa_87_sa_algo))
ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
if (ret != 0) {
Expand Down Expand Up @@ -29957,9 +30057,15 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
ret = NOT_COMPILED_IN;
#endif
}
else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
else if (
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
(ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level3_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level5_sa_algo)) {
(ssl->buffers.altKeyType == dilithium_level5_sa_algo) ||
#endif
(ssl->buffers.altKeyType == ml_dsa_44_sa_algo) ||
(ssl->buffers.altKeyType == ml_dsa_65_sa_algo) ||
(ssl->buffers.altKeyType == ml_dsa_87_sa_algo)) {
#if defined(HAVE_DILITHIUM)
if (ssl->buffers.altKeyLabel) {
ret = wc_dilithium_init_label((dilithium_key*)ssl->hsAltKey,
Expand All @@ -29973,18 +30079,38 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
ssl->buffers.altKeyDevId);
}
if (ret == 0) {
if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) {
if (ssl->buffers.altKeyType == ml_dsa_44_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, WC_ML_DSA_44);
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_44);
}
else if (ssl->buffers.altKeyType == ml_dsa_65_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_65);
}
else if (ssl->buffers.altKeyType == ml_dsa_87_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_87);
}
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
else if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_44_DRAFT);
}
else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, WC_ML_DSA_65);
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_65_DRAFT);
}
else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, WC_ML_DSA_87);
(dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_87_DRAFT);
}
#endif
}
if (ret == 0) {
if (ssl->buffers.altKeySz < ssl->options.minDilithiumKeySz) {
Expand Down Expand Up @@ -30182,9 +30308,14 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey);
#endif

if (ssl->buffers.altKeyType == dilithium_level2_sa_algo ||
if (ssl->buffers.altKeyType == ml_dsa_44_sa_algo ||
ssl->buffers.altKeyType == ml_dsa_65_sa_algo ||
ssl->buffers.altKeyType == ml_dsa_87_sa_algo ||
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
ssl->buffers.altKeyType == dilithium_level2_sa_algo ||
ssl->buffers.altKeyType == dilithium_level3_sa_algo ||
ssl->buffers.altKeyType == dilithium_level5_sa_algo ||
#endif
ssl->buffers.altKeyType == 0) {

ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM;
Expand All @@ -30193,15 +30324,32 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
goto exit_dapk;
}

if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_44);
if (ssl->buffers.altKeyType == ml_dsa_44_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_44);
}
else if (ssl->buffers.altKeyType == ml_dsa_65_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_65);
}
else if (ssl->buffers.altKeyType == ml_dsa_87_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_87);
}
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
else if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_44_DRAFT);
}
else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_65);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_65_DRAFT);
}
else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_87);
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey,
WC_ML_DSA_87_DRAFT);
}
#endif
else {
/* What if ssl->buffers.keyType is 0? We might want to do something
* more graceful here. */
Expand Down
Loading

0 comments on commit f11bb73

Please sign in to comment.