Kyber: Add option to build Kyber API

wolfSSL Kyber implementation not included.
Added tests and benchmarking.
This commit is contained in:
Sean Parkinson
2022-09-08 11:23:30 +10:00
committed by Anthony Hu
parent 38418b31f1
commit 8c1e2c52e7
20 changed files with 5307 additions and 267 deletions

View File

@@ -963,6 +963,78 @@ then
fi
# 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_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
fi
# SINGLE THREADED
AC_ARG_ENABLE([singlethreaded],
[AS_HELP_STRING([--enable-singlethreaded],[Enable wolfSSL single threaded (default: disabled)])],
@@ -3068,7 +3140,6 @@ then
fi
# FP ECC, Fixed Point cache ECC
AC_ARG_ENABLE([fpecc],
[AS_HELP_STRING([--enable-fpecc],[Enable Fixed Point cache ECC (default: disabled)])],
@@ -8042,6 +8113,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_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_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_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"])
@@ -8443,14 +8515,16 @@ echo " * DH Default Parameters: $ENABLED_DHDEFAULTPARAMS"
echo " * ECC: $ENABLED_ECC"
echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES"
echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ"
echo " * FPECC: $ENABLED_FPECC"
echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT"
echo " * CURVE25519: $ENABLED_CURVE25519"
echo " * ED25519: $ENABLED_ED25519"
echo " * ED25519 streaming: $ENABLED_ED25519_STREAM"
echo " * CURVE448: $ENABLED_CURVE448"
echo " * ED448: $ENABLED_ED448"
echo " * ED448 streaming: $ENABLED_ED448_STREAM"
echo " * FPECC: $ENABLED_FPECC"
echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT"
echo " * KYBER: $ENABLED_KYBER"
echo " * KYBER wolfSSL impl: $ENABLED_WC_KYBER"
echo " * ECCSI $ENABLED_ECCSI"
echo " * SAKKE $ENABLED_SAKKE"
echo " * ASN: $ENABLED_ASN"

View File

@@ -104,6 +104,14 @@ if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
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
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
endif
@@ -185,6 +193,14 @@ if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
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
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM
@@ -587,6 +603,14 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/sakke.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_CURVE25519
src_libwolfssl_la_SOURCES += wolfcrypt/src/curve25519.c
endif

View File

@@ -7629,7 +7629,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
}
#endif
#endif
#ifdef HAVE_PQC
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
#endif
@@ -7864,7 +7864,7 @@ void FreeHandshakeResources(WOLFSSL* ssl)
FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0;
#endif /* HAVE_ED448 */
#ifdef HAVE_PQC
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
#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_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3},
{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_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3},
{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("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},
#endif
#endif
{0, NULL, 0},
};
@@ -2879,6 +2881,7 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_KYBER_LEVEL1:
case WOLFSSL_KYBER_LEVEL3:
case WOLFSSL_KYBER_LEVEL5:
#ifdef HAVE_LIBOQS
case WOLFSSL_NTRU_HPS_LEVEL1:
case WOLFSSL_NTRU_HPS_LEVEL3:
case WOLFSSL_NTRU_HPS_LEVEL5:
@@ -2902,6 +2905,7 @@ static int isValidCurveGroup(word16 name)
case WOLFSSL_P256_KYBER_90S_LEVEL1:
case WOLFSSL_P384_KYBER_90S_LEVEL3:
case WOLFSSL_P521_KYBER_90S_LEVEL5:
#endif
#endif
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) || \
defined(HAVE_PQC) || !defined(NO_RSA)
(defined(HAVE_PQC) && defined(HAVE_LIBOQS)) || !defined(NO_RSA)
if (ssl) {
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
(defined(HAVE_CURVE448) && defined(HAVE_ED448))
@@ -20751,6 +20755,19 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
#elif defined(HAVE_PQM4)
case WOLFSSL_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
}
}

541
src/tls.c
View File

@@ -49,7 +49,12 @@
#include <wolfssl/wolfcrypt/curve448.h>
#endif
#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>
#endif
#elif defined(HAVE_LIBOQS)
#include <oqs/kem.h>
#elif defined(HAVE_PQM4)
#include "api_kyber.h"
@@ -7053,7 +7058,35 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
}
#ifdef HAVE_PQC
#ifdef HAVE_LIBOQS
#ifdef WOLFSSL_HAVE_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. */
static const char* OQS_ID2name(int id)
{
@@ -7150,7 +7183,120 @@ static void findEccPqc(int *ecc, int *pqc, int group)
* kse The key share entry object.
* returns 0 on success, otherwise failure.
*/
#ifdef HAVE_LIBOQS
#ifdef WOLFSSL_HAVE_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)
{
int ret = 0;
@@ -7938,7 +8084,174 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
}
#ifdef HAVE_PQC
#ifdef HAVE_LIBOQS
#ifdef WOLFSSL_HAVE_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("Kyber 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.
*
* ssl The SSL/TLS object.
@@ -8568,10 +8881,171 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
}
#ifdef HAVE_PQC
#ifdef HAVE_LIBOQS
#ifdef WOLFSSL_HAVE_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("OQS 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,
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
* to generate the public information (AKA ciphertext) and shared secret
* here. Note the "public information" is equivalent to a the public key in
@@ -8721,7 +9195,8 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
#elif defined(HAVE_PQM4)
static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
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
* to generate the public information (AKA ciphertext) and shared secret
* here. Note the "public information" is equivalent to a the public key in
@@ -9059,7 +9534,18 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
#endif
#endif
#ifdef HAVE_PQC
#ifdef HAVE_LIBOQS
#ifdef WOLFSSL_HAVE_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_LEVEL3:
case WOLFSSL_KYBER_LEVEL5:
@@ -9165,9 +9651,22 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
/* For the liboqs groups we need to do a runtime check because
* liboqs could be compiled to make an algorithm unavailable.
*/
#ifdef WOLFSSL_HAVE_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))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL1;
#ifdef HAVE_LIBOQS
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL3))
ssl->group[ssl->numGroups++] = WOLFSSL_KYBER_LEVEL3;
if (TLSX_KeyShare_IsSupported(WOLFSSL_KYBER_LEVEL5))
@@ -9218,6 +9717,9 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
ssl->group[ssl->numGroups++] = WOLFSSL_P384_KYBER_90S_LEVEL3;
if (TLSX_KeyShare_IsSupported(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_PQC */
}
@@ -11231,8 +11733,24 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
#endif
#ifdef HAVE_PQC
#ifdef WOLFSSL_HAVE_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);
#if HAVE_LIBOQS
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
ssl->heap);
@@ -11308,7 +11826,8 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_90S_LEVEL5,
ssl->heap);
#elif defined(HAVE_PQM4)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap);
#endif /* HAVE_LIBOQS */
#endif /* HAVE_PQC */

View File

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

View File

@@ -914,6 +914,17 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE;
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
#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
--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
#include <wolfssl/wolfcrypt/ed448.h>
#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
#include <wolfssl/wolfcrypt/eccsi.h>
#endif
@@ -431,6 +437,7 @@
#define BENCH_RSA 0x00000002
#define BENCH_RSA_SZ 0x00000004
#define BENCH_DH 0x00000010
#define BENCH_KYBER 0x00000020
#define BENCH_ECC_MAKEKEY 0x00001000
#define BENCH_ECC 0x00002000
#define BENCH_ECC_ENCRYPT 0x00004000
@@ -694,6 +701,9 @@ static const bench_alg bench_asym_opt[] = {
#ifndef NO_DH
{ "-dh", BENCH_DH },
#endif
#ifdef WOLFSSL_HAVE_KYBER
{ "-kyber", BENCH_KYBER },
#endif
#ifdef HAVE_ECC
{ "-ecc-kg", BENCH_ECC_MAKEKEY },
{ "-ecc", BENCH_ECC },
@@ -753,7 +763,7 @@ static const bench_alg bench_other_opt[] = {
#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
* OQS name. */
typedef struct bench_pq_alg {
@@ -934,13 +944,14 @@ static const char* bench_result_words1[][4] = {
defined(HAVE_ECC) || !defined(NO_DH) || defined(HAVE_ECC_ENCRYPT) || \
defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET) || \
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] = {
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 */
{"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 0 English */
static const char* bench_desc_words[][15] = {
/* 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", "decap", NULL}, /* 0 English */
#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
};
@@ -1061,7 +1072,8 @@ static const char* bench_desc_words[][14] = {
#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WC_NO_RNG)) \
|| !defined(NO_DH) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \
|| 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
static THREAD_LS_T WC_RNG gRng;
#define GLOBAL_RNG &gRng
@@ -1072,14 +1084,16 @@ static const char* bench_desc_words[][14] = {
#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
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
#endif
#if defined(BENCH_ASYM)
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
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] = {
{ "ops took", "sec" , "avg" , "ops/sec", NULL }, /* 0 English */
#ifndef NO_MULTIBYTE_PRINT
@@ -1644,7 +1658,8 @@ static void bench_stats_sym_finish(const char* desc, int useDeviceID, int count,
#ifdef BENCH_ASYM
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
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,
const char* desc, int useDeviceID, int count, double start, int ret)
{
@@ -1690,7 +1705,7 @@ static void bench_stats_asym_finish(const char* algo, int strength,
}
#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,
double start, int ret)
{
@@ -2261,6 +2276,20 @@ static void* benchmarks_do(void* args)
}
#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
if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) ||
(bench_asym_algs & BENCH_ECC) ||
@@ -2371,7 +2400,7 @@ static void* benchmarks_do(void* args)
#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))
bench_pqcKemKeygen(BENCH_KYBER_LEVEL1_KEYGEN);
if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_ENCAP))
@@ -6135,6 +6164,128 @@ exit:
}
#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
/* +8 for 'ECDSA [%s]' and null terminator */
@@ -7285,7 +7436,7 @@ void bench_sakke(void)
#endif /* WOLFCRYPT_SAKKE_CLIENT */
#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,
const char **wolf_name, OQS_KEM **kem)
{
@@ -8188,7 +8339,7 @@ static void Usage(void)
for (i=0; bench_other_opt[i].str != NULL; i++)
print_alg(bench_other_opt[i].str + 1, &line);
printf("\n ");
#if defined(HAVE_PQC)
#if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
line = 13;
for (i=0; bench_pq_asym_opt[i].str != NULL; i++)
print_alg(bench_pq_asym_opt[i].str + 1, &line);
@@ -8365,7 +8516,7 @@ int main(int argc, char** argv)
optMatched = 1;
}
}
#if defined(HAVE_PQC)
#if defined(HAVE_PQC) && (defined(HAVE_LIBOQS) || defined(HAVE_PQM4))
/* Known asymmetric post-quantum algorithms */
for (i=0; !optMatched && bench_pq_asym_opt[i].str != NULL; i++) {
if (string_matches(argv[1], bench_pq_asym_opt[i].str)) {

View File

@@ -85,6 +85,7 @@ void bench_rsaKeyGen_size(int useDeviceID, int keySz);
void bench_rsa(int useDeviceID);
void bench_rsa_key(int useDeviceID, int keySz);
void bench_dh(int useDeviceID);
void bench_kyber(int type);
void bench_ecc_curve(int curveId);
void bench_eccMakeKey(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;
#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
* are:
*
@@ -11269,7 +11269,8 @@ static int GetCertHeader(DecodedCert* cert)
}
#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.
*
* @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);
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_PQC
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
#ifdef HAVE_FALCON
case FALCON_LEVEL1k:
cert->pkCurveOID = FALCON_LEVEL1k;

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

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

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

@@ -0,0 +1,232 @@
/* 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,
};
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);
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
#ifdef WOLFSSL_HAVE_KYBER
#define HAVE_PQC
#endif
/* Enable Post-Quantum Cryptography if we have liboqs from the OpenQuantumSafe
* group */
#ifdef HAVE_LIBOQS
@@ -2737,7 +2741,8 @@ extern void uITRON4_free(void *p) ;
#define HAVE_KYBER
#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.
#endif

View File

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