mirror of https://github.com/wolfSSL/wolfssl
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:
commit
c7645a42a7
47
INSTALL
47
INSTALL
|
@ -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.
|
||||
|
|
53
configure.ac
53
configure.ac
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
17
src/ssl.c
17
src/ssl.c
|
@ -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
371
src/tls.c
|
@ -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;
|
||||
|
||||
|
|
13
src/tls13.c
13
src/tls13.c
|
@ -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;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#ifndef WOLFSSL_INT_H
|
||||
#define WOLFSSL_INT_H
|
||||
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#ifdef HAVE_CRL
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue