Merge pull request #4320 from anhu/liboqs_keyshare_updated

WolfSSL support for OQS's implementation of NIST Round 3 KEMs as TLS 1.3 groups
This commit is contained in:
David Garske 2021-08-27 17:42:25 -07:00 committed by GitHub
commit c7645a42a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 773 additions and 37 deletions

47
INSTALL
View File

@ -136,3 +136,50 @@
2) Run the Visual Studio batch to setup command line variables, e.g. C:\Program Files (x86)\Microsoft Visual
Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
3) Follow steps in "Unix-based Platforms" above.
15. Building with liboqs for TLS 1.3 KEM Groups [EXPERIMENTAL]
In order be able to use liboqs, you must have it built and installed on your
system. For example, on linux, this would be sufficient:
$ cd liboqs
$ mkdir build
$ cd build
$ cmake -DOQS_USE_OPENSSL=0 ..
$ make all
$ sudo make install
And then for building wolfssl, the following is sufficient:
$ cd wolfssl
$ ./autogen.sh (Might not be necessary)
$ ./configure --with-liboqs
$ make all
Execute the following to see the liboqs-related options near the end of the
output of these commands:
$ ./examples/server/server -?
$ ./examples/client/client -?
For a quick start, you can run the client and server like this:
$ ./examples/server/server -v 4 --oqs KYBER512
$ ./examples/client/client -v 4 --oqs KYBER512
Look for the following line in the output of the server and client:
```
Using OQS KEM: KYBER512
```
The following NIST Competition Round 3 Finalist KEMs are supported:
- CRYSTALS-KYBER
- SABER
- NTRU
Links to more information about these algorithms can be found here:
https://csrc.nist.gov/projects/post-quantum-cryptography/round-3-submissions
NOTE: The quantum-safe algorithms provided by LIBOQS are unstandardized and
experimental. It is highly advised that they NOT be used in production
environments.

View File

@ -3741,6 +3741,52 @@ then
fi
# liboqs
ENABLED_LIBOQS="no"
tryliboqsdir=""
AC_ARG_WITH([liboqs],
[AS_HELP_STRING([--with-liboqs=PATH],[Path to liboqs install (default /usr/local) EXPERIMENTAL!])],
[
AC_MSG_CHECKING([for liboqs])
CPPFLAGS="$CPPFLAGS -DHAVE_LIBOQS -DHAVE_TLS_EXTENSIONS"
LIBS="$LIBS -loqs"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <oqs/common.h>]], [[ OQS_init(); ]])], [ liboqs_linked=yes ],[ liboqs_linked=no ])
if test "x$liboqs_linked" = "xno" ; then
if test "x$withval" != "xno" ; then
tryliboqsdir=$withval
fi
if test "x$withval" = "xyes" ; then
tryliboqsdir="/usr/local"
fi
LDFLAGS="$AM_LDFLAGS $LDFLAGS -L$tryliboqsdir/lib"
CPPFLAGS="$CPPFLAGS -I$tryliboqsdir/include"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <oqs/common.h>]], [[ OQS_init(); ]])], [ liboqs_linked=yes ],[ liboqs_linked=no ])
if test "x$liboqs_linked" = "xno" ; then
AC_MSG_ERROR([liboqs isn't found.
If it's already installed, specify its path using --with-liboqs=/dir/])
fi
AC_MSG_RESULT([yes])
AM_LDFLAGS="$AM_LDFLAGS -L$tryliboqsdir/lib"
else
AC_MSG_RESULT([yes])
fi
if test "x$ENABLED_OPENSSLEXTRA" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno"
then
ENABLED_OPENSSLEXTRA="yes"
AM_CFLAGS="-DOPENSSL_EXTRA $AM_CFLAGS"
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBOQS -DHAVE_TLS_EXTENSIONS"
ENABLED_LIBOQS="yes"
]
)
# Whitewood netRandom client library
ENABLED_WNR="no"
trywnrdir=""
@ -3942,11 +3988,12 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_REQUIRE_FFDHE"
fi
# TLS 1.3 Requires either ECC or (RSA/DH), or CURVE25519/ED25519 or CURVE448/ED448
# TLS 1.3 Requires either ECC or (RSA/DH), or CURVE25519/ED25519 or CURVE448/ED448 or libOQS
if test "x$ENABLED_PSK" = "xno" && test "x$ENABLED_ECC" = "xno" && \
(test "x$ENABLED_RSA" = "xno" || test "x$ENABLED_DH" = "xno") && \
(test "x$ENABLED_CURVE25519" = "xno" || test "x$ENABLED_ED25519" = "xno") && \
(test "x$ENABLED_CURVE448" = "xno" || test "x$ENABLED_ED448" = "xno")
(test "x$ENABLED_CURVE448" = "xno" || test "x$ENABLED_ED448" = "xno") && \
test "x$ENABLED_LIBOQS" = "xno"
then
# disable TLS 1.3
ENABLED_TLS13=no
@ -6754,6 +6801,7 @@ AM_CONDITIONAL([BUILD_CRL_MONITOR],[test "x$ENABLED_CRL_MONITOR" = "xyes"])
AM_CONDITIONAL([BUILD_USER_RSA],[test "x$ENABLED_USER_RSA" = "xyes"] )
AM_CONDITIONAL([BUILD_USER_CRYPTO],[test "x$ENABLED_USER_CRYPTO" = "xyes"])
AM_CONDITIONAL([BUILD_NTRU],[test "x$ENABLED_NTRU" = "xyes"])
AM_CONDITIONAL([BUILD_LIBOQS],[test "x$ENABLED_LIBOQS" = "xyes"])
AM_CONDITIONAL([BUILD_WNR],[test "x$ENABLED_WNR" = "xyes"])
AM_CONDITIONAL([BUILD_SRP],[test "x$ENABLED_SRP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([USE_VALGRIND],[test "x$ENABLED_VALGRIND" = "xyes"])
@ -7114,6 +7162,7 @@ echo " * Atomic User Record Layer: $ENABLED_ATOMICUSER"
echo " * Public Key Callbacks: $ENABLED_PKCALLBACKS"
echo " * NTRU: $ENABLED_NTRU"
echo " * QSH: $ENABLED_QSH"
echo " * liboqs: $ENABLED_LIBOQS"
echo " * Whitewood netRandom: $ENABLED_WNR"
echo " * Server Name Indication: $ENABLED_SNI"
echo " * ALPN: $ENABLED_ALPN"

View File

@ -284,7 +284,7 @@ static void ShowVersions(void)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
#define MAX_GROUP_NUMBER 4
static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
int useX448, int setGroups)
int useX448, int useLibOqs, char* oqsAlg, int setGroups)
{
int ret;
int groups[MAX_GROUP_NUMBER] = {0};
@ -292,6 +292,8 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
(void)useX25519;
(void)useX448;
(void)useLibOqs;
(void)oqsAlg;
WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
if (onlyKeyShare == 0 || onlyKeyShare == 2) {
@ -358,6 +360,72 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
} while (ret == WC_PENDING_E);
#endif
}
#ifdef HAVE_LIBOQS
if (onlyKeyShare == 0 || onlyKeyShare == 3) {
if (useLibOqs) {
int group = 0;
if (XSTRNCMP(oqsAlg, "KYBER512", XSTRLEN("KYBER512")) == 0) {
group = WOLFSSL_KYBER512;
}
else if (XSTRNCMP(oqsAlg, "KYBER768",
XSTRLEN("KYBER768")) == 0) {
group = WOLFSSL_KYBER768;
}
else if (XSTRNCMP(oqsAlg, "KYBER1024",
XSTRLEN("KYBER1024")) == 0) {
group = WOLFSSL_KYBER1024;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS2048509",
XSTRLEN("NTRU_HPS2048509")) == 0) {
group = WOLFSSL_NTRU_HPS2048509;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS2048677",
XSTRLEN("NTRU_HPS2048677")) == 0) {
group = WOLFSSL_NTRU_HPS2048677;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS4096821",
XSTRLEN("NTRU_HPS4096821")) == 0) {
group = WOLFSSL_NTRU_HPS4096821;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HRSS701",
XSTRLEN("NTRU_HRSS701")) == 0) {
group = WOLFSSL_NTRU_HRSS701;
}
else if (XSTRNCMP(oqsAlg, "LIGHTSABER",
XSTRLEN("LIGHTSABER")) == 0) {
group = WOLFSSL_LIGHTSABER;
}
else if (XSTRNCMP(oqsAlg, "SABER",
XSTRLEN("SABER")) == 0) {
group = WOLFSSL_SABER;
}
else if (XSTRNCMP(oqsAlg, "FIRESABER",
XSTRLEN("FIRESABER")) == 0) {
group = WOLFSSL_FIRESABER;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S512",
XSTRLEN("KYBER90S512")) == 0) {
group = WOLFSSL_KYBER90S512;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S768",
XSTRLEN("KYBER90S768")) == 0) {
group = WOLFSSL_KYBER90S768;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S1024",
XSTRLEN("KYBER90S1024")) == 0) {
group = WOLFSSL_KYBER90S1024;
} else {
err_sys("invalid OQS KEM specified");
}
printf("Using OQS KEM: %s\n", oqsAlg);
if (wolfSSL_UseKeyShare(ssl, group) != WOLFSSL_SUCCESS) {
err_sys("unable to use oqs KEM");
}
}
}
#endif
if (count >= MAX_GROUP_NUMBER)
err_sys("example group array size error");
if (setGroups && count > 0) {
@ -438,7 +506,8 @@ static const char* client_bench_conmsg[][5] = {
static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519,
int useX448, int helloRetry, int onlyKeyShare, int version, int earlyData)
int useX448, int useLibOqs, char* oqsAlg, int helloRetry, int onlyKeyShare,
int version, int earlyData)
{
/* time passed in number of connects give average */
int times = benchmark, skip = times * 0.1;
@ -455,6 +524,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
(void)resumeSession;
(void)useX25519;
(void)useX448;
(void)useLibOqs;
(void)oqsAlg;
(void)helloRetry;
(void)onlyKeyShare;
(void)version;
@ -484,7 +555,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
else if (version >= 4) {
if (!helloRetry)
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 1);
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448,
useLibOqs, oqsAlg, 1);
else
wolfSSL_NoKeyShares(ssl);
}
@ -568,7 +640,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
/* Measures throughput in mbps. Throughput = number of bytes */
static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519,
int useX448, int exitWithRet, int version, int onlyKeyShare)
int useX448, int useLibOqs, char* oqsAlg, int exitWithRet, int version,
int onlyKeyShare)
{
double start, conn_time = 0, tx_time = 0, rx_time = 0;
SOCKET_T sockfd;
@ -587,11 +660,14 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
(void)useX25519;
(void)useX448;
(void)useLibOqs;
(void)oqsAlg;
(void)version;
(void)onlyKeyShare;
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
if (version >= 4) {
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 1);
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, useLibOqs,
oqsAlg, 1);
}
#endif
@ -1171,10 +1247,16 @@ static const char* client_usage_msg[][70] = {
" SSLv3(0) - TLS1.2(3)\n",
#else
"-7 Set minimum downgrade protocol version [0-4] "
" SSLv3(0) - TLS1.3(4)\n\n", /* 69 */
" SSLv3(0) - TLS1.3(4)\n", /* 69 */
#endif
#ifdef HAVE_LIBOQS
"--oqs <alg> Key Share with specified liboqs algorithm only\n",
"[KYBER512, KYBER768, KYBER1024, KYBER90S512, KYBER90S768, KYBER90S1024,\n",
" NTRU_HPS2048509, NTRU_HPS2048677, NTRU_HPS4096821, NTRU_HRSS701,\n",
" LIGHTSABER, SABER, FIRESABER]\n\n", /* 70 */
#endif
"For simpler wolfSSL TLS client examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 70 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 71 */
NULL,
},
#ifndef NO_MULTIBYTE_PRINT
@ -1371,10 +1453,16 @@ static const char* client_usage_msg[][70] = {
" SSLv3(0) - TLS1.2(3)\n",
#else
"-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-4] "
" SSLv3(0) - TLS1.3(4)\n\n", /* 69 */
" SSLv3(0) - TLS1.3(4)\n", /* 69 */
#endif
#ifdef HAVE_LIBOQS
"--oqs <alg> liboqs 名前付きグループとの鍵共有のみ\n",
"[KYBER512, KYBER768, KYBER1024, KYBER90S512, KYBER90S768, KYBER90S1024,\n",
" NTRU_HPS2048509, NTRU_HPS2048677, NTRU_HPS4096821, NTRU_HRSS701,\n",
" LIGHTSABER, SABER, FIRESABER]\n\n", /* 70 */
#endif
"For simpler wolfSSL TLS client examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 70 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 71 */
NULL,
},
#endif
@ -1559,6 +1647,12 @@ static void Usage(void)
#endif
printf("%s", msg[++msgid]); /* -7 */
printf("%s", msg[++msgid]); /* Examples repo link */
#ifdef HAVE_LIBOQS
printf("%s", msg[++msgid]); /* --oqs */
printf("%s", msg[++msgid]); /* --oqs options */
printf("%s", msg[++msgid]); /* more --oqs options */
printf("%s", msg[++msgid]); /* more --oqs options */
#endif
}
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
@ -1597,6 +1691,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
{ "help", 0, 257 },
{ "ヘルプ", 0, 258 },
#if defined(HAVE_LIBOQS)
{ "oqs", 1, 259 },
#endif
{ 0, 0, 0 }
};
#endif
@ -1701,6 +1798,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
int useX25519 = 0;
int useX448 = 0;
int useLibOqs = 0;
char* oqsAlg = NULL;
int exitWithRet = 0;
int loadCertKeyIntoSSLObj = 0;
@ -1789,7 +1888,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)onlyKeyShare;
(void)useSupCurve;
(void)loadCertKeyIntoSSLObj;
(void)useLibOqs;
(void)oqsAlg;
StackTrap();
/* Reinitialize the global myVerifyAction. */
@ -2277,6 +2377,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
nonBlocking = 1;
simulateWantWrite = 1;
break;
case '7' :
minVersion = atoi(myoptarg);
if (minVersion < 0 || minVersion > 4) {
@ -2284,6 +2385,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
XEXIT_T(MY_EX_USAGE);
}
break;
case '8' :
#ifdef HAVE_CURVE448
useX448 = 1;
@ -2345,6 +2447,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
break;
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) && \
defined(HAVE_LIBOQS)
case 259:
useLibOqs = 1;
onlyKeyShare = 3;
oqsAlg = myoptarg;
break;
#endif
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -2466,6 +2576,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
err_sys("can't load whitewood net random config file");
#endif
#ifdef HAVE_LIBOQS
if (useLibOqs) {
if (version == CLIENT_DOWNGRADE_VERSION ||
version == EITHER_DOWNGRADE_VERSION)
printf("WARNING: If a TLS 1.3 connection is not negotiated, you "
"will not be using a liboqs group.\n");
else if (version != 4)
err_sys("can only use liboqs groups with TLS 1.3");
}
#endif
switch (version) {
#ifndef NO_OLD_TLS
#ifdef WOLFSSL_ALLOW_SSLV3
@ -2993,8 +3114,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
((func_args*)args)->return_code =
ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
benchmark, resumeSession, useX25519,
useX448, helloRetry, onlyKeyShare,
version, earlyData);
useX448, useLibOqs, oqsAlg, helloRetry,
onlyKeyShare, version, earlyData);
wolfSSL_CTX_free(ctx); ctx = NULL;
XEXIT_T(EXIT_SUCCESS);
}
@ -3003,7 +3124,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
((func_args*)args)->return_code =
ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP,
block, throughput, useX25519, useX448,
exitWithRet, version, onlyKeyShare);
useLibOqs, oqsAlg, exitWithRet, version,
onlyKeyShare);
wolfSSL_CTX_free(ctx); ctx = NULL;
if (!exitWithRet)
XEXIT_T(EXIT_SUCCESS);
@ -3127,7 +3249,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
if (!helloRetry && version >= 4) {
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 0);
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, useLibOqs,
oqsAlg, 0);
}
else {
wolfSSL_NoKeyShares(ssl);

View File

@ -225,7 +225,6 @@ static WC_INLINE int PeekSeq(const char* buf, word32* seq)
return 0;
}
/* The send embedded callback
* return : nb bytes sent, or error
*/
@ -587,7 +586,7 @@ static void ServerWrite(WOLFSSL* ssl, const char* output, int outputLen)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
#define MAX_GROUP_NUMBER 4
static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
int useX448)
int useX448, int useLibOqs, char* oqsAlg)
{
int ret;
int groups[MAX_GROUP_NUMBER] = {0};
@ -595,6 +594,8 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
(void)useX25519;
(void)useX448;
(void)useLibOqs;
(void)oqsAlg;
WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
if (onlyKeyShare == 2) {
@ -626,6 +627,76 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
else
err_sys("unable to use curve x448");
} while (ret == WC_PENDING_E);
#endif
}
else if (useLibOqs == 1) {
#ifdef HAVE_LIBOQS
groups[count] = 0;
if (XSTRNCMP(oqsAlg, "KYBER512", XSTRLEN("KYBER512")) == 0) {
groups[count] = WOLFSSL_KYBER512;
}
else if (XSTRNCMP(oqsAlg, "KYBER768",
XSTRLEN("KYBER768")) == 0) {
groups[count] = WOLFSSL_KYBER768;
}
else if (XSTRNCMP(oqsAlg, "KYBER1024",
XSTRLEN("KYBER1024")) == 0) {
groups[count] = WOLFSSL_KYBER1024;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS2048509",
XSTRLEN("NTRU_HPS2048509")) == 0) {
groups[count] = WOLFSSL_NTRU_HPS2048509;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS2048677",
XSTRLEN("NTRU_HPS2048677")) == 0) {
groups[count] = WOLFSSL_NTRU_HPS2048677;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HPS4096821",
XSTRLEN("NTRU_HPS4096821")) == 0) {
groups[count] = WOLFSSL_NTRU_HPS4096821;
}
else if (XSTRNCMP(oqsAlg, "NTRU_HRSS701",
XSTRLEN("NTRU_HRSS701")) == 0) {
groups[count] = WOLFSSL_NTRU_HRSS701;
}
else if (XSTRNCMP(oqsAlg, "LIGHTSABER",
XSTRLEN("LIGHTSABER")) == 0) {
groups[count] = WOLFSSL_LIGHTSABER;
}
else if (XSTRNCMP(oqsAlg, "SABER",
XSTRLEN("SABER")) == 0) {
groups[count] = WOLFSSL_SABER;
}
else if (XSTRNCMP(oqsAlg, "FIRESABER",
XSTRLEN("FIRESABER")) == 0) {
groups[count] = WOLFSSL_FIRESABER;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S512",
XSTRLEN("KYBER90S512")) == 0) {
groups[count] = WOLFSSL_KYBER90S512;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S768",
XSTRLEN("KYBER90S768")) == 0) {
groups[count] = WOLFSSL_KYBER90S768;
}
else if (XSTRNCMP(oqsAlg, "KYBER90S1024",
XSTRLEN("KYBER90S1024")) == 0) {
groups[count] = WOLFSSL_KYBER90S1024;
}
if (groups[count] == 0) {
err_sys("invalid OQS KEM specified");
}
else {
if (wolfSSL_UseKeyShare(ssl, groups[count]) == WOLFSSL_SUCCESS) {
printf("Using OQS KEM: %s\n", oqsAlg);
count++;
}
else {
groups[count] = 0;
err_sys("unable to use oqs algorithm");
}
}
#endif
}
else {
@ -818,16 +889,21 @@ static const char* server_usage_msg[][60] = {
"--wolfsentry-config <file> Path for JSON wolfSentry config\n",
/* 58 */
#endif
#ifndef WOLFSSL_TLS13
"-7 Set minimum downgrade protocol version [0-3] "
" SSLv3(0) - TLS1.2(3)\n",
#else
"-7 Set minimum downgrade protocol version [0-4] "
" SSLv3(0) - TLS1.3(4)\n\n", /* 59 */
" SSLv3(0) - TLS1.3(4)\n", /* 59 */
#endif
#ifdef HAVE_LIBOQS
"--oqs <alg> Key Share with specified liboqs algorithm only\n",
"[KYBER512, KYBER768, KYBER1024, KYBER90S512, KYBER90S768, KYBER90S1024,\n",
" NTRU_HPS2048509, NTRU_HPS2048677, NTRU_HPS4096821, NTRU_HRSS701,\n",
" LIGHTSABER, SABER, FIRESABER]\n\n", /* 60 */
#endif
"For simpler wolfSSL TLS server examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 60 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 61 */
NULL,
},
#ifndef NO_MULTIBYTE_PRINT
@ -981,10 +1057,16 @@ static const char* server_usage_msg[][60] = {
" SSLv3(0) - TLS1.2(3)\n",
#else
"-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-4] "
" SSLv3(0) - TLS1.3(4)\n\n", /* 59 */
" SSLv3(0) - TLS1.3(4)\n", /* 59 */
#endif
#ifdef HAVE_LIBOQS
"--oqs <alg> liboqs 名前付きグループとの鍵共有のみ\n",
"[KYBER512, KYBER768, KYBER1024, KYBER90S512, KYBER90S768, KYBER90S1024,\n",
" NTRU_HPS2048509, NTRU_HPS2048677, NTRU_HPS4096821, NTRU_HRSS701,\n",
" LIGHTSABER, SABER, FIRESABER]\n\n", /* 60 */
#endif
"For simpler wolfSSL TLS server examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 60 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 61 */
NULL,
},
#endif
@ -1127,6 +1209,12 @@ static void Usage(void)
#endif
printf("%s", msg[++msgId]); /* -7 */
printf("%s", msg[++msgId]); /* Examples repo link */
#ifdef HAVE_LIBOQS
printf("%s", msg[++msgId]); /* --oqs */
printf("%s", msg[++msgId]); /* --oqs options */
printf("%s", msg[++msgId]); /* more --oqs options */
printf("%s", msg[++msgId]); /* more --oqs options */
#endif
}
THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
@ -1154,6 +1242,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
{ "help", 0, 257 },
{ "ヘルプ", 0, 258 },
#if defined(HAVE_LIBOQS)
{ "oqs", 1, 259 },
#endif
{ 0, 0, 0 }
};
#endif
@ -1296,6 +1387,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
int useX25519 = 0;
int useX448 = 0;
int useLibOqs = 0;
char* oqsAlg = NULL;
int exitWithRet = 0;
int loadCertKeyIntoSSLObj = 0;
@ -1356,6 +1449,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
(void)mcastID;
(void)loadCertKeyIntoSSLObj;
(void)nonBlocking;
(void)oqsAlg;
(void)useLibOqs;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
@ -1872,6 +1967,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
break;
#endif
#ifdef HAVE_LIBOQS
case 259:
useLibOqs = 1;
onlyKeyShare = 2;
oqsAlg = myoptarg;
break;
#endif
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -1912,6 +2015,18 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
"file");
#endif
#ifdef HAVE_LIBOQS
if (useLibOqs) {
if (version == SERVER_DOWNGRADE_VERSION ||
version == EITHER_DOWNGRADE_VERSION) {
printf("WARNING: If a TLS 1.3 connection is not negotiated, you "
"will not be using a liboqs group.\n");
} else if (version != 4) {
err_sys("can only use liboqs groups with TLS 1.3");
}
}
#endif
switch (version) {
#ifndef NO_OLD_TLS
#ifdef WOLFSSL_ALLOW_SSLV3
@ -2604,7 +2719,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
if (version >= 4) {
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448);
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, useLibOqs,
oqsAlg);
}
#endif

View File

@ -2527,6 +2527,22 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_FFDHE_4096:
case WOLFSSL_FFDHE_6144:
case WOLFSSL_FFDHE_8192:
#ifdef HAVE_LIBOQS
case WOLFSSL_KYBER512:
case WOLFSSL_KYBER768:
case WOLFSSL_KYBER1024:
case WOLFSSL_NTRU_HPS2048509:
case WOLFSSL_NTRU_HPS2048677:
case WOLFSSL_NTRU_HPS4096821:
case WOLFSSL_NTRU_HRSS701:
case WOLFSSL_LIGHTSABER:
case WOLFSSL_SABER:
case WOLFSSL_FIRESABER:
case WOLFSSL_KYBER90S512:
case WOLFSSL_KYBER90S768:
case WOLFSSL_KYBER90S1024:
#endif
return 1;
default:
@ -22792,7 +22808,6 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
return id;
}
byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
byte* dst, int* dstLen)
{

371
src/tls.c
View File

@ -50,6 +50,9 @@
#include "libntruencrypt/ntru_crypto.h"
#include <wolfssl/wolfcrypt/random.h>
#endif
#ifdef HAVE_LIBOQS
#include <oqs/kem.h>
#endif
#ifdef HAVE_QSH
static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
@ -3768,10 +3771,10 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
#ifdef HAVE_SUPPORTED_CURVES
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
&& !defined(HAVE_FFDHE)
#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
Use --enable-ecc in the configure script or define HAVE_ECC. \
Alternatively use FFDHE for DH ciphersuites.
&& !defined(HAVE_FFDHE) && !defined(HAVE_LIBOQS)
#error Elliptic Curves Extension requires Elliptic Curve Cryptography or liboqs groups. \
Use --enable-ecc and/or --enable-liboqs in the configure script or \
define HAVE_ECC. Alternatively use FFDHE for DH ciphersuites.
#endif
static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
@ -7130,6 +7133,94 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
return ret;
}
#ifdef HAVE_LIBOQS
/* Transform a group ID into an OQS Algorithm name as a string. */
static const char* OQS_ID2name(int id)
{
switch (id) {
case WOLFSSL_KYBER512: return OQS_KEM_alg_kyber_512;
case WOLFSSL_KYBER768: return OQS_KEM_alg_kyber_768;
case WOLFSSL_KYBER1024: return OQS_KEM_alg_kyber_1024;
case WOLFSSL_NTRU_HPS2048509: return OQS_KEM_alg_ntru_hps2048509;
case WOLFSSL_NTRU_HPS2048677: return OQS_KEM_alg_ntru_hps2048677;
case WOLFSSL_NTRU_HPS4096821: return OQS_KEM_alg_ntru_hps4096821;
case WOLFSSL_NTRU_HRSS701: return OQS_KEM_alg_ntru_hrss701;
case WOLFSSL_LIGHTSABER: return OQS_KEM_alg_saber_lightsaber;
case WOLFSSL_SABER: return OQS_KEM_alg_saber_saber;
case WOLFSSL_FIRESABER: return OQS_KEM_alg_saber_firesaber;
case WOLFSSL_KYBER90S512: return OQS_KEM_alg_kyber_512_90s;
case WOLFSSL_KYBER90S768: return OQS_KEM_alg_kyber_768_90s;
case WOLFSSL_KYBER90S1024: return OQS_KEM_alg_kyber_1024_90s;
default: break;
}
return NULL;
}
/* Create a key share entry using liboqs parameters group.
* Generates a key pair.
*
* ssl The SSL/TLS object.
* kse The key share entry object.
* returns 0 on success, otherwise failure.
*/
static int TLSX_KeyShare_GenOqsKey(WOLFSSL *ssl, KeyShareEntry* kse)
{
int ret = -1;
const char* algName = NULL;
OQS_KEM* kem = NULL;
byte* pubKey = NULL;
byte* privKey = NULL;
algName = OQS_ID2name(kse->group);
if (algName == NULL) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
return BAD_FUNC_ARG;
}
kem = OQS_KEM_new(algName);
if (kem == NULL) {
WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support"
"was enabled in liboqs.");
return BAD_FUNC_ARG;
}
pubKey = (byte*)XMALLOC(kem->length_public_key, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
privKey = (byte*)XMALLOC(kem->length_secret_key, ssl->heap,
DYNAMIC_TYPE_PRIVATE_KEY);
if (pubKey == NULL || privKey == NULL) {
WOLFSSL_MSG("memory allocation failure");
ret = MEMORY_ERROR;
}
else if (OQS_KEM_keypair(kem, pubKey, privKey) == OQS_SUCCESS) {
kse->pubKey = pubKey;
kse->pubKeyLen = (word32) kem->length_public_key;
pubKey = NULL;
kse->key = privKey;
kse->keyLen = (word32) kem->length_secret_key;
privKey = NULL;
ret = 0;
}
else {
WOLFSSL_MSG("liboqs keygen failure");
ret = BAD_FUNC_ARG;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Public liboqs Key");
WOLFSSL_BUFFER(pubKey, kem->length_public_key);
#endif
OQS_KEM_free(kem);
if (pubKey != NULL)
XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (privKey != NULL)
XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
return ret;
}
#endif
/* Generate a secret/key using the key share entry.
*
* ssl The SSL/TLS object.
@ -7145,6 +7236,10 @@ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
ret = TLSX_KeyShare_GenX25519Key(ssl, kse);
else if (kse->group == WOLFSSL_ECC_X448)
ret = TLSX_KeyShare_GenX448Key(ssl, kse);
#ifdef HAVE_LIBOQS
else if (kse->group >= WOLFSSL_OQS_MIN && kse->group <= WOLFSSL_OQS_MAX)
ret = TLSX_KeyShare_GenOqsKey(ssl, kse);
#endif
else
ret = TLSX_KeyShare_GenEccKey(ssl, kse);
#ifdef WOLFSSL_ASYNC_CRYPT
@ -7179,6 +7274,13 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
wc_curve448_free((curve448_key*)current->key);
#endif
}
#ifdef HAVE_LIBOQS
else if (current->group >= WOLFSSL_OQS_MIN &&
current->group <= WOLFSSL_OQS_MAX &&
current->key != NULL) {
ForceZero((byte*)current->key, current->keyLen);
}
#endif
else {
#ifdef HAVE_ECC
wc_ecc_free((ecc_key*)current->key);
@ -7680,6 +7782,73 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
return ret;
}
#ifdef HAVE_LIBOQS
/* Process the liboqs key share extension on the client side.
*
* ssl The SSL/TLS object.
* keyShareEntry The key share entry object to use to calculate shared secret.
* returns 0 on success and other values indicate failure.
*/
static int TLSX_KeyShare_ProcessOqs(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
{
int ret = -1;
const char* algName = NULL;
OQS_KEM* kem = NULL;
byte* sharedSecret = NULL;
if (ssl->options.side == WOLFSSL_SERVER_END) {
if (keyShareEntry->ke == NULL) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
return BAD_FUNC_ARG;
}
/* If I'm the server, the shared secret has already been generated and
* is in keyShareEntry->ke; transfer ownership of the buffer.
*/
if (ssl->arrays->preMasterSecret != NULL)
XFREE(ssl->arrays->preMasterSecret, ssl->heap,
DYNAMIC_TYPE_SECRET);
ssl->arrays->preMasterSecret = keyShareEntry->ke;
ssl->arrays->preMasterSz = keyShareEntry->keLen;
keyShareEntry->ke = NULL;
keyShareEntry->keLen = 0;
return 0;
}
algName = OQS_ID2name(keyShareEntry->group);
if (algName == NULL) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
return BAD_FUNC_ARG;
}
kem = OQS_KEM_new(algName);
if (kem == NULL) {
WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support"
"was enabled in liboqs.");
return MEMORY_E;
}
sharedSecret = (byte*)XMALLOC(kem->length_shared_secret,
ssl->heap, DYNAMIC_TYPE_TLSX);
if (sharedSecret == NULL) {
OQS_KEM_free(kem);
return MEMORY_E;
}
if (OQS_KEM_decaps(kem, sharedSecret, keyShareEntry->ke,
keyShareEntry->key) == OQS_SUCCESS) {
ssl->arrays->preMasterSecret = sharedSecret;
ssl->arrays->preMasterSz = (word32) kem->length_shared_secret;
ret = 0;
} else {
XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
}
OQS_KEM_free(kem);
return ret;
}
#endif
/* Process the key share extension on the client side.
*
* ssl The SSL/TLS object.
@ -7700,6 +7869,11 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
else if (keyShareEntry->group == WOLFSSL_ECC_X448)
ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
#ifdef HAVE_LIBOQS
else if (keyShareEntry->group >= WOLFSSL_OQS_MIN &&
keyShareEntry->group <= WOLFSSL_OQS_MAX)
ret = TLSX_KeyShare_ProcessOqs(ssl, keyShareEntry);
#endif
else
ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
@ -7986,6 +8160,80 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
return 0;
}
#ifdef HAVE_LIBOQS
static int server_generate_oqs_ciphertext(WOLFSSL* ssl,
KeyShareEntry* keyShareEntry,
byte* data, word16 len) {
/* if this is a kem group and I am the server, the data is the
* client's public key. I need to generate the public information
* (AKA ciphertext) and shared secret here. Note the "public
* information" is equivalent to a the public key in key exchange
* parlance. That's why it is being assigned to pubKey.
*/
const char* algName = NULL;
OQS_KEM* kem = NULL;
byte* sharedSecret = NULL;
byte* ciphertext = NULL;
int ret = 0;
algName = OQS_ID2name(keyShareEntry->group);
if (algName == NULL) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
return BAD_FUNC_ARG;
}
kem = OQS_KEM_new(algName);
if (kem == NULL) {
WOLFSSL_MSG("Error creating OQS KEM, ensure algorithm support "
"was enabled in liboqs.");
return MEMORY_E;
}
if (len != kem->length_public_key) {
OQS_KEM_free(kem);
WOLFSSL_MSG("Invalid public key.");
ret = BAD_FUNC_ARG;
}
sharedSecret = (byte*)XMALLOC(kem->length_shared_secret,
ssl->heap, DYNAMIC_TYPE_TLSX);
ciphertext = (byte*)XMALLOC(kem->length_ciphertext,
ssl->heap, DYNAMIC_TYPE_TLSX);
if (sharedSecret == NULL || ciphertext == NULL) {
ret = MEMORY_E;
}
if (ret == 0 &&
OQS_KEM_encaps(kem, ciphertext, sharedSecret, data)
!= OQS_SUCCESS) {
WOLFSSL_MSG("Encapsulation failure.");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
if (keyShareEntry->ke != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
keyShareEntry->pubKey = ciphertext;
keyShareEntry->pubKeyLen = (word32) kem->length_ciphertext;
ciphertext = NULL;
keyShareEntry->ke = sharedSecret;
keyShareEntry->keLen = (word32) kem->length_shared_secret;
sharedSecret = NULL;
}
OQS_KEM_free(kem);
if (sharedSecret == NULL)
XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
if (ciphertext == NULL)
XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
return ret;
}
#endif
/* Use the data to create a new key share object in the extensions.
*
* ssl The SSL/TLS object.
@ -8033,11 +8281,24 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
}
if (data != NULL) {
if (keyShareEntry->ke != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
#ifdef HAVE_LIBOQS
if (group >= WOLFSSL_OQS_MIN &&
group <= WOLFSSL_OQS_MAX &&
ssl->options.side == WOLFSSL_SERVER_END) {
ret = server_generate_oqs_ciphertext(ssl, keyShareEntry, data,
len);
if (ret != 0)
return ret;
}
else
#endif
{
if (keyShareEntry->ke != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
keyShareEntry->ke = data;
keyShareEntry->keLen = len;
}
keyShareEntry->ke = data;
keyShareEntry->keLen = len;
}
else {
/* Generate a key pair. */
@ -8129,6 +8390,22 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
case WOLFSSL_ECC_SECP521R1:
break;
#endif /* !NO_ECC_SECP */
#endif
#ifdef HAVE_LIBOQS
case WOLFSSL_KYBER512:
case WOLFSSL_KYBER768:
case WOLFSSL_KYBER1024:
case WOLFSSL_NTRU_HPS2048509:
case WOLFSSL_NTRU_HPS2048677:
case WOLFSSL_NTRU_HPS4096821:
case WOLFSSL_NTRU_HRSS701:
case WOLFSSL_LIGHTSABER:
case WOLFSSL_SABER:
case WOLFSSL_FIRESABER:
case WOLFSSL_KYBER90S512:
case WOLFSSL_KYBER90S768:
case WOLFSSL_KYBER90S1024:
break;
#endif
default:
return 0;
@ -8195,6 +8472,22 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
#ifdef HAVE_FFDHE_8192
ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_8192;
#endif
#ifdef HAVE_LIBOQS
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER512;
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER768;
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER1024;
ssl->group[ssl->numGroups++] = WOLFSSL_NTRU_HPS2048509;
ssl->group[ssl->numGroups++] = WOLFSSL_NTRU_HPS2048677;
ssl->group[ssl->numGroups++] = WOLFSSL_NTRU_HPS4096821;
ssl->group[ssl->numGroups++] = WOLFSSL_NTRU_HRSS701;
ssl->group[ssl->numGroups++] = WOLFSSL_LIGHTSABER;
ssl->group[ssl->numGroups++] = WOLFSSL_SABER;
ssl->group[ssl->numGroups++] = WOLFSSL_FIRESABER;
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER90S512;
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER90S768;
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER90S1024;
#endif
}
for (i = 0; i < ssl->numGroups; i++)
@ -8320,7 +8613,11 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
if ((clientKSE->group & NAMED_DH_MASK) == 0) {
/* Check max value supported. */
if (clientKSE->group > WOLFSSL_ECC_MAX) {
continue;
#ifdef HAVE_LIBOQS
if (clientKSE->group < WOLFSSL_OQS_MIN ||
clientKSE->group > WOLFSSL_OQS_MAX )
#endif
continue;
}
#ifdef OPENSSL_EXTRA
/* Check if server supports group. */
@ -8349,13 +8646,30 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
}
list = NULL;
/* Generate a new key pair. */
/* Generate a new key pair except in the case of OQS KEM because we
* are going to encapsulate and that does not require us to generate a
* key pair.
*/
ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE);
if (ret != 0)
return ret;
if (clientKSE->key == NULL) {
ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
#ifdef HAVE_LIBOQS
if (clientKSE->group >= WOLFSSL_OQS_MIN &&
clientKSE->group <= WOLFSSL_OQS_MAX ) {
/* Going to need the public key (AKA ciphertext). */
serverKSE->pubKey = clientKSE->pubKey;
clientKSE->pubKey = NULL;
serverKSE->pubKeyLen = clientKSE->pubKeyLen;
clientKSE->pubKeyLen = 0;
}
else
#endif
{
ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
}
/* for async do setup of serverKSE below, but return WC_PENDING_E */
if (ret != 0
#ifdef WOLFSSL_ASYNC_CRYPT
@ -10203,6 +10517,41 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
#endif
#endif
#ifdef HAVE_LIBOQS
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER512, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER768, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER1024, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_NTRU_HPS2048509,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_NTRU_HPS2048677,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_NTRU_HPS4096821,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_NTRU_HRSS701,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_LIGHTSABER, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SABER, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FIRESABER, ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER90S512,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER90S768,
ssl->heap);
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER90S1024,
ssl->heap);
#endif /* HAVE_LIBOQS */
(void)ssl;
(void)extensions;

View File

@ -8667,6 +8667,19 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
}
#endif
#ifdef HAVE_LIBOQS
if (group >= WOLFSSL_OQS_MIN &&
group <= WOLFSSL_OQS_MAX &&
ssl->options.side == WOLFSSL_SERVER_END) {
/* If I am the server of a KEM connection, do not do keygen because I'm
* going to encapsulate with the client's public key. Note that I might
* be the client and ssl->option.side has not been properly set yet. In
* that case the KeyGen operation will be deferred to connection time.
*/
return WOLFSSL_SUCCESS;
}
#endif
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
if (ret != 0)
return ret;

View File

@ -24,7 +24,6 @@
#ifndef WOLFSSL_INT_H
#define WOLFSSL_INT_H
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/ssl.h>
#ifdef HAVE_CRL

View File

@ -775,7 +775,11 @@ enum SNICbReturn {
/* Maximum master key length (SECRET_LEN) */
#define WOLFSSL_MAX_MASTER_KEY_LENGTH 48
/* Maximum number of groups that can be set */
#ifdef HAVE_LIBOQS
#define WOLFSSL_MAX_GROUP_COUNT 23
#else
#define WOLFSSL_MAX_GROUP_COUNT 10
#endif
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
enum Tls13Secret {
@ -3493,6 +3497,27 @@ enum {
WOLFSSL_FFDHE_4096 = 258,
WOLFSSL_FFDHE_6144 = 259,
WOLFSSL_FFDHE_8192 = 260,
#ifdef HAVE_LIBOQS
/* These group numbers were taken from liboqs' openssl fork, see:
https://github.com/open-quantum-safe/openssl/blob/OQS-OpenSSL_1_1_1-stable/
oqs-template/oqs-kem-info.md */
WOLFSSL_OQS_MIN = 532,
WOLFSSL_NTRU_HPS2048509 = 532,
WOLFSSL_NTRU_HPS2048677 = 533,
WOLFSSL_NTRU_HPS4096821 = 534,
WOLFSSL_NTRU_HRSS701 = 535,
WOLFSSL_LIGHTSABER = 536,
WOLFSSL_SABER = 537,
WOLFSSL_FIRESABER = 538,
WOLFSSL_KYBER512 = 570,
WOLFSSL_KYBER768 = 572,
WOLFSSL_KYBER1024 = 573,
WOLFSSL_KYBER90S512 = 574,
WOLFSSL_KYBER90S768 = 575,
WOLFSSL_KYBER90S1024 = 576,
WOLFSSL_OQS_MAX = 576,
#endif
};
enum {