Merge pull request #5569 from SparkiDev/kyber

Kyber: Add option to build Kyber API
This commit is contained in:
JacobBarthelmeh
2022-09-16 14:56:02 -06:00
committed by GitHub
23 changed files with 6128 additions and 317 deletions

View File

@@ -963,6 +963,134 @@ then
fi 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="$AM_CFLAGS -DOPENSSL_EXTRA"
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBOQS -DHAVE_TLS_EXTENSIONS"
ENABLED_LIBOQS="yes"
]
)
# KYBER
# Used:
# - SHA3, Shake128 and Shake256, or
# - SHA256, SHA512, AES-CTR
AC_ARG_ENABLE([kyber],
[AS_HELP_STRING([--enable-kyber],[Enable KYBER (default: disabled)])],
[ ENABLED_KYBER=$enableval ],
[ ENABLED_KYBER=no ]
)
ENABLED_WC_KYBER=no
for v in `echo $ENABLED_KYBER | tr "," " "`
do
case $v in
yes | all)
ENABLED_KYBER512=yes
ENABLED_KYBER768=yes
ENABLED_KYBER1024=yes
;;
no)
;;
wolfssl)
ENABLED_WC_KYBER=yes
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_KYBER"
;;
90s)
ENABLED_KYBER_90S=yes
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KYBER_90S"
;;
small)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KYBER_SMALL"
;;
512)
ENABLED_KYBER512=yes
;;
768)
ENABLED_KYBER768=yes
;;
1024)
ENABLED_KYBER1024=yes
;;
*)
AC_MSG_ERROR([Invalid choice for KYBER []: $ENABLED_KYBER.])
break;;
esac
done
if test "$ENABLED_KYBER" != "no"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_KYBER"
if test "$ENABLED_WC_KYBER" = "yes"
then
if test "$ENABLED_KYBER512" = ""; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER512"
fi
if test "$ENABLED_KYBER768" = ""; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER768"
fi
if test "$ENABLED_KYBER1024" = ""; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER1024"
fi
if test "$ENABLED_KYBER_90S" != "yes"; then
test "$enable_sha3" = "" && enable_sha3=yes
test "$enable_shake128" = "" && enable_shake128=yes
test "$enable_shake256" = "" && enable_shake256=yes
else
test "$enable_sha256" = "" && enable_sha256=yes
test "$enable_sha512" = "" && enable_sha512=yes
test "$enable_aesctr" = "" && enable_aesctr=yes
fi
else
# Default is to use liboqs. Make sure its enabled.
if test "$ENABLED_LIBOQS" = "no"; then
AC_MSG_ERROR([The default implementation for kyber is liboqs.
Please use --with-liboqs.])
fi
fi
fi
# SINGLE THREADED # SINGLE THREADED
AC_ARG_ENABLE([singlethreaded], AC_ARG_ENABLE([singlethreaded],
[AS_HELP_STRING([--enable-singlethreaded],[Enable wolfSSL single threaded (default: disabled)])], [AS_HELP_STRING([--enable-singlethreaded],[Enable wolfSSL single threaded (default: disabled)])],
@@ -3068,7 +3196,6 @@ then
fi fi
# FP ECC, Fixed Point cache ECC # FP ECC, Fixed Point cache ECC
AC_ARG_ENABLE([fpecc], AC_ARG_ENABLE([fpecc],
[AS_HELP_STRING([--enable-fpecc],[Enable Fixed Point cache ECC (default: disabled)])], [AS_HELP_STRING([--enable-fpecc],[Enable Fixed Point cache ECC (default: disabled)])],
@@ -4533,52 +4660,6 @@ then
AC_MSG_ERROR([cannot enable user crypto and fips, user crypto posibility of using code in fips boundary.]) AC_MSG_ERROR([cannot enable user crypto and fips, user crypto posibility of using code in fips boundary.])
fi 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="$AM_CFLAGS -DOPENSSL_EXTRA"
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBOQS -DHAVE_TLS_EXTENSIONS"
ENABLED_LIBOQS="yes"
]
)
# Whitewood netRandom client library # Whitewood netRandom client library
ENABLED_WNR="no" ENABLED_WNR="no"
trywnrdir="" trywnrdir=""
@@ -8042,6 +8123,7 @@ AM_CONDITIONAL([BUILD_FE448], [test "x$ENABLED_FE448" = "xyes" || test "x$ENABLE
AM_CONDITIONAL([BUILD_GE448], [test "x$ENABLED_GE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_GE448], [test "x$ENABLED_GE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_CURVE448],[test "x$ENABLED_CURVE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CURVE448],[test "x$ENABLED_CURVE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_CURVE448_SMALL],[test "x$ENABLED_CURVE448_SMALL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CURVE448_SMALL],[test "x$ENABLED_CURVE448_SMALL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_WC_KYBER],[test "x$ENABLED_WC_KYBER" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_ECCSI],[test "x$ENABLED_ECCSI" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_ECCSI],[test "x$ENABLED_ECCSI" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_SAKKE],[test "x$ENABLED_SAKKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SAKKE],[test "x$ENABLED_SAKKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_MEMORY],[test "x$ENABLED_MEMORY" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_MEMORY],[test "x$ENABLED_MEMORY" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
@@ -8443,14 +8525,16 @@ echo " * DH Default Parameters: $ENABLED_DHDEFAULTPARAMS"
echo " * ECC: $ENABLED_ECC" echo " * ECC: $ENABLED_ECC"
echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES" echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES"
echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ" echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ"
echo " * FPECC: $ENABLED_FPECC"
echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT"
echo " * CURVE25519: $ENABLED_CURVE25519" echo " * CURVE25519: $ENABLED_CURVE25519"
echo " * ED25519: $ENABLED_ED25519" echo " * ED25519: $ENABLED_ED25519"
echo " * ED25519 streaming: $ENABLED_ED25519_STREAM" echo " * ED25519 streaming: $ENABLED_ED25519_STREAM"
echo " * CURVE448: $ENABLED_CURVE448" echo " * CURVE448: $ENABLED_CURVE448"
echo " * ED448: $ENABLED_ED448" echo " * ED448: $ENABLED_ED448"
echo " * ED448 streaming: $ENABLED_ED448_STREAM" echo " * ED448 streaming: $ENABLED_ED448_STREAM"
echo " * FPECC: $ENABLED_FPECC" echo " * KYBER: $ENABLED_KYBER"
echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" echo " * KYBER wolfSSL impl: $ENABLED_WC_KYBER"
echo " * ECCSI $ENABLED_ECCSI" echo " * ECCSI $ENABLED_ECCSI"
echo " * SAKKE $ENABLED_SAKKE" echo " * SAKKE $ENABLED_SAKKE"
echo " * ASN: $ENABLED_ASN" echo " * ASN: $ENABLED_ASN"

View File

@@ -104,6 +104,14 @@ if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif endif
if BUILD_WC_KYBER
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_poly.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_asm.S
endif
endif
if BUILD_AES if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
endif endif
@@ -185,6 +193,14 @@ if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif endif
if BUILD_WC_KYBER
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_poly.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_asm.S
endif
endif
if BUILD_AES if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM if BUILD_ARMASM
@@ -587,6 +603,14 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/sakke.c
endif endif
endif endif
if BUILD_WC_KYBER
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_poly.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/wc_kyber_asm.S
endif
endif
if BUILD_CURVE25519 if BUILD_CURVE25519
src_libwolfssl_la_SOURCES += wolfcrypt/src/curve25519.c src_libwolfssl_la_SOURCES += wolfcrypt/src/curve25519.c
endif endif
@@ -663,6 +687,7 @@ if BUILD_LIBOQS
src_libwolfssl_la_SOURCES += wolfcrypt/src/falcon.c src_libwolfssl_la_SOURCES += wolfcrypt/src/falcon.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/dilithium.c src_libwolfssl_la_SOURCES += wolfcrypt/src/dilithium.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/sphincs.c src_libwolfssl_la_SOURCES += wolfcrypt/src/sphincs.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/ext_kyber.c
endif endif
if BUILD_LIBZ if BUILD_LIBZ

View File

@@ -7629,7 +7629,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
} }
#endif #endif
#endif #endif
#ifdef HAVE_PQC #if defined(HAVE_PQC) && defined(HAVE_FALCON)
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey); FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0; ssl->peerFalconKeyPresent = 0;
#endif #endif
@@ -7864,7 +7864,7 @@ void FreeHandshakeResources(WOLFSSL* ssl)
FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key); FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0; ssl->peerEd448KeyPresent = 0;
#endif /* HAVE_ED448 */ #endif /* HAVE_ED448 */
#ifdef HAVE_PQC #if defined(HAVE_PQC) && defined(HAVE_FALCON)
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey); FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0; ssl->peerFalconKeyPresent = 0;
#endif /* HAVE_PQC */ #endif /* HAVE_PQC */

View File

@@ -225,6 +225,7 @@ const WOLF_EC_NIST_NAME kNistCurves[] = {
{XSTR_SIZEOF("KYBER_LEVEL1"), "KYBER_LEVEL1", WOLFSSL_KYBER_LEVEL1}, {XSTR_SIZEOF("KYBER_LEVEL1"), "KYBER_LEVEL1", WOLFSSL_KYBER_LEVEL1},
{XSTR_SIZEOF("KYBER_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3}, {XSTR_SIZEOF("KYBER_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3},
{XSTR_SIZEOF("KYBER_LEVEL5"), "KYBER_LEVEL5", WOLFSSL_KYBER_LEVEL5}, {XSTR_SIZEOF("KYBER_LEVEL5"), "KYBER_LEVEL5", WOLFSSL_KYBER_LEVEL5},
#ifdef HAVE_LIBOQS
{XSTR_SIZEOF("NTRU_HPS_LEVEL1"), "NTRU_HPS_LEVEL1", WOLFSSL_NTRU_HPS_LEVEL1}, {XSTR_SIZEOF("NTRU_HPS_LEVEL1"), "NTRU_HPS_LEVEL1", WOLFSSL_NTRU_HPS_LEVEL1},
{XSTR_SIZEOF("NTRU_HPS_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3}, {XSTR_SIZEOF("NTRU_HPS_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3},
{XSTR_SIZEOF("NTRU_HPS_LEVEL5"), "NTRU_HPS_LEVEL5", WOLFSSL_NTRU_HPS_LEVEL5}, {XSTR_SIZEOF("NTRU_HPS_LEVEL5"), "NTRU_HPS_LEVEL5", WOLFSSL_NTRU_HPS_LEVEL5},
@@ -248,6 +249,7 @@ const WOLF_EC_NIST_NAME kNistCurves[] = {
{XSTR_SIZEOF("P256_KYBER_90S_LEVEL1"), "P256_KYBER_90S_LEVEL1", WOLFSSL_P256_KYBER_90S_LEVEL1}, {XSTR_SIZEOF("P256_KYBER_90S_LEVEL1"), "P256_KYBER_90S_LEVEL1", WOLFSSL_P256_KYBER_90S_LEVEL1},
{XSTR_SIZEOF("P384_KYBER_90S_LEVEL3"), "P384_KYBER_90S_LEVEL3", WOLFSSL_P384_KYBER_90S_LEVEL3}, {XSTR_SIZEOF("P384_KYBER_90S_LEVEL3"), "P384_KYBER_90S_LEVEL3", WOLFSSL_P384_KYBER_90S_LEVEL3},
{XSTR_SIZEOF("P521_KYBER_90S_LEVEL5"), "P521_KYBER_90S_LEVEL5", WOLFSSL_P521_KYBER_90S_LEVEL5}, {XSTR_SIZEOF("P521_KYBER_90S_LEVEL5"), "P521_KYBER_90S_LEVEL5", WOLFSSL_P521_KYBER_90S_LEVEL5},
#endif
#endif #endif
{0, NULL, 0}, {0, NULL, 0},
}; };
@@ -2879,6 +2881,7 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_KYBER_LEVEL1:
case WOLFSSL_KYBER_LEVEL3: case WOLFSSL_KYBER_LEVEL3:
case WOLFSSL_KYBER_LEVEL5: case WOLFSSL_KYBER_LEVEL5:
#ifdef HAVE_LIBOQS
case WOLFSSL_NTRU_HPS_LEVEL1: case WOLFSSL_NTRU_HPS_LEVEL1:
case WOLFSSL_NTRU_HPS_LEVEL3: case WOLFSSL_NTRU_HPS_LEVEL3:
case WOLFSSL_NTRU_HPS_LEVEL5: case WOLFSSL_NTRU_HPS_LEVEL5:
@@ -2902,6 +2905,7 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_P256_KYBER_90S_LEVEL1: case WOLFSSL_P256_KYBER_90S_LEVEL1:
case WOLFSSL_P384_KYBER_90S_LEVEL3: case WOLFSSL_P384_KYBER_90S_LEVEL3:
case WOLFSSL_P521_KYBER_90S_LEVEL5: case WOLFSSL_P521_KYBER_90S_LEVEL5:
#endif
#endif #endif
return 1; return 1;
@@ -6689,7 +6693,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
} }
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
defined(HAVE_PQC) || !defined(NO_RSA) (defined(HAVE_PQC) && defined(HAVE_LIBOQS)) || !defined(NO_RSA)
if (ssl) { if (ssl) {
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
(defined(HAVE_CURVE448) && defined(HAVE_ED448)) (defined(HAVE_CURVE448) && defined(HAVE_ED448))
@@ -20754,6 +20758,19 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
#elif defined(HAVE_PQM4) #elif defined(HAVE_PQM4)
case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1"; return "KYBER_LEVEL1";
#elif defined(WOLFSSL_WC_KYBER)
#ifdef WOLFSSL_KYBER512
case WOLFSSL_KYBER_LEVEL1:
return "KYBER_LEVEL1";
#endif
#ifdef WOLFSSL_KYBER768
case WOLFSSL_KYBER_LEVEL3:
return "KYBER_LEVEL3";
#endif
#ifdef WOLFSSL_KYBER1024
case WOLFSSL_KYBER_LEVEL5:
return "KYBER_LEVEL5";
#endif
#endif #endif
} }
} }

543
src/tls.c
View File

@@ -49,14 +49,21 @@
#include <wolfssl/wolfcrypt/curve448.h> #include <wolfssl/wolfcrypt/curve448.h>
#endif #endif
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_HAVE_KYBER
#include <wolfssl/wolfcrypt/kyber.h>
#ifdef WOLFSSL_WC_KYBER
#include <wolfssl/wolfcrypt/wc_kyber.h>
#elif defined(HAVE_LIBOQS)
#include <oqs/kem.h> #include <oqs/kem.h>
#include <wolfssl/wolfcrypt/ext_kyber.h>
#elif defined(HAVE_PQM4) #elif defined(HAVE_PQM4)
#include "api_kyber.h" #include "api_kyber.h"
#define PQM4_PUBLIC_KEY_LENGTH CRYPTO_PUBLICKEYBYTES #define PQM4_PUBLIC_KEY_LENGTH CRYPTO_PUBLICKEYBYTES
#define PQM4_PRIVATE_KEY_LENGTH CRYPTO_SECRETKEYBYTES #define PQM4_PRIVATE_KEY_LENGTH CRYPTO_SECRETKEYBYTES
#define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES #define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES
#define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES #define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES
#include <wolfssl/wolfcrypt/ext_kyber.h>
#endif
#endif #endif
#endif #endif
@@ -7055,7 +7062,35 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
} }
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_WC_KYBER
static int kyber_id2type(int id, int *type)
{
int ret = 0;
switch (id) {
#ifdef WOLFSSL_KYBER512
case WOLFSSL_KYBER_LEVEL1:
*type = KYBER512;
break;
#endif
#ifdef WOLFSSL_KYBER768
case WOLFSSL_KYBER_LEVEL3:
*type = KYBER768;
break;
#endif
#ifdef WOLFSSL_KYBER1024
case WOLFSSL_KYBER_LEVEL5:
*type = KYBER1024;
break;
#endif
default:
ret = NOT_COMPILED_IN;
break;
}
return ret;
}
#elif defined(HAVE_LIBOQS)
/* Transform a group ID into an OQS Algorithm name as a string. */ /* Transform a group ID into an OQS Algorithm name as a string. */
static const char* OQS_ID2name(int id) static const char* OQS_ID2name(int id)
{ {
@@ -7152,7 +7187,120 @@ static void findEccPqc(int *ecc, int *pqc, int group)
* kse The key share entry object. * kse The key share entry object.
* returns 0 on success, otherwise failure. * returns 0 on success, otherwise failure.
*/ */
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_WC_KYBER
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
{
int ret = 0;
int type = 0;
KyberKey kem[1];
byte* pubKey = NULL;
byte* privKey = NULL;
KeyShareEntry *ecc_kse = NULL;
int oqs_group = 0;
int ecc_group = 0;
word32 privSz = 0;
word32 pubSz = 0;
findEccPqc(&ecc_group, &oqs_group, kse->group);
ret = kyber_id2type(oqs_group, &type);
if (ret == NOT_COMPILED_IN) {
WOLFSSL_MSG("Invalid Kyber algorithm specified.");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
if (ret != 0) {
WOLFSSL_MSG("Failed to intialize Kyber Key.");
}
}
if (ret == 0) {
ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
DYNAMIC_TYPE_TLSX);
if (ecc_kse == NULL) {
WOLFSSL_MSG("ecc_kse memory allocation failure");
ret = MEMORY_ERROR;
}
}
if (ret == 0) {
XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
}
if (ret == 0) {
ret = wc_KyberKey_PublicKeySize(kem, &pubSz);
}
if (ret == 0 && ecc_group != 0) {
ecc_kse->group = ecc_group;
ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
/* If fail, no error message, TLSX_KeyShare_GenEccKey will do it. */
}
if (ret == 0) {
pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + pubSz, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
if (pubKey == NULL) {
WOLFSSL_MSG("pubkey memory allocation failure");
ret = MEMORY_ERROR;
}
}
if (ret == 0) {
privKey = (byte*)XMALLOC(privSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
if (privKey == NULL) {
WOLFSSL_MSG("privkey memory allocation failure");
ret = MEMORY_ERROR;
}
}
if (ret == 0) {
ret = wc_KyberKey_MakeKey(kem, ssl->rng);
if (ret != 0) {
WOLFSSL_MSG("lKyber keygen failure");
}
}
if (ret == 0) {
ret = wc_KyberKey_EncodePublicKey(kem, pubKey + ecc_kse->pubKeyLen,
pubSz);
}
if (ret == 0) {
ret = wc_KyberKey_EncodePrivateKey(kem, privKey, privSz);
}
if (ret == 0) {
XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
kse->pubKey = pubKey;
kse->pubKeyLen = ecc_kse->pubKeyLen + pubSz;
pubKey = NULL;
/* Note we are saving the OQS private key and ECC private key
* separately. That's because the ECC private key is not simply a
* buffer. Its is an ecc_key struct.
*/
kse->privKey = privKey;
privKey = NULL;
kse->key = ecc_kse->key;
ecc_kse->key = NULL;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Public Kyber Key");
WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
#endif
wc_KyberKey_Free(kem);
TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
if (pubKey != NULL)
XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (privKey != NULL)
XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
return ret;
}
#elif defined(HAVE_LIBOQS)
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
{ {
int ret = 0; int ret = 0;
@@ -7940,7 +8088,174 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
} }
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_WC_KYBER
/* Process the Kyber 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_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
{
int ret = 0;
int type;
KyberKey kem[1];
byte* sharedSecret = NULL;
word32 sharedSecretLen = 0;
int oqs_group = 0;
int ecc_group = 0;
ecc_key eccpubkey;
word32 outlen = 0;
word32 privSz = 0;
word32 ctSz = 0;
word32 ssSz = 0;
if (keyShareEntry->ke == NULL) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
return BAD_FUNC_ARG;
}
if (ssl->options.side == WOLFSSL_SERVER_END) {
/* I am the server, the shared secret has already been generated and
* is in keyShareEntry->ke; copy it to the pre-master secret
* pre-allocated buffer. */
if (keyShareEntry->keLen > ENCRYPT_LEN) {
WOLFSSL_MSG("shared secret is too long.");
return LENGTH_ERROR;
}
XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke,
keyShareEntry->keLen);
ssl->arrays->preMasterSz = keyShareEntry->keLen;
XFREE(keyShareEntry->ke, sl->heap, DYNAMIC_TYPE_SECRET)
keyShareEntry->ke = NULL;
keyShareEntry->keLen = 0;
return 0;
}
/* I am the client, the ciphertext is in keyShareEntry->ke */
findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
ret = kyber_id2type(oqs_group, &type);
if (ret != 0) {
WOLFSSL_MSG("Invalid OQS algorithm specified.");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
if (ret != 0) {
WOLFSSL_MSG("Error creating Kyber KEM");
}
}
if (ret == 0) {
ret = wc_KyberKey_SharedSecretSize(kem, &ssSz);
}
if (ret == 0) {
sharedSecretLen = ssSz;
switch (ecc_group) {
case WOLFSSL_ECC_SECP256R1:
sharedSecretLen += 32;
outlen = 32;
break;
case WOLFSSL_ECC_SECP384R1:
sharedSecretLen += 48;
outlen = 48;
break;
case WOLFSSL_ECC_SECP521R1:
sharedSecretLen += 66;
outlen = 66;
break;
default:
break;
}
ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
if (ret != 0) {
WOLFSSL_MSG("Memory allocation error.");
ret = MEMORY_E;
}
}
if (ret == 0) {
sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap,
DYNAMIC_TYPE_TLSX);
if (sharedSecret == NULL) {
WOLFSSL_MSG("Memory allocation error.");
ret = MEMORY_E;
}
}
if (ret == 0) {
ret = wc_KyberKey_CipherTextSize(kem, &ctSz);
}
if (ret == 0) {
ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
}
if (ret == 0) {
ret = wc_KyberKey_DecodePrivateKey(kem, keyShareEntry->privKey, privSz);
}
if (ret == 0) {
ret = wc_KyberKey_Decapsulate(kem, sharedSecret + outlen,
keyShareEntry->ke + keyShareEntry->keLen - ctSz, ctSz);
if (ret != 0) {
WOLFSSL_MSG("wc_KyberKey decapsulation failure.");
ret = BAD_FUNC_ARG;
}
}
if (ecc_group != 0) {
if (ret == 0) {
/* Point is validated by import function. */
ret = wc_ecc_import_x963(keyShareEntry->ke,
keyShareEntry->keLen - ctSz,
&eccpubkey);
if (ret != 0) {
WOLFSSL_MSG("ECC Public key import error.");
}
}
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
!defined(HAVE_SELFTEST)
if (ret == 0) {
ret = wc_ecc_set_rng(keyShareEntry->key, ssl->rng);
if (ret != 0) {
WOLFSSL_MSG("Failure to set the ECC private key RNG.");
}
}
#endif
if (ret == 0) {
PRIVATE_KEY_UNLOCK();
ret = wc_ecc_shared_secret(keyShareEntry->key, &eccpubkey,
sharedSecret, &outlen);
PRIVATE_KEY_LOCK();
if (outlen != sharedSecretLen - ssSz) {
WOLFSSL_MSG("ECC shared secret derivation error.");
ret = BAD_FUNC_ARG;
}
}
}
if ((ret == 0) && (sharedSecretLen > ENCRYPT_LEN)) {
WOLFSSL_MSG("shared secret is too long.");
ret = LENGTH_ERROR;
}
if (ret == 0) {
/* Copy the shared secret to the pre-master secret pre-allocated
* buffer. */
XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen);
ssl->arrays->preMasterSz = (word32) sharedSecretLen;
}
if (sharedSecret != NULL) {
XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET);
}
wc_ecc_free(&eccpubkey);
wc_KyberKey_Free(kem);
return ret;
}
#elif defined(HAVE_LIBOQS)
/* Process the liboqs key share extension on the client side. /* Process the liboqs key share extension on the client side.
* *
* ssl The SSL/TLS object. * ssl The SSL/TLS object.
@@ -8570,10 +8885,171 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
} }
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_WC_KYBER
static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
KeyShareEntry* keyShareEntry, byte* data, word16 len)
{
/* I am the server. The data parameter 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.
*/
int type;
KyberKey kem[1];
byte* sharedSecret = NULL;
byte* ciphertext = NULL;
int ret = 0;
int oqs_group = 0;
int ecc_group = 0;
KeyShareEntry *ecc_kse = NULL;
ecc_key eccpubkey;
word32 outlen = 0;
word32 pubSz = 0;
word32 ctSz = 0;
word32 ssSz = 0;
findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
ret = kyber_id2type(oqs_group, &type);
if (ret != 0) {
WOLFSSL_MSG("Invalid Kyber algorithm specified.");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
if (ret != 0) {
WOLFSSL_MSG("Could not do ECC public key initialization.");
ret = MEMORY_E;
}
}
if (ret == 0) {
ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
DYNAMIC_TYPE_TLSX);
if (ecc_kse == NULL) {
WOLFSSL_MSG("ecc_kse memory allocation failure");
ret = MEMORY_ERROR;
}
}
if (ret == 0) {
XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
}
if (ret == 0 && ecc_group != 0) {
ecc_kse->group = ecc_group;
ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
if (ret != 0) {
/* No message, TLSX_KeyShare_GenEccKey() will do it. */
return ret;
}
ret = 0;
}
if (ret == 0) {
ret = wc_KyberKey_Init(type, kem, ssl->heap, INVALID_DEVID);
if (ret == 0) {
WOLFSSL_MSG("Error creating Kyber KEM");
}
}
if (ret == 0) {
ret = wc_KyberKey_PublicKeySize(kem, &pubSz);
}
if (ret == 0) {
ret = wc_KyberKey_CipherTextSize(kem, &ctSz);
}
if (ret == 0) {
ret = wc_KyberKey_SharedSecretSize(kem, &ssSz);
}
if (ret == 0 && len != pubSz + ecc_kse->pubKeyLen) {
WOLFSSL_MSG("Invalid public key.");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen + ssSz, ssl->heap,
DYNAMIC_TYPE_TLSX);
ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + ctSz, ssl->heap,
DYNAMIC_TYPE_TLSX);
if (sharedSecret == NULL || ciphertext == NULL) {
WOLFSSL_MSG("Ciphertext/shared secret memory allocation failure.");
ret = MEMORY_E;
}
}
if (ecc_group != 0) {
if (ret == 0) {
/* Point is validated by import function. */
ret = wc_ecc_import_x963(data, len - pubSz, &eccpubkey);
if (ret != 0) {
WOLFSSL_MSG("Bad ECC public key.");
}
}
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
!defined(HAVE_SELFTEST)
if (ret == 0) {
ret = wc_ecc_set_rng(ecc_kse->key, ssl->rng);
}
#endif
if (ret == 0) {
outlen = ecc_kse->keyLen;
PRIVATE_KEY_UNLOCK();
ret = wc_ecc_shared_secret(ecc_kse->key, &eccpubkey,
sharedSecret,
&outlen);
PRIVATE_KEY_LOCK();
if (outlen != ecc_kse->keyLen) {
WOLFSSL_MSG("Data length mismatch.");
ret = BAD_FUNC_ARG;
}
}
}
if (ret == 0) {
ret = wc_KyberKey_DecodePublicKey(kem, data + ecc_kse->pubKeyLen,
pubSz);
}
if (ret == 0) {
ret = wc_KyberKey_Encapsulate(kem, ciphertext + ecc_kse->pubKeyLen,
sharedSecret + outlen, ssl->rng);
if (ret != 0) {
WOLFSSL_MSG("wc_KyberKey encapsulation failure.");
}
}
if (ret == 0) {
if (keyShareEntry->ke != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
keyShareEntry->ke = sharedSecret;
keyShareEntry->keLen = outlen + ssSz;
sharedSecret = NULL;
XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
keyShareEntry->pubKey = ciphertext;
keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen + ctSz);
ciphertext = NULL;
}
TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
if (sharedSecret != NULL)
XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_TLSX);
if (ciphertext != NULL)
XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
wc_ecc_free(&eccpubkey);
wc_KyberKey_Free(kem);
return ret;
}
#elif defined(HAVE_LIBOQS)
static int server_generate_pqc_ciphertext(WOLFSSL* ssl, static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
KeyShareEntry* keyShareEntry, KeyShareEntry* keyShareEntry,
byte* data, word16 len) { byte* data, word16 len)
{
/* I am the server. The data parameter is the client's public key. I need /* I am the server. The data parameter is the client's public key. I need
* to generate the public information (AKA ciphertext) and shared secret * to generate the public information (AKA ciphertext) and shared secret
* here. Note the "public information" is equivalent to a the public key in * here. Note the "public information" is equivalent to a the public key in
@@ -8723,7 +9199,8 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
#elif defined(HAVE_PQM4) #elif defined(HAVE_PQM4)
static int server_generate_pqc_ciphertext(WOLFSSL* ssl, static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
KeyShareEntry* keyShareEntry, KeyShareEntry* keyShareEntry,
byte* data, word16 len) { byte* data, word16 len)
{
/* I am the server. The data parameter is the client's public key. I need /* I am the server. The data parameter is the client's public key. I need
* to generate the public information (AKA ciphertext) and shared secret * to generate the public information (AKA ciphertext) and shared secret
* here. Note the "public information" is equivalent to a the public key in * here. Note the "public information" is equivalent to a the public key in
@@ -9061,7 +9538,18 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
#endif #endif
#endif #endif
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef HAVE_LIBOQS #ifdef WOLFSSL_WC_KYBER
#ifdef WOLFSSL_KYBER512
case WOLFSSL_KYBER_LEVEL1:
#endif
#ifdef WOLFSSL_KYBER768
case WOLFSSL_KYBER_LEVEL3:
#endif
#ifdef WOLFSSL_KYBER1024
case WOLFSSL_KYBER_LEVEL5:
#endif
break;
#elif defined(HAVE_LIBOQS)
case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_KYBER_LEVEL1:
case WOLFSSL_KYBER_LEVEL3: case WOLFSSL_KYBER_LEVEL3:
case WOLFSSL_KYBER_LEVEL5: case WOLFSSL_KYBER_LEVEL5:
@@ -9167,9 +9655,22 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
/* For the liboqs groups we need to do a runtime check because /* For the liboqs groups we need to do a runtime check because
* liboqs could be compiled to make an algorithm unavailable. * liboqs could be compiled to make an algorithm unavailable.
*/ */
#ifdef WOLFSSL_WC_KYBER
#ifdef WOLFSSL_KYBER512
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
#endif
#ifdef WOLFSSL_KYBER768
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3;
#endif
#ifdef WOLFSSL_KYBER1024
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL5;
#endif
#elif defined(HAVE_LIBOQS)
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1)) if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1; ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
#ifdef HAVE_LIBOQS
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3)) if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3; ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3;
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5)) if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5))
@@ -9220,6 +9721,9 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
ssl->group[ssl->numGroups++] = WOLFSSL_P384_KYBER_90S_LEVEL3; ssl->group[ssl->numGroups++] = WOLFSSL_P384_KYBER_90S_LEVEL3;
if (TLSX_KeyShare_IsSupported(WOLFSSL_P521_KYBER_90S_LEVEL5)) if (TLSX_KeyShare_IsSupported(WOLFSSL_P521_KYBER_90S_LEVEL5))
ssl->group[ssl->numGroups++] = WOLFSSL_P521_KYBER_90S_LEVEL5; ssl->group[ssl->numGroups++] = WOLFSSL_P521_KYBER_90S_LEVEL5;
#elif defined(HAVE_PQM4)
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL1))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
#endif /* HAVE_LIBOQS */ #endif /* HAVE_LIBOQS */
#endif /* HAVE_PQC */ #endif /* HAVE_PQC */
} }
@@ -11233,8 +11737,24 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
#endif #endif
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifdef WOLFSSL_WC_KYBER
#ifdef WOLFSSL_KYBER512
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
ssl->heap);
#endif
#ifdef WOLFSSL_KYBER768
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
ssl->heap);
#endif
#ifdef WOLFSSL_KYBER768
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5,
ssl->heap);
#endif
#elif defined(HAVE_LIBOQS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap); ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap);
#if HAVE_LIBOQS
if (ret == WOLFSSL_SUCCESS) if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3, ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
ssl->heap); ssl->heap);
@@ -11310,7 +11830,8 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
if (ret == WOLFSSL_SUCCESS) if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_90S_LEVEL5, ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_90S_LEVEL5,
ssl->heap); ssl->heap);
#elif defined(HAVE_PQM4)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap);
#endif /* HAVE_LIBOQS */ #endif /* HAVE_LIBOQS */
#endif /* HAVE_PQC */ #endif /* HAVE_PQC */

View File

@@ -50380,7 +50380,11 @@ static int test_tls13_apis(void)
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
int groups[2] = { WOLFSSL_ECC_SECP256R1, int groups[2] = { WOLFSSL_ECC_SECP256R1,
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifndef WOLFSSL_WC_KYBER
WOLFSSL_SABER_LEVEL3 WOLFSSL_SABER_LEVEL3
#else
WOLFSSL_KYBER_LEVEL1
#endif
#else #else
WOLFSSL_ECC_SECP256R1 WOLFSSL_ECC_SECP256R1
#endif #endif
@@ -50402,7 +50406,11 @@ static int test_tls13_apis(void)
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
"P-256" "P-256"
#ifdef HAVE_PQC #ifdef HAVE_PQC
#ifndef WOLFSSL_WC_KYBER
":P256_SABER_LEVEL1" ":P256_SABER_LEVEL1"
#else
":P256_KYBER_LEVEL1"
#endif
#endif #endif
#endif #endif
#ifdef HAVE_PQC #ifdef HAVE_PQC

View File

@@ -27,6 +27,7 @@ EXTRA_DIST += tests/unit.h \
tests/test-tls13-ecc.conf \ tests/test-tls13-ecc.conf \
tests/test-tls13-psk.conf \ tests/test-tls13-psk.conf \
tests/test-tls13-pq.conf \ tests/test-tls13-pq.conf \
tests/test-tls13-pq-2.conf \
tests/test-psk.conf \ tests/test-psk.conf \
tests/test-psk-no-id.conf \ tests/test-psk-no-id.conf \
tests/test-psk-no-id-sha2.conf \ tests/test-psk-no-id-sha2.conf \

View File

@@ -914,6 +914,17 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE; args.return_code = EXIT_FAILURE;
goto exit; goto exit;
} }
#ifdef HAVE_LIBOQS
/* add TLSv13 pq tests */
XSTRLCPY(argv0[1], "tests/test-tls13-pq-2.conf", sizeof(argv0[1]));
printf("starting TLSv13 post-quantum groups tests\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#endif
#endif #endif
#endif #endif
#if defined(WC_RSA_PSS) && (!defined(HAVE_FIPS) || \ #if defined(WC_RSA_PSS) && (!defined(HAVE_FIPS) || \

230
tests/test-tls13-pq-2.conf Normal file
View File

@@ -0,0 +1,230 @@
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_90S_LEVEL5

View File

@@ -28,233 +28,3 @@
-l TLS13-AES256-GCM-SHA384 -l TLS13-AES256-GCM-SHA384
--pqc KYBER_LEVEL5 --pqc KYBER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc KYBER_90S_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P256_KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P384_KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--pqc P521_KYBER_90S_LEVEL5

View File

@@ -254,6 +254,12 @@
#ifdef HAVE_ED448 #ifdef HAVE_ED448
#include <wolfssl/wolfcrypt/ed448.h> #include <wolfssl/wolfcrypt/ed448.h>
#endif #endif
#ifdef WOLFSSL_HAVE_KYBER
#include <wolfssl/wolfcrypt/kyber.h>
#ifdef WOLFSSL_WC_KYBER
#include <wolfssl/wolfcrypt/wc_kyber.h>
#endif
#endif
#ifdef WOLFCRYPT_HAVE_ECCSI #ifdef WOLFCRYPT_HAVE_ECCSI
#include <wolfssl/wolfcrypt/eccsi.h> #include <wolfssl/wolfcrypt/eccsi.h>
#endif #endif
@@ -263,6 +269,7 @@
#ifdef HAVE_LIBOQS #ifdef HAVE_LIBOQS
#include <oqs/kem.h> #include <oqs/kem.h>
#include <oqs/sig.h> #include <oqs/sig.h>
#include <wolfssl/wolfcrypt/ext_kyber.h>
#endif #endif
#if defined(HAVE_PQC) #if defined(HAVE_PQC)
@@ -284,6 +291,7 @@
#define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES #define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES
#define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES #define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES
typedef char OQS_KEM; typedef char OQS_KEM;
#include <wolfssl/wolfcrypt/ext_kyber.h>
#endif #endif
#include <wolfssl/wolfcrypt/dh.h> #include <wolfssl/wolfcrypt/dh.h>
@@ -431,6 +439,7 @@
#define BENCH_RSA 0x00000002 #define BENCH_RSA 0x00000002
#define BENCH_RSA_SZ 0x00000004 #define BENCH_RSA_SZ 0x00000004
#define BENCH_DH 0x00000010 #define BENCH_DH 0x00000010
#define BENCH_KYBER 0x00000020
#define BENCH_ECC_MAKEKEY 0x00001000 #define BENCH_ECC_MAKEKEY 0x00001000
#define BENCH_ECC 0x00002000 #define BENCH_ECC 0x00002000
#define BENCH_ECC_ENCRYPT 0x00004000 #define BENCH_ECC_ENCRYPT 0x00004000
@@ -694,6 +703,9 @@ static const bench_alg bench_asym_opt[] = {
#ifndef NO_DH #ifndef NO_DH
{ "-dh", BENCH_DH }, { "-dh", BENCH_DH },
#endif #endif
#ifdef WOLFSSL_HAVE_KYBER
{ "-kyber", BENCH_KYBER },
#endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
{ "-ecc-kg", BENCH_ECC_MAKEKEY }, { "-ecc-kg", BENCH_ECC_MAKEKEY },
{ "-ecc", BENCH_ECC }, { "-ecc", BENCH_ECC },
@@ -753,7 +765,7 @@ static const bench_alg bench_other_opt[] = {
#endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */ #endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
/* The post-quantum-specific mapping of command line option to bit values and /* The post-quantum-specific mapping of command line option to bit values and
* OQS name. */ * OQS name. */
typedef struct bench_pq_alg { typedef struct bench_pq_alg {
@@ -934,13 +946,14 @@ static const char* bench_result_words1[][4] = {
defined(HAVE_ECC) || !defined(NO_DH) || defined(HAVE_ECC_ENCRYPT) || \ defined(HAVE_ECC) || !defined(NO_DH) || defined(HAVE_ECC_ENCRYPT) || \
defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET) || \ defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET) || \
defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \ defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \
defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448) defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448) || \
defined(WOLFSSL_HAVE_KYBER)
static const char* bench_desc_words[][14] = { static const char* bench_desc_words[][15] = {
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 */ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
{"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 0 English */ {"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", "rsk gen", "encap", "derive", "valid", "pair gen", "decap", NULL}, /* 0 English */
#ifndef NO_MULTIBYTE_PRINT #ifndef NO_MULTIBYTE_PRINT
{"公開鍵", "秘密鍵" ,"鍵生成" , "鍵共有" , "署名", "検証" , "暗号化" , "復号化" , "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 1 Japanese */ {"公開鍵", "秘密鍵" ,"鍵生成" , "鍵共有" , "署名", "検証" , "暗号化" , "復号化" , "rsk gen", "encap", "derive", "valid", "pair gen", "decap", NULL}, /* 1 Japanese */
#endif #endif
}; };
@@ -1061,7 +1074,8 @@ static const char* bench_desc_words[][14] = {
#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WC_NO_RNG)) \ #if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WC_NO_RNG)) \
|| !defined(NO_DH) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \ || !defined(NO_DH) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \
|| defined(HAVE_CURVE25519) || defined(HAVE_ED25519) \ || defined(HAVE_CURVE25519) || defined(HAVE_ED25519) \
|| defined(HAVE_CURVE448) || defined(HAVE_ED448) || defined(HAVE_CURVE448) || defined(HAVE_ED448) \
|| defined(WOLFSSL_HAVE_KYBER)
#define HAVE_LOCAL_RNG #define HAVE_LOCAL_RNG
static THREAD_LS_T WC_RNG gRng; static THREAD_LS_T WC_RNG gRng;
#define GLOBAL_RNG &gRng #define GLOBAL_RNG &gRng
@@ -1072,14 +1086,16 @@ static const char* bench_desc_words[][14] = {
#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || \ #if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) || \ defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(HAVE_ECC) || !defined(NO_DH) || \ defined(HAVE_ECC) || !defined(NO_DH) || \
!defined(NO_RSA) || defined(HAVE_SCRYPT) !defined(NO_RSA) || defined(HAVE_SCRYPT) || \
defined(WOLFSSL_HAVE_KYBER)
#define BENCH_ASYM #define BENCH_ASYM
#endif #endif
#if defined(BENCH_ASYM) #if defined(BENCH_ASYM)
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \ #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \ defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(WOLFSSL_HAVE_KYBER)
static const char* bench_result_words2[][5] = { static const char* bench_result_words2[][5] = {
{ "ops took", "sec" , "avg" , "ops/sec", NULL }, /* 0 English */ { "ops took", "sec" , "avg" , "ops/sec", NULL }, /* 0 English */
#ifndef NO_MULTIBYTE_PRINT #ifndef NO_MULTIBYTE_PRINT
@@ -1644,7 +1660,8 @@ static void bench_stats_sym_finish(const char* desc, int useDeviceID, int count,
#ifdef BENCH_ASYM #ifdef BENCH_ASYM
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \ #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \ defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(WOLFSSL_HAVE_KYBER)
static void bench_stats_asym_finish(const char* algo, int strength, static void bench_stats_asym_finish(const char* algo, int strength,
const char* desc, int useDeviceID, int count, double start, int ret) const char* desc, int useDeviceID, int count, double start, int ret)
{ {
@@ -1690,7 +1707,7 @@ static void bench_stats_asym_finish(const char* algo, int strength,
} }
#endif #endif
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
static void bench_stats_pq_asym_finish(const char* algo, int useDeviceID, int count, static void bench_stats_pq_asym_finish(const char* algo, int useDeviceID, int count,
double start, int ret) double start, int ret)
{ {
@@ -2261,6 +2278,20 @@ static void* benchmarks_do(void* args)
} }
#endif #endif
#ifdef WOLFSSL_HAVE_KYBER
if (bench_all || (bench_asym_algs & BENCH_KYBER)) {
#ifdef WOLFSSL_KYBER512
bench_kyber(KYBER512);
#endif
#ifdef WOLFSSL_KYBER768
bench_kyber(KYBER768);
#endif
#ifdef WOLFSSL_KYBER1024
bench_kyber(KYBER1024);
#endif
}
#endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) || if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) ||
(bench_asym_algs & BENCH_ECC) || (bench_asym_algs & BENCH_ECC) ||
@@ -2371,7 +2402,7 @@ static void* benchmarks_do(void* args)
#endif #endif
#endif #endif
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_KEYGEN)) if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_KEYGEN))
bench_pqcKemKeygen(BENCH_KYBER_LEVEL1_KEYGEN); bench_pqcKemKeygen(BENCH_KYBER_LEVEL1_KEYGEN);
if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_ENCAP)) if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_ENCAP))
@@ -6135,6 +6166,128 @@ exit:
} }
#endif /* !NO_DH */ #endif /* !NO_DH */
#ifdef WOLFSSL_HAVE_KYBER
static void bench_kyber_keygen(int type, const char* name, int keySize,
KyberKey* key)
{
int ret = 0, times, count, pending = 0;
double start;
const char**desc = bench_desc_words[lng_index];
/* KYBER Make Key */
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
wc_KyberKey_Free(key);
ret = wc_KyberKey_Init(type, key, HEAP_HINT, INVALID_DEVID);
if (ret != 0)
goto exit;
#ifdef KYBER_NONDETERMINISTIC
ret = wc_KyberKey_MakeKey(key, &gRng);
#else
unsigned char rand[KYBER_MAKEKEY_RAND_SZ] = {0,};
ret = wc_KyberKey_MakeKeyWithRandom(key, rand, sizeof(rand));
#endif
if (ret != 0)
goto exit;
} /* for times */
count += times;
}
while (bench_stats_sym_check(start));
exit:
bench_stats_asym_finish(name, keySize, desc[2], 0, count, start, ret);
}
static void bench_kyber_encap(const char* name, int keySize, KyberKey* key)
{
int ret = 0, times, count, pending = 0;
double start;
const char**desc = bench_desc_words[lng_index];
byte ct[KYBER_MAX_CIPHER_TEXT_SIZE];
byte ss[KYBER_SS_SZ];
word32 ctSz;
ret = wc_KyberKey_CipherTextSize(key, &ctSz);
if (ret != 0) {
return;
}
/* KYBER Encapsulate */
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
#ifdef KYBER_NONDETERMINISTIC
ret = wc_KyberKey_Encapsulate(key, ct, ss, &gRng);
#else
unsigned char rand[KYBER_ENC_RAND_SZ] = {0,};
ret = wc_KyberKey_EncapsulateWithRandom(key, ct, ss, rand,
sizeof(rand));
#endif
if (ret != 0)
goto exit_encap;
} /* for times */
count += times;
}
while (bench_stats_sym_check(start));
exit_encap:
bench_stats_asym_finish(name, keySize, desc[9], 0, count, start, ret);
/* KYBER Decapsulate */
bench_stats_start(&count, &start);
do {
/* while free pending slots in queue, submit ops */
for (times = 0; times < agreeTimes || pending > 0; times++) {
ret = wc_KyberKey_Decapsulate(key, ss, ct, ctSz);
if (ret != 0)
goto exit_decap;
} /* for times */
count += times;
}
while (bench_stats_sym_check(start));
exit_decap:
bench_stats_asym_finish(name, keySize, desc[13], 0, count, start, ret);
}
void bench_kyber(int type)
{
KyberKey key;
const char* name = NULL;
int keySize = 0;
switch (type) {
#ifdef WOLFSSL_KYBER512
case KYBER512:
name = "KYBER512 ";
keySize = 128;
break;
#endif
#ifdef WOLFSSL_KYBER768
case KYBER768:
name = "KYBER768 ";
keySize = 192;
break;
#endif
#ifdef WOLFSSL_KYBER1024
case KYBER1024:
name = "KYBER1024";
keySize = 256;
break;
#endif
}
bench_kyber_keygen(type, name, keySize, &key);
bench_kyber_encap(name, keySize, &key);
wc_KyberKey_Free(&key);
}
#endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
/* +8 for 'ECDSA [%s]' and null terminator */ /* +8 for 'ECDSA [%s]' and null terminator */
@@ -7285,7 +7438,7 @@ void bench_sakke(void)
#endif /* WOLFCRYPT_SAKKE_CLIENT */ #endif /* WOLFCRYPT_SAKKE_CLIENT */
#endif /* WOLFCRYPT_HAVE_SAKKE */ #endif /* WOLFCRYPT_HAVE_SAKKE */
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
static void bench_pqcKemInit(word32 alg, byte **priv_key, byte **pub_key, static void bench_pqcKemInit(word32 alg, byte **priv_key, byte **pub_key,
const char **wolf_name, OQS_KEM **kem) const char **wolf_name, OQS_KEM **kem)
{ {
@@ -8188,7 +8341,7 @@ static void Usage(void)
for (i=0; bench_other_opt[i].str != NULL; i++) for (i=0; bench_other_opt[i].str != NULL; i++)
print_alg(bench_other_opt[i].str + 1, &line); print_alg(bench_other_opt[i].str + 1, &line);
printf("\n "); printf("\n ");
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
line = 13; line = 13;
for (i=0; bench_pq_asym_opt[i].str != NULL; i++) for (i=0; bench_pq_asym_opt[i].str != NULL; i++)
print_alg(bench_pq_asym_opt[i].str + 1, &line); print_alg(bench_pq_asym_opt[i].str + 1, &line);
@@ -8365,7 +8518,7 @@ int main(int argc, char** argv)
optMatched = 1; optMatched = 1;
} }
} }
#if defined(HAVE_PQC) #if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
/* Known asymmetric post-quantum algorithms */ /* Known asymmetric post-quantum algorithms */
for (i=0; !optMatched && bench_pq_asym_opt[i].str != NULL; i++) { for (i=0; !optMatched && bench_pq_asym_opt[i].str != NULL; i++) {
if (string_matches(argv[1], bench_pq_asym_opt[i].str)) { if (string_matches(argv[1], bench_pq_asym_opt[i].str)) {
@@ -8376,10 +8529,14 @@ int main(int argc, char** argv)
} }
#if defined(HAVE_LIBOQS) #if defined(HAVE_LIBOQS)
/* Both bench_pq_asym_opt and bench_pq_asym_opt2 are looking for /* Both bench_pq_asym_opt and bench_pq_asym_opt2 are looking for
* -pq, so we need to reset optMatched in case it was set to 1 just * -pq, so we need to do a special case for -pq since optMatched
* above. */ * was set to 1 just above. */
optMatched = 0; if (string_matches(argv[1], bench_pq_asym_opt[0].str)) {
for (i=0; !optMatched && bench_pq_asym_opt2[i].str != NULL; i++) { bench_pq_asym_algs2 |= bench_pq_asym_opt2[0].val;
bench_all = 0;
optMatched = 1;
}
for (i=1; !optMatched && bench_pq_asym_opt2[i].str != NULL; i++) {
if (string_matches(argv[1], bench_pq_asym_opt2[i].str)) { if (string_matches(argv[1], bench_pq_asym_opt2[i].str)) {
bench_pq_asym_algs2 |= bench_pq_asym_opt2[i].val; bench_pq_asym_algs2 |= bench_pq_asym_opt2[i].val;
bench_all = 0; bench_all = 0;

View File

@@ -85,6 +85,7 @@ void bench_rsaKeyGen_size(int useDeviceID, int keySz);
void bench_rsa(int useDeviceID); void bench_rsa(int useDeviceID);
void bench_rsa_key(int useDeviceID, int keySz); void bench_rsa_key(int useDeviceID, int keySz);
void bench_dh(int useDeviceID); void bench_dh(int useDeviceID);
void bench_kyber(int type);
void bench_ecc_curve(int curveId); void bench_ecc_curve(int curveId);
void bench_eccMakeKey(int useDeviceID, int curveId); void bench_eccMakeKey(int useDeviceID, int curveId);
void bench_ecc(int useDeviceID, int curveId); void bench_ecc(int useDeviceID, int curveId);

View File

@@ -5698,7 +5698,7 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
actualOidSz = (word32)length; actualOidSz = (word32)length;
#endif /* NO_VERIFY_OID */ #endif /* NO_VERIFY_OID */
#ifdef HAVE_PQC #if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
/* Since we are summing it up, there could be collisions...and indeed there /* Since we are summing it up, there could be collisions...and indeed there
* are: * are:
* *
@@ -11269,7 +11269,8 @@ static int GetCertHeader(DecodedCert* cert)
} }
#endif #endif
#if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_PQC) #if defined(HAVE_ED25519) || defined(HAVE_ED448) || (defined(HAVE_PQC) && \
defined(HAVE_LIBOQS))
/* Store the key data under the BIT_STRING in dynamicly allocated data. /* Store the key data under the BIT_STRING in dynamicly allocated data.
* *
* @param [in, out] cert Certificate object. * @param [in, out] cert Certificate object.
@@ -11761,7 +11762,7 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
ret = StoreKey(cert, source, &srcIdx, maxIdx); ret = StoreKey(cert, source, &srcIdx, maxIdx);
break; break;
#endif /* HAVE_ED448 */ #endif /* HAVE_ED448 */
#ifdef HAVE_PQC #if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
#ifdef HAVE_FALCON #ifdef HAVE_FALCON
case FALCON_LEVEL1k: case FALCON_LEVEL1k:
cert->pkCurveOID = FALCON_LEVEL1k; cert->pkCurveOID = FALCON_LEVEL1k;

690
wolfcrypt/src/ext_kyber.c Normal file
View File

@@ -0,0 +1,690 @@
/* ext_kyber.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/ext_kyber.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if defined(WOLFSSL_KYBER_90S) && defined(HAVE_PQM4)
#error "KYBER-90s is not supported when building PQM4"
#endif
#ifdef WOLFSSL_HAVE_KYBER
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#if defined (HAVE_LIBOQS)
static const char* OQS_ID2name(int id) {
switch (id) {
#ifdef WOLFSSL_KYBER_90S
case KYBER_LEVEL1: return OQS_KEM_alg_kyber_512_90s;
case KYBER_LEVEL3: return OQS_KEM_alg_kyber_768_90s;
case KYBER_LEVEL5: return OQS_KEM_alg_kyber_1024_90s;
#else
case KYBER_LEVEL1: return OQS_KEM_alg_kyber_512;
case KYBER_LEVEL3: return OQS_KEM_alg_kyber_768;
case KYBER_LEVEL5: return OQS_KEM_alg_kyber_1024;
#endif
default: break;
}
return NULL;
}
#endif
/******************************************************************************/
/* Initializer and cleanup functions. */
/**
* Initialize the Kyber key.
*
* @param [in] type Type of key: KYBER512, KYBER768, KYBER1024.
* @param [out] key Kyber key object to initialize.
* @param [in] heap Dynamic memory hint.
* @param [in] devId Device Id.
* @return 0 on success.
* @return BAD_FUNC_ARG when key is NULL or type is unrecognized.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_Init(int type, KyberKey* key, void* heap, int devId)
{
int ret = 0;
/* Validate key. */
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
/* Validate type. */
switch (type) {
case KYBER_LEVEL1:
#ifdef HAVE_LIBOQS
case KYBER_LEVEL3:
case KYBER_LEVEL5:
#endif /* HAVE_LIBOQS */
break;
default:
/* No other values supported. */
ret = BAD_FUNC_ARG;
break;
}
}
if (ret == 0) {
/* Zero out all data. */
XMEMSET(key, 0, sizeof(*key));
/* Keep type for parameters. */
key->type = type;
}
(void)devId;
(void)heap;
return ret;
}
/**
* Free the Kyber key object.
*
* @param [in, out] key Kyber key object to dispose of.
*/
void wc_KyberKey_Free(KyberKey* key)
{
if (key != NULL) {
/* Ensure all private data is zeroed. */
ForceZero(key, sizeof(*key));
}
}
/******************************************************************************/
/* Data size getters. */
/**
* Get the size in bytes of encoded private key for the key.
*
* @param [in] key Kyber key object.
* @param [out] len Length of encoded private key in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or len is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_PrivateKeySize(KyberKey* key, word32* len)
{
int ret = 0;
/* Validate parameters. */
if ((key == NULL) || (len == NULL)) {
ret = BAD_FUNC_ARG;
}
#ifdef HAVE_LIBOQS
/* NOTE: SHAKE and AES variants have the same length private key. */
if (ret == 0) {
switch (key->type) {
case KYBER_LEVEL1:
*len = OQS_KEM_kyber_512_length_secret_key;
break;
case KYBER_LEVEL3:
*len = OQS_KEM_kyber_768_length_secret_key;
break;
case KYBER_LEVEL5:
*len = OQS_KEM_kyber_1024_length_secret_key;
break;
default:
/* No other values supported. */
ret = BAD_FUNC_ARG;
break;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
(void)key;
if (ret == 0) {
*len = PQM4_PRIVATE_KEY_LENGTH;
}
#endif /* HAVE_PQM4 */
return ret;
}
/**
* Get the size in bytes of encoded public key for the key.
*
* @param [in] key Kyber key object.
* @param [out] len Length of encoded public key in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or len is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_PublicKeySize(KyberKey* key, word32* len)
{
int ret = 0;
/* Validate parameters. */
if ((key == NULL) || (len == NULL)) {
ret = BAD_FUNC_ARG;
}
#ifdef HAVE_LIBOQS
/* NOTE: SHAKE and AES variants have the same length public key. */
if (ret == 0) {
switch (key->type) {
case KYBER_LEVEL1:
*len = OQS_KEM_kyber_512_length_public_key;
break;
case KYBER_LEVEL3:
*len = OQS_KEM_kyber_768_length_public_key;
break;
case KYBER_LEVEL5:
*len = OQS_KEM_kyber_1024_length_public_key;
break;
default:
/* No other values supported. */
ret = BAD_FUNC_ARG;
break;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
(void)key;
if (ret == 0) {
*len = PQM4_PUBLIC_KEY_LENGTH;
}
#endif /* HAVE_PQM4 */
return ret;
}
/**
* Get the size in bytes of cipher text for key.
*
* @param [in] key Kyber key object.
* @param [out] len Length of cipher text in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or len is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_CipherTextSize(KyberKey* key, word32* len)
{
int ret = 0;
/* Validate parameters. */
if ((key == NULL) || (len == NULL)) {
ret = BAD_FUNC_ARG;
}
#ifdef HAVE_LIBOQS
/* NOTE: SHAKE and AES variants have the same length ciphertext. */
if (ret == 0) {
switch (key->type) {
case KYBER_LEVEL1:
*len = OQS_KEM_kyber_512_length_ciphertext;
break;
case KYBER_LEVEL3:
*len = OQS_KEM_kyber_768_length_ciphertext;
break;
case KYBER_LEVEL5:
*len = OQS_KEM_kyber_1024_length_ciphertext;
break;
default:
/* No other values supported. */
ret = BAD_FUNC_ARG;
break;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
(void)key;
if (ret == 0) {
*len = PQM4_CIPHERTEXT_LENGTH;
}
#endif /* HAVE_PQM4 */
return ret;
}
/**
* Size of a shared secret in bytes. Always KYBER_SS_SZ.
*
* @param [in] key Kyber key object. Not used.
* @param [out] Size of the shared secret created with a Kyber key.
* @return 0 on success.
* @return 0 to indicate success.
*/
int wc_KyberKey_SharedSecretSize(KyberKey* key, word32* len)
{
(void)key;
/* Validate parameters. */
if (len == NULL) {
return BAD_FUNC_ARG;
}
*len = KYBER_SS_SZ;
return 0;
}
/******************************************************************************/
/* Cryptographic operations. */
/**
* Make a Kyber key object using a random number generator.
*
* NOTE: rng is ignored. OQS and PQM4 don't use our RNG.
*
* @param [in, out] key Kyber key ovject.
* @param [in] rng Random number generator.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or rng is NULL.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng)
{
int ret = 0;
const char* algName = NULL;
OQS_KEM *kem = NULL;
(void)rng;
/* Validate parameter. */
if (key == NULL) {
return BAD_FUNC_ARG;
}
#ifdef HAVE_LIBOQS
if (ret == 0) {
algName = OQS_ID2name(key->type);
if (algName == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
algName = OQS_ID2name(key->type);
if (algName == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
kem = OQS_KEM_new(algName);
if (kem == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
if (OQS_KEM_keypair(kem, key->pub, key->priv) !=
OQS_SUCCESS) {
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
if (ret == 0) {
if (crypto_kem_keypair(key->pub, key->priv) != 0) {
WOLFSSL_MSG("PQM4 keygen failure");
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_PQM4 */
if (ret != 0) {
ForceZero(key, sizeof(*key));
}
OQS_KEM_free(kem);
return ret;
}
/**
* Make a Kyber key object using random data.
*
* @param [in, out] key Kyber key ovject.
* @param [in] rng Random number generator.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or rand is NULL.
* @return BUFFER_E when length is not KYBER_MAKEKEY_RAND_SZ.
* @return NOT_COMPILED_IN when key type is not supported.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_KyberKey_MakeKeyWithRandom(KyberKey* key, const unsigned char* rand,
int len)
{
(void)rand;
(void)len;
/* OQS and PQM4 don't support external randomness. */
return wc_KyberKey_MakeKey(key, NULL);
}
/**
* Encapsulate with random number generator and derive secret.
*
* @param [in] key Kyber key object.
* @param [out] ct Cipher text.
* @param [out] ss Shared secret generated.
* @param [in] rng Random number generator.
* @return 0 on success.
* @return BAD_FUNC_ARG when key, ct, ss or RNG is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss,
WC_RNG* rng)
{
int ret = 0;
const char * algName = NULL;
OQS_KEM *kem = NULL;
(void)rng;
/* Validate parameters. */
if ((key == NULL) || (ct == NULL) || (ss == NULL)) {
ret = BAD_FUNC_ARG;
}
#ifdef HAVE_LIBOQS
if (ret == 0) {
algName = OQS_ID2name(key->type);
if (algName == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
kem = OQS_KEM_new(algName);
if (kem == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
if (OQS_KEM_encaps(kem, ct, ss, key->pub) != OQS_SUCCESS) {
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
if (ret == 0) {
if (crypto_kem_enc(ct, ss, key->pub) != 0) {
WOLFSSL_MSG("PQM4 Encapsulation failure.");
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_PQM4 */
OQS_KEM_free(kem);
return ret;
}
/**
* Encapsulate with random data and derive secret.
*
* @param [out] ct Cipher text.
* @param [out] ss Shared secret generated.
* @param [in] rand Random data.
* @param [in] len Random data.
* @return 0 on success.
* @return BAD_FUNC_ARG when key, ct, ss or RNG is NULL.
* @return BUFFER_E when len is not KYBER_ENC_RAND_SZ.
* @return NOT_COMPILED_IN when key type is not supported.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_KyberKey_EncapsulateWithRandom(KyberKey* key, unsigned char* ct,
unsigned char* ss, const unsigned char* rand, int len)
{
(void)rand;
(void)len;
/* OQS and PQM4 don't support external randomness. */
return wc_KyberKey_Encapsulate(key, ct, ss, NULL);
}
/**
* Decapsulate the cipher text to calculate the shared secret.
*
* Validates the cipher text by encapsulating and comparing with data passed in.
*
* @param [in] key Kyber key object.
* @param [out] ss Shared secret.
* @param [in] ct Cipher text.
* @param [in] len Length of cipher text.
* @return 0 on success.
* @return BAD_FUNC_ARG when key, ss or cr are NULL.
* @return NOT_COMPILED_IN when key type is not supported.
* @return BUFFER_E when len is not the length of cipher text for the key type.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss,
const unsigned char* ct, word32 len)
{
int ret = 0;
const char * algName = NULL;
word32 ctlen = 0;
OQS_KEM *kem = NULL;
/* Validate parameters. */
if ((key == NULL) || (ss == NULL) || (ct == NULL)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_CipherTextSize(key, &ctlen);
}
if ((ret == 0) && (len != ctlen)) {
ret = BUFFER_E;
}
#ifdef HAVE_LIBOQS
if (ret == 0) {
algName = OQS_ID2name(key->type);
if (algName == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
kem = OQS_KEM_new(algName);
if (kem == NULL) {
ret = BAD_FUNC_ARG;
}
}
if (ret == 0) {
if (OQS_KEM_decaps(kem, ss, ct, key->priv) != OQS_SUCCESS) {
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_LIBOQS */
#ifdef HAVE_PQM4
if (ret == 0) {
if (crypto_kem_enc(ss, ct, key->priv) != 0) {
WOLFSSL_MSG("PQM4 Decapsulation failure.");
ret = BAD_FUNC_ARG;
}
}
#endif /* HAVE_PQM4 */
OQS_KEM_free(kem);
return ret;
}
/******************************************************************************/
/* Encoding and decoding functions. */
/**
* Decode the private key.
*
* We store the whole thing in the private key buffer. Note this means we cannot
* do the encapsulation operation with the private key. But generally speaking
* this is never done.
*
* @param [in, out] key Kyber key object.
* @param [in] in Buffer holding encoded key.
* @param [in] len Length of data in buffer.
* @return 0 on success.
* @return BAD_FUNC_ARG when key ot in is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
* @return BUFFER_E when len is not the correct size.
*/
int wc_KyberKey_DecodePrivateKey(KyberKey* key, unsigned char* in, word32 len)
{
int ret = 0;
word32 privLen = 0;
/* Validate parameters. */
if ((key == NULL) || (in == NULL)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_PrivateKeySize(key, &privLen);
}
/* Ensure the data is the correct length for the key type. */
if ((ret == 0) && (len != privLen)) {
ret = BUFFER_E;
}
if (ret == 0) {
XMEMCPY(key->priv, in, privLen);
}
return ret;
}
/**
* Decode public key.
*
* We store the whole thing in the public key buffer.
*
* @param [in, out] key Kyber key object.
* @param [in] in Buffer holding encoded key.
* @param [in] len Length of data in buffer.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or in is NULL.
* @return NOT_COMPILED_IN when key type is not supported.
* @return BUFFER_E when len is not the correct size.
*/
int wc_KyberKey_DecodePublicKey(KyberKey* key, unsigned char* in, word32 len)
{
int ret = 0;
word32 pubLen = 0;
/* Validate parameters. */
if ((key == NULL) || (in == NULL)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_PublicKeySize(key, &pubLen);
}
/* Ensure the data is the correct length for the key type. */
if ((ret == 0) && (len != pubLen)) {
ret = BUFFER_E;
}
if (ret == 0) {
XMEMCPY(key->pub, in, pubLen);
}
return ret;
}
/**
* Encode the private key.
*
* We stored it as a blob so we can just copy it over.
*
* @param [in] key Kyber key object.
* @param [out] out Buffer to hold data.
* @param [in] len Size of buffer in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or out is NULL or private/public key not
* available.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_EncodePrivateKey(KyberKey* key, unsigned char* out, word32 len)
{
int ret = 0;
unsigned int privLen = 0;
if ((key == NULL) || (out == NULL)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_PrivateKeySize(key, &privLen);
}
/* Check buffer is big enough for encoding. */
if ((ret == 0) && (len != privLen)) {
ret = BUFFER_E;
}
if (ret == 0) {
XMEMCPY(out, key->priv, privLen);
}
return ret;
}
/**
* Encode the public key.
*
* We stored it as a blob so we can just copy it over.
*
* @param [in] key Kyber key object.
* @param [out] out Buffer to hold data.
* @param [in] len Size of buffer in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when key or out is NULL or public key not available.
* @return NOT_COMPILED_IN when key type is not supported.
*/
int wc_KyberKey_EncodePublicKey(KyberKey* key, unsigned char* out, word32 len)
{
int ret = 0;
unsigned int pubLen = 0;
if ((key == NULL) || (out == NULL)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
ret = wc_KyberKey_PublicKeySize(key, &pubLen);
}
/* Check buffer is big enough for encoding. */
if ((ret == 0) && (len != pubLen)) {
ret = BUFFER_E;
}
if (ret == 0) {
XMEMCPY(out, key->pub, pubLen);
}
return ret;
}
#endif /* WOLFSSL_HAVE_KYBER */

3
wolfcrypt/src/wc_kyber.c Normal file
View File

@@ -0,0 +1,3 @@
#error "Contact wolfSSL to get the implementation of this file"

View File

@@ -0,0 +1,3 @@
#error "Contact wolfSSL to get the implementation of this file"

View File

@@ -0,0 +1,3 @@
#error "Contact wolfSSL to get the implementation of this file"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/* ext_kyber.h
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef EXT_KYBER_H
#define EXT_KYBER_H
#include <wolfssl/wolfcrypt/kyber.h>
#if !defined(HAVE_LIBOQS) && !defined(HAVE_PQM4)
#error "This code requires liboqs or pqm4"
#endif
#if defined(WOLFSSL_WC_KYBER)
#error "This code is incompatible with wolfCrypt's implementation of Kyber."
#endif
#if defined (HAVE_LIBOQS)
#include <oqs/kem.h>
#define EXT_KYBER_MAX_PRIV_SZ OQS_KEM_kyber_1024_length_secret_key
#define EXT_KYBER_MAX_PUB_SZ OQS_KEM_kyber_1024_length_public_key
#elif defined(HAVE_PQM4)
#include "api_kyber.h"
#define PQM4_PUBLIC_KEY_LENGTH CRYPTO_PUBLICKEYBYTES
#define PQM4_PRIVATE_KEY_LENGTH CRYPTO_SECRETKEYBYTES
#define PQM4_SHARED_SECRET_LENGTH CRYPTO_BYTES
#define PQM4_CIPHERTEXT_LENGTH CRYPTO_CIPHERTEXTBYTES
#define EXT_KYBER_MAX_PRIV_SZ PQM4_PRIVATE_KEY_LENGTH
#define EXT_KYBER_MAX_PUB_SZ PQM4_PUBLIC_KEY_LENGTH
#endif
struct KyberKey {
/* Type of key: KYBER_LEVEL1
* KYBER_LEVEL3
* KYBER_LEVEL5
*
* Note we don't save the variant (SHAKE vs AES) as that is decided at
* configuration time. */
int type;
byte priv[EXT_KYBER_MAX_PRIV_SZ];
byte pub[EXT_KYBER_MAX_PUB_SZ];
};
#endif /* EXT_KYBER_H */

View File

@@ -71,7 +71,10 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/sha3.h \ wolfssl/wolfcrypt/sha3.h \
wolfssl/wolfcrypt/siphash.h \ wolfssl/wolfcrypt/siphash.h \
wolfssl/wolfcrypt/cpuid.h \ wolfssl/wolfcrypt/cpuid.h \
wolfssl/wolfcrypt/cryptocb.h wolfssl/wolfcrypt/cryptocb.h \
wolfssl/wolfcrypt/kyber.h \
wolfssl/wolfcrypt/wc_kyber.h \
wolfssl/wolfcrypt/ext_kyber.h
noinst_HEADERS+= \ noinst_HEADERS+= \
wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \

223
wolfssl/wolfcrypt/kyber.h Normal file
View File

@@ -0,0 +1,223 @@
/* kyber.h
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/kyber.h
*/
#ifndef WOLF_CRYPT_KYBER_H
#define WOLF_CRYPT_KYBER_H
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/random.h>
#ifdef WOLFSSL_HAVE_KYBER
/* Define algorithm type when not excluded. */
#ifndef WOLFSSL_NO_KYBER512
#define WOLFSSL_KYBER512
#endif
#ifndef WOLFSSL_NO_KYBER768
#define WOLFSSL_KYBER768
#endif
#ifndef WOLFSSL_NO_KYBER1024
#define WOLFSSL_KYBER1024
#endif
/* Number of co-efficients in polynomial. */
#define KYBER_N 256
/* Size of a polynomial vector based on dimensions. */
#define KYBER_POLY_VEC_SZ(k) (k * KYBER_POLY_SIZE)
/* Size of a compressed polynomial based on bits per coefficient. */
#define KYBER_POLY_COMPRESSED_SZ(b) (b * (KYBER_N / 8))
/* Size of a compressed vector polynomial based on dimensions and bits per
* coefficient. */
#define KYBER_POLY_VEC_COMPRESSED_SZ(k, b) (k * (b * (KYBER_N / 8)))
/* Kyber-512 parameters */
#ifdef WOLFSSL_KYBER512
/* Number of polynomials in a vector and vectors in a matrix. */
#define KYBER512_K 2
/* Size of a polynomial vector. */
#define KYBER512_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER512_K)
/* Size of a compressed polynomial based on bits per coefficient. */
#define KYBER512_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(4)
/* Size of a compressed vector polynomial based on dimensions and bits per
* coefficient. */
#define KYBER512_POLY_VEC_COMPRESSED_SZ \
KYBER_POLY_VEC_COMPRESSED_SZ(KYBER512_K, 10)
/* Public key size. */
#define KYBER512_PUBLIC_KEY_SIZE \
(KYBER512_POLY_VEC_SZ + KYBER_SYM_SZ)
/* Private key size. */
#define KYBER512_PRIVATE_KEY_SIZE \
(KYBER512_POLY_VEC_SZ + KYBER512_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ)
/* Cipher text size. */
#define KYBER512_CIPHER_TEXT_SIZE \
(KYBER512_POLY_VEC_COMPRESSED_SZ + KYBER512_POLY_COMPRESSED_SZ)
#endif /* WOLFSSL_KYBER512 */
/* Kyber-768 parameters */
#ifdef WOLFSSL_KYBER768
/* Number of polynomials in a vector and vectors in a matrix. */
#define KYBER768_K 3
/* Size of a polynomial vector. */
#define KYBER768_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER768_K)
/* Size of a compressed polynomial based on bits per coefficient. */
#define KYBER768_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(4)
/* Size of a compressed vector polynomial based on dimensions and bits per
* coefficient. */
#define KYBER768_POLY_VEC_COMPRESSED_SZ \
KYBER_POLY_VEC_COMPRESSED_SZ(KYBER768_K, 10)
/* Public key size. */
#define KYBER768_PUBLIC_KEY_SIZE \
(KYBER768_POLY_VEC_SZ + KYBER_SYM_SZ)
/* Private key size. */
#define KYBER768_PRIVATE_KEY_SIZE \
(KYBER768_POLY_VEC_SZ + KYBER768_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ)
/* Cipher text size. */
#define KYBER768_CIPHER_TEXT_SIZE \
(KYBER768_POLY_VEC_COMPRESSED_SZ + KYBER768_POLY_COMPRESSED_SZ)
#endif /* WOLFSSL_KYBER768 */
/* Kyber-1024 parameters */
#ifdef WOLFSSL_KYBER1024
/* Number of polynomials in a vector and vectors in a matrix. */
#define KYBER1024_K 4
/* Size of a polynomial vector. */
#define KYBER1024_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER1024_K)
/* Size of a compressed polynomial based on bits per coefficient. */
#define KYBER1024_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(5)
/* Size of a compressed vector polynomial based on dimensions and bits per
* coefficient. */
#define KYBER1024_POLY_VEC_COMPRESSED_SZ \
KYBER_POLY_VEC_COMPRESSED_SZ(KYBER1024_K, 11)
/* Public key size. */
#define KYBER1024_PUBLIC_KEY_SIZE \
(KYBER1024_POLY_VEC_SZ + KYBER_SYM_SZ)
/* Private key size. */
#define KYBER1024_PRIVATE_KEY_SIZE \
(KYBER1024_POLY_VEC_SZ + KYBER1024_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ)
/* Cipher text size. */
#define KYBER1024_CIPHER_TEXT_SIZE \
(KYBER1024_POLY_VEC_COMPRESSED_SZ + KYBER1024_POLY_COMPRESSED_SZ)
#endif /* WOLFSSL_KYBER1024 */
/* Maximum dimensions and sizes of supported key types. */
#ifdef WOLFSSL_KYBER1024
#define KYBER_MAX_K KYBER1024_K
#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER1024_PRIVATE_KEY_SIZE
#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER1024_PUBLIC_KEY_SIZE
#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER1024_CIPHER_TEXT_SIZE
#elif defined(WOLFSSL_KYBER768)
#define KYBER_MAX_K KYBER768_K
#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER768_PRIVATE_KEY_SIZE
#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER768_PUBLIC_KEY_SIZE
#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER768_CIPHER_TEXT_SIZE
#else
#define KYBER_MAX_K KYBER512_K
#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER512_PRIVATE_KEY_SIZE
#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER512_PUBLIC_KEY_SIZE
#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER512_CIPHER_TEXT_SIZE
#endif
enum {
/* Types of Kyber keys. */
KYBER512 = 0,
KYBER768 = 1,
KYBER1024 = 2,
KYBER_LEVEL1 = KYBER512,
KYBER_LEVEL3 = KYBER768,
KYBER_LEVEL5 = KYBER1024,
/* Symmetric data size. */
KYBER_SYM_SZ = 32,
/* Shared secret size. */
KYBER_SS_SZ = 32,
/* Size of random required for making a key. */
KYBER_MAKEKEY_RAND_SZ = 2 * KYBER_SYM_SZ,
/* Size of random required for encapsulation. */
KYBER_ENC_RAND_SZ = KYBER_SYM_SZ,
/* Encoded polynomial size. */
KYBER_POLY_SIZE = 384,
};
/* Different structures for different implementations. */
typedef struct KyberKey KyberKey;
#ifdef __cplusplus
extern "C" {
#endif
WOLFSSL_API int wc_KyberKey_Init(int type, KyberKey* key, void* heap,
int devId);
WOLFSSL_API void wc_KyberKey_Free(KyberKey* key);
WOLFSSL_API int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng);
WOLFSSL_API int wc_KyberKey_MakeKeyWithRandom(KyberKey* key,
const unsigned char* rand, int len);
WOLFSSL_API int wc_KyberKey_CipherTextSize(KyberKey* key, word32* len);
WOLFSSL_API int wc_KyberKey_SharedSecretSize(KyberKey* key, word32* len);
WOLFSSL_API int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct,
unsigned char* ss, WC_RNG* rng);
WOLFSSL_API int wc_KyberKey_EncapsulateWithRandom(KyberKey* key,
unsigned char* ct, unsigned char* ss, const unsigned char* rand, int len);
WOLFSSL_API int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss,
const unsigned char* ct, word32 len);
WOLFSSL_API int wc_KyberKey_DecodePrivateKey(KyberKey* key, unsigned char* in,
word32 len);
WOLFSSL_API int wc_KyberKey_DecodePublicKey(KyberKey* key, unsigned char* in,
word32 len);
WOLFSSL_API int wc_KyberKey_PrivateKeySize(KyberKey* key, word32* len);
WOLFSSL_API int wc_KyberKey_PublicKeySize(KyberKey* key, word32* len);
WOLFSSL_API int wc_KyberKey_EncodePrivateKey(KyberKey* key, unsigned char* out,
word32 len);
WOLFSSL_API int wc_KyberKey_EncodePublicKey(KyberKey* key, unsigned char* out,
word32 len);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLFSSL_HAVE_KYBER */
#endif /* WOLF_CRYPT_KYBER_H */

View File

@@ -2722,6 +2722,10 @@ extern void uITRON4_free(void *p) ;
#endif #endif
#endif #endif
#ifdef WOLFSSL_HAVE_KYBER
#define HAVE_PQC
#endif
/* Enable Post-Quantum Cryptography if we have liboqs from the OpenQuantumSafe /* Enable Post-Quantum Cryptography if we have liboqs from the OpenQuantumSafe
* group */ * group */
#ifdef HAVE_LIBOQS #ifdef HAVE_LIBOQS
@@ -2737,7 +2741,8 @@ extern void uITRON4_free(void *p) ;
#define HAVE_KYBER #define HAVE_KYBER
#endif #endif
#if defined(HAVE_PQC) && !defined(HAVE_LIBOQS) && !defined(HAVE_PQM4) #if defined(HAVE_PQC) && !defined(HAVE_LIBOQS) && !defined(HAVE_PQM4) && \
!defined(WOLFSSL_HAVE_KYBER)
#error Please do not define HAVE_PQC yourself. #error Please do not define HAVE_PQC yourself.
#endif #endif

View File

@@ -0,0 +1,3 @@
#error "Contact wolfSSL to get the implementation of this file"