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_KYBER_ORIGINAL` is 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 <[email protected]>
  • Loading branch information
Frauschi committed Sep 19, 2024
1 parent b990840 commit 6d0774b
Show file tree
Hide file tree
Showing 17 changed files with 606 additions and 325 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
25 changes: 24 additions & 1 deletion examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,38 @@ 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
if (XSTRCMP(pqcAlg, "P521_KYBER_LEVEL5") == 0) {
group = WOLFSSL_P521_KYBER_LEVEL5;
}
else if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL5") == 0) {
group = WOLFSSL_P384_KYBER_LEVEL5;
}
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;
}
#endif
else {
err_sys("invalid post-quantum KEM specified");
}

Expand Down
24 changes: 24 additions & 0 deletions examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,12 +740,36 @@ 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
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;
}
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
{
Expand Down
23 changes: 23 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -34131,6 +34131,29 @@ 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) {
case WOLFSSL_KYBER_LEVEL1:
case WOLFSSL_KYBER_LEVEL3:
case WOLFSSL_KYBER_LEVEL5:
case WOLFSSL_P256_KYBER_LEVEL3:
case WOLFSSL_X25519_KYBER_LEVEL3:
case WOLFSSL_P384_KYBER_LEVEL5:
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:
return 1;
default:
return 0;
}
}
#endif /* WOLFSSL_HAVE_KYBER */

int TranslateErrorToAlert(int err)
{
switch (err) {
Expand Down
68 changes: 54 additions & 14 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3304,6 +3304,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 @@ -14448,37 +14453,67 @@ 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(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
#endif
}
Expand Down Expand Up @@ -21775,7 +21810,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 6d0774b

Please sign in to comment.