Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more PQC hybrid key exchange algorithms #7821

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" },
Comment on lines +299 to +301
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its interesting.

You are adding :

  • WOLFSSL_X25519_KYBER_LEVEL1
  • WOLFSSL_X448_KYBER_LEVEL3
  • WOLFSSL_X25519_KYBER_LEVEL3
  • WOLFSSL_P256_KYBER_LEVEL3
  • WOLFSSL_P384_KYBER_LEVEL5

Can you let us know why you are adding these? I suppose they are to interop with other places, but can you let us know specifically (ie which ones are mozilla and which ones are liboqs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am currently investigating the real-world performance impact of various PQC deployments in different embedded context (for my PhD). As hybrid constellations using X25519 and X448 are pretty popular in other projects, I wanted to test them, too. That's why I started this work in the first place.

The compatibility with the web browsers is based on the use case to access a web-based management interface of an embedded device and to make that PQC secure. For that, WOLFSSL_X25519_KYBER_LEVEL3 is the relevant hybrid constellation (that is what browser vendors are currently settled on).

The other constellations are based on what OQS has defined. I added them (besides my internal performance tests) for general interoperability with OQS and because it wasn't much overhead anyway.

#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
Loading