Skip to content

Commit

Permalink
Add more PQC hybrid key exchange algorithms
Browse files Browse the repository at this point in the history
Add support for all remaining hybrid PQC + ECC hybrid key exchange
groups to match OQS. Next to two new combinations with SECP curves, this
mainly also adds support for combinations with X25519 and X448.

This also enables compatability with the PQC key exchange support in
Chromium browsers and Mozilla Firefox (hybrid Kyber768 and X25519; when
`WOLFSSL_ML_KEM` is not defined).

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

Signed-off-by: Tobias Frauenschläger <tobias.frauenschlaeger@oth-regensburg.de>
  • Loading branch information
Frauschi committed Aug 21, 2024
1 parent 2505a59 commit 418b80e
Show file tree
Hide file tree
Showing 15 changed files with 553 additions and 295 deletions.
11 changes: 8 additions & 3 deletions examples/benchmark/tls_bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,14 @@ static struct group_info groups[] = {
{ 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_P384_KYBER_LEVEL5, "P384_KYBER_LEVEL5" },
{ WOLFSSL_X25519_KYBER_LEVEL1, "X25519_KYBER_LEVEL1" },
{ WOLFSSL_X448_KYBER_LEVEL3, "X448_KYBER_LEVEL3" },
{ WOLFSSL_X25519_KYBER_LEVEL3, "X25519_KYBER_LEVEL3" },
#endif
{ 0, NULL }
};
Expand Down
22 changes: 21 additions & 1 deletion examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,29 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
else 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 if (XSTRCMP(pqcAlg, "P521_KYBER_LEVEL5") == 0) {
group = WOLFSSL_P521_KYBER_LEVEL5;
} else {
}
else if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL5") == 0) {
group = WOLFSSL_P384_KYBER_LEVEL5;
}
#ifdef HAVE_CURVE25519
else if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL1") == 0) {
group = WOLFSSL_X25519_KYBER_LEVEL1;
}
else if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL3") == 0) {
group = WOLFSSL_X25519_KYBER_LEVEL3;
}
#endif
#ifdef HAVE_CURVE448
else if (XSTRCMP(pqcAlg, "X448_KYBER_LEVEL3") == 0) {
group = WOLFSSL_X448_KYBER_LEVEL3;
}
#endif
else {
err_sys("invalid post-quantum KEM specified");
}

Expand Down
19 changes: 19 additions & 0 deletions examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,9 +725,28 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
else 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 if (XSTRCMP(pqcAlg, "P521_KYBER_LEVEL5") == 0) {
groups[count] = WOLFSSL_P521_KYBER_LEVEL5;
}
else if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL5") == 0) {
groups[count] = WOLFSSL_P384_KYBER_LEVEL5;
}
#ifdef HAVE_CURVE25519
else if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL1") == 0) {
groups[count] = WOLFSSL_X25519_KYBER_LEVEL1;
}
else if (XSTRCMP(pqcAlg, "X25519_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_X25519_KYBER_LEVEL3;
}
#endif
#ifdef HAVE_CURVE448
else if (XSTRCMP(pqcAlg, "X448_KYBER_LEVEL3") == 0) {
groups[count] = WOLFSSL_X448_KYBER_LEVEL3;
}
#endif

if (groups[count] == 0) {
err_sys("invalid post-quantum KEM specified");
Expand Down
74 changes: 57 additions & 17 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3280,6 +3280,11 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_P256_KYBER_LEVEL1:
case WOLFSSL_P384_KYBER_LEVEL3:
case WOLFSSL_P521_KYBER_LEVEL5:
case WOLFSSL_P384_KYBER_LEVEL5:
case WOLFSSL_X25519_KYBER_LEVEL1:
case WOLFSSL_X448_KYBER_LEVEL3:
case WOLFSSL_X25519_KYBER_LEVEL3:
case WOLFSSL_P256_KYBER_LEVEL3:
#endif
#endif
return 1;
Expand Down Expand Up @@ -14289,41 +14294,71 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
* check to override this result in the case of a hybrid. */
if (IsAtLeastTLSv1_3(ssl->version)) {
switch (ssl->namedGroup) {
#ifdef HAVE_LIBOQS
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
case WOLFSSL_KYBER_LEVEL3:
return "KYBER_LEVEL3";
case WOLFSSL_KYBER_LEVEL5:
return "KYBER_LEVEL5";
case WOLFSSL_P256_KYBER_LEVEL1:
return "P256_KYBER_LEVEL1";
case WOLFSSL_P384_KYBER_LEVEL3:
return "P384_KYBER_LEVEL3";
case WOLFSSL_P521_KYBER_LEVEL5:
return "P521_KYBER_LEVEL5";
#elif defined(HAVE_PQM4)
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
#elif defined(WOLFSSL_WC_KYBER)
#if defined(WOLFSSL_WC_KYBER)
#ifdef WOLFSSL_KYBER512
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
case WOLFSSL_P256_KYBER_LEVEL1:
return "P256_KYBER_LEVEL1";
#ifdef HAVE_CURVE25519
case WOLFSSL_X25519_KYBER_LEVEL1:
return "X25519_KYBER_LEVEL1";
#endif
#endif
#ifdef WOLFSSL_KYBER768
case WOLFSSL_KYBER_LEVEL3:
return "KYBER_LEVEL3";
case WOLFSSL_P384_KYBER_LEVEL3:
return "P384_KYBER_LEVEL3";
case WOLFSSL_P256_KYBER_LEVEL3:
return "P256_KYBER_LEVEL3";
#ifdef HAVE_CURVE25519
case WOLFSSL_X25519_KYBER_LEVEL3:
return "X25519_KYBER_LEVEL3";
#endif
#ifdef HAVE_CURVE448
case WOLFSSL_X448_KYBER_LEVEL3:
return "X448_KYBER_LEVEL3";
#endif
#endif
#ifdef WOLFSSL_KYBER1024
case WOLFSSL_KYBER_LEVEL5:
return "KYBER_LEVEL5";
case WOLFSSL_P521_KYBER_LEVEL5:
return "P521_KYBER_LEVEL5";
case WOLFSSL_P384_KYBER_LEVEL5:
return "P384_KYBER_LEVEL5";
#endif
#elif defined (HAVE_LIBOQS)
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
case WOLFSSL_KYBER_LEVEL3:
return "KYBER_LEVEL3";
case WOLFSSL_KYBER_LEVEL5:
return "KYBER_LEVEL5";
case WOLFSSL_P256_KYBER_LEVEL1:
return "P256_KYBER_LEVEL1";
case WOLFSSL_P384_KYBER_LEVEL3:
return "P384_KYBER_LEVEL3";
case WOLFSSL_P256_KYBER_LEVEL3:
return "P256_KYBER_LEVEL3";
case WOLFSSL_P521_KYBER_LEVEL5:
return "P521_KYBER_LEVEL5";
case WOLFSSL_P384_KYBER_LEVEL5:
return "P384_KYBER_LEVEL5";
#ifdef HAVE_CURVE25519
case WOLFSSL_X25519_KYBER_LEVEL1:
return "X25519_KYBER_LEVEL1";
case WOLFSSL_X25519_KYBER_LEVEL3:
return "X25519_KYBER_LEVEL3";
#endif
#ifdef HAVE_CURVE448
case WOLFSSL_X448_KYBER_LEVEL3:
return "X448_KYBER_LEVEL3";
#endif
#elif defined(HAVE_PQM4)
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
#endif
}
}
Expand Down Expand Up @@ -21555,7 +21590,12 @@ const WOLF_EC_NIST_NAME kNistCurves[] = {
#if (defined(WOLFSSL_WC_KYBER) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC)
{CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("P256_KYBER_LEVEL3"), WOLFSSL_P256_KYBER_LEVEL3, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("P384_KYBER_LEVEL5"), WOLFSSL_P384_KYBER_LEVEL5, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("X25519_KYBER_LEVEL1"), WOLFSSL_X25519_KYBER_LEVEL1, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("X448_KYBER_LEVEL3"), WOLFSSL_X448_KYBER_LEVEL3, WOLFSSL_P256_KYBER_LEVEL1},
{CURVE_NAME("X25519_KYBER_LEVEL3"), WOLFSSL_X25519_KYBER_LEVEL3, WOLFSSL_P256_KYBER_LEVEL1},
#endif
#endif
#ifdef WOLFSSL_SM2
Expand Down
Loading

0 comments on commit 418b80e

Please sign in to comment.