Skip to content

Commit

Permalink
Improvements for PQC hybrid key exchange
Browse files Browse the repository at this point in the history
Add support for X25519 and X448 based hybrid PQC + ECC key exchange
groups. Furthermore, two new combinations with SECP curves are added to
match OQS combinations.

This also incorporates the changed order of X25519 and X448 based
combinations to place the PQC material before the ECDH material. This is
motivated by the necessity to always have material of a FIPS approved
algorithm first.

Also, codepoints are updated to reflect the latest draft standards for
pure ML-KEM and some of the hybrids. With these changes and based on the
recent additions to both enable ML-KEM final and draft versions
simultaneously, a WolfSSL TLS server is now compatible with all recent
browsers that support either the draft version of ML-KEM (Chromium based
browsers and Firefox < version 132; only when the draft version is
enabled in the build) or the final version already (Firefox > version 132).

In the process of extending support, some code and logic cleanup
happened. Furthermore, some memory leaks within the hybrid code path have
been fixed.

Signed-off-by: Tobias Frauenschläger <[email protected]>
  • Loading branch information
Frauschi committed Jan 28, 2025
1 parent c48ba69 commit 4b90007
Show file tree
Hide file tree
Showing 20 changed files with 1,838 additions and 615 deletions.
21 changes: 15 additions & 6 deletions examples/benchmark/tls_bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,17 +296,26 @@ static struct group_info groups[] = {
{ WOLFSSL_ML_KEM_512, "ML_KEM_512" },
{ WOLFSSL_ML_KEM_768, "ML_KEM_768" },
{ WOLFSSL_ML_KEM_1024, "ML_KEM_1024" },
{ WOLFSSL_P256_ML_KEM_512, "P256_ML_KEM_512" },
{ WOLFSSL_P384_ML_KEM_768, "P384_ML_KEM_768" },
{ WOLFSSL_P521_ML_KEM_1024, "P521_ML_KEM_1024" },
{ WOLFSSL_P256_ML_KEM_512, "P256_ML_KEM_512" },
{ WOLFSSL_P384_ML_KEM_768, "P384_ML_KEM_768" },
{ WOLFSSL_P256_ML_KEM_768, "P256_ML_KEM_768" },
{ WOLFSSL_P521_ML_KEM_1024, "P521_ML_KEM_1024" },
{ WOLFSSL_P384_ML_KEM_1024, "P384_ML_KEM_1024" },
{ WOLFSSL_X25519_ML_KEM_512, "X25519_ML_KEM_512" },
{ WOLFSSL_X448_ML_KEM_768, "X448_ML_KEM_768" },
{ WOLFSSL_X25519_ML_KEM_768, "X25519_ML_KEM_768" },
#endif
#ifdef WOLFSSL_KYBER_ORIGINAL
{ WOLFSSL_KYBER_LEVEL1, "KYBER_LEVEL1" },
{ WOLFSSL_KYBER_LEVEL3, "KYBER_LEVEL3" },
{ WOLFSSL_KYBER_LEVEL5, "KYBER_LEVEL5" },
{ WOLFSSL_P256_KYBER_LEVEL1, "P256_KYBER_LEVEL1" },
{ WOLFSSL_P384_KYBER_LEVEL3, "P384_KYBER_LEVEL3" },
{ WOLFSSL_P521_KYBER_LEVEL5, "P521_KYBER_LEVEL5" },
{ WOLFSSL_P256_KYBER_LEVEL1, "P256_KYBER_LEVEL1" },
{ WOLFSSL_P384_KYBER_LEVEL3, "P384_KYBER_LEVEL3" },
{ WOLFSSL_P256_KYBER_LEVEL3, "P256_KYBER_LEVEL3" },
{ WOLFSSL_P521_KYBER_LEVEL5, "P521_KYBER_LEVEL5" },
{ WOLFSSL_X25519_KYBER_LEVEL1, "X25519_KYBER_LEVEL1" },
{ WOLFSSL_X448_KYBER_LEVEL3, "X448_KYBER_LEVEL3" },
{ WOLFSSL_X25519_KYBER_LEVEL3, "X25519_KYBER_LEVEL3" },
#endif
#endif
{ 0, NULL }
Expand Down
55 changes: 53 additions & 2 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,36 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
if (XSTRCMP(pqcAlg, "P384_ML_KEM_768") == 0) {
group = WOLFSSL_P384_ML_KEM_768;
}
else if (XSTRCMP(pqcAlg, "P256_ML_KEM_768") == 0) {
group = WOLFSSL_P256_ML_KEM_768;
}
else
#endif
#ifndef WOLFSSL_NO_ML_KEM_1024
if (XSTRCMP(pqcAlg, "P521_ML_KEM_1024") == 0) {
group = WOLFSSL_P521_ML_KEM_1024;
}
else if (XSTRCMP(pqcAlg, "P384_ML_KEM_1024") == 0) {
group = WOLFSSL_P384_ML_KEM_1024;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_ML_KEM_512") == 0) {
group = WOLFSSL_X25519_ML_KEM_512;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_ML_KEM_768") == 0) {
group = WOLFSSL_X25519_ML_KEM_768;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448)
if (XSTRCMP(pqcAlg, "X448_ML_KEM_768") == 0) {
group = WOLFSSL_X448_ML_KEM_768;
}
else
#endif
#endif /* WOLFSSL_NO_ML_KEM */
Expand Down Expand Up @@ -469,6 +493,9 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL3") == 0) {
group = WOLFSSL_P384_KYBER_LEVEL3;
}
else if (XSTRCMP(pqcAlg, "P256_KYBER_LEVEL3") == 0) {
group = WOLFSSL_P256_KYBER_LEVEL3;
}
else
#endif
#ifndef WOLFSSL_NO_KYBER1024
Expand All @@ -477,6 +504,24 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER512) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL1") == 0) {
group = WOLFSSL_X25519_KYBER_LEVEL1;
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER768) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL3") == 0) {
group = WOLFSSL_X25519_KYBER_LEVEL3;
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER768) && defined(HAVE_CURVE448)
if (XSTRCMP(pqcAlg, "X448_KYBER_LEVEL3") == 0) {
group = WOLFSSL_X448_KYBER_LEVEL3;
}
else
#endif
#endif /* WOLFSSL_KYBER_ORIGINAL */
{
err_sys("invalid post-quantum KEM specified");
Expand Down Expand Up @@ -1378,12 +1423,18 @@ static const char* client_usage_msg[][78] = {
#ifndef WOLFSSL_NO_ML_KEM
" ML_KEM_512, ML_KEM_768, ML_KEM_1024, P256_ML_KEM_512,"
"\n"
" P384_ML_KEM_768, P521_ML_KEM_1024\n"
" P384_ML_KEM_768, P256_ML_KEM_768, P521_ML_KEM_1024,\n"
" P384_ML_KEM_1024, X25519_ML_KEM_512, "
"X25519_ML_KEM_768,\n"
" X448_ML_KEM_768\n"
#endif
#ifdef WOLFSSL_KYBER_ORIGINAL
" KYBER_LEVEL1, KYBER_LEVEL3, KYBER_LEVEL5, "
"P256_KYBER_LEVEL1,\n"
" P384_KYBER_LEVEL3, P521_KYBER_LEVEL5\n"
" P384_KYBER_LEVEL3, P256_KYBER_LEVEL3, "
"P521_KYBER_LEVEL5,\n"
" X25519_KYBER_LEVEL1, X25519_KYBER_LEVEL3, "
"X448_KYBER_LEVEL3\n"
#endif
"",
/* 69 */
Expand Down
55 changes: 53 additions & 2 deletions examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,12 +744,36 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
if (XSTRCMP(pqcAlg, "P384_ML_KEM_768") == 0) {
groups[count] = WOLFSSL_P384_ML_KEM_768;
}
else if (XSTRCMP(pqcAlg, "P256_ML_KEM_768") == 0) {
groups[count] = WOLFSSL_P256_ML_KEM_768;
}
else
#endif
#ifndef WOLFSSL_NO_ML_KEM_1024
if (XSTRCMP(pqcAlg, "P521_ML_KEM_1024") == 0) {
groups[count] = WOLFSSL_P521_ML_KEM_1024;
}
else if (XSTRCMP(pqcAlg, "P384_ML_KEM_1024") == 0) {
groups[count] = WOLFSSL_P384_ML_KEM_1024;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_ML_KEM_512") == 0) {
groups[count] = WOLFSSL_X25519_ML_KEM_512;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_ML_KEM_768") == 0) {
groups[count] = WOLFSSL_X25519_ML_KEM_768;
}
else
#endif
#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448)
if (XSTRCMP(pqcAlg, "X448_ML_KEM_768") == 0) {
groups[count] = WOLFSSL_X448_ML_KEM_768;
}
else
#endif
#endif /* WOLFSSL_NO_ML_KEM */
Expand Down Expand Up @@ -782,6 +806,9 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_P384_KYBER_LEVEL3;
}
else if (XSTRCMP(pqcAlg, "P256_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_P256_KYBER_LEVEL3;
}
else
#endif
#ifndef WOLFSSL_NO_KYBER1024
Expand All @@ -790,6 +817,24 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER512) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL1") == 0) {
groups[count] = WOLFSSL_X25519_KYBER_LEVEL1;
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER768) && defined(HAVE_CURVE25519)
if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_X25519_KYBER_LEVEL3;
}
else
#endif
#if !defined(WOLFSSL_NO_KYBER768) && defined(HAVE_CURVE448)
if (XSTRCMP(pqcAlg, "X448_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_X448_KYBER_LEVEL3;
}
else
#endif
#endif
{
err_sys("invalid post-quantum KEM specified");
Expand Down Expand Up @@ -1027,12 +1072,18 @@ static const char* server_usage_msg[][66] = {
#ifndef WOLFSSL_NO_ML_KEM
" ML_KEM_512, ML_KEM_768, ML_KEM_1024, P256_ML_KEM_512,"
"\n"
" P384_ML_KEM_768, P521_ML_KEM_1024\n"
" P384_ML_KEM_768, P256_ML_KEM_768, P521_ML_KEM_1024,\n"
" P384_ML_KEM_1024, X25519_ML_KEM_512, "
"X25519_ML_KEM_768,\n"
" X448_ML_KEM_768\n"
#endif
#ifdef WOLFSSL_KYBER_ORIGINAL
" KYBER_LEVEL1, KYBER_LEVEL3, KYBER_LEVEL5, "
"P256_KYBER_LEVEL1,\n"
" P384_KYBER_LEVEL3, P521_KYBER_LEVEL5\n"
" P384_KYBER_LEVEL3, P256_KYBER_LEVEL3, "
"P521_KYBER_LEVEL5,\n"
" X25519_KYBER_LEVEL1, X25519_KYBER_LEVEL3, "
"X448_KYBER_LEVEL3\n"
#endif
"",
/* 60 */
Expand Down
51 changes: 51 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -35054,6 +35054,57 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif /* HAVE_ECC */

#ifdef WOLFSSL_HAVE_KYBER
/* Returns 1 when the given group is a PQC group, 0 otherwise. */
int NamedGroupIsPqc(int group)
{
switch (group) {
#ifndef WOLFSSL_NO_ML_KEM
case WOLFSSL_ML_KEM_512:
case WOLFSSL_ML_KEM_768:
case WOLFSSL_ML_KEM_1024:
#endif
#ifdef WOLFSSL_KYBER_ORIGINAL
case WOLFSSL_KYBER_LEVEL1:
case WOLFSSL_KYBER_LEVEL3:
case WOLFSSL_KYBER_LEVEL5:
#endif
return 1;
default:
return 0;
}
}

/* Returns 1 when the given group is a PQC hybrid group, 0 otherwise. */
int NamedGroupIsPqcHybrid(int group)
{
switch (group) {
#ifndef WOLFSSL_NO_ML_KEM
case WOLFSSL_P256_ML_KEM_768:
case WOLFSSL_X25519_ML_KEM_768:
case WOLFSSL_P384_ML_KEM_1024:
case WOLFSSL_P256_ML_KEM_512:
case WOLFSSL_P384_ML_KEM_768:
case WOLFSSL_P521_ML_KEM_1024:
case WOLFSSL_X25519_ML_KEM_512:
case WOLFSSL_X448_ML_KEM_768:
#endif
#ifdef WOLFSSL_KYBER_ORIGINAL
case WOLFSSL_P256_KYBER_LEVEL3:
case WOLFSSL_X25519_KYBER_LEVEL3:
case WOLFSSL_P256_KYBER_LEVEL1:
case WOLFSSL_P384_KYBER_LEVEL3:
case WOLFSSL_P521_KYBER_LEVEL5:
case WOLFSSL_X25519_KYBER_LEVEL1:
case WOLFSSL_X448_KYBER_LEVEL3:
#endif
return 1;
default:
return 0;
}
}
#endif /* WOLFSSL_HAVE_KYBER */

int TranslateErrorToAlert(int err)
{
switch (err) {
Expand Down
Loading

0 comments on commit 4b90007

Please sign in to comment.