mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 20:54:41 +02:00
wolfCrypt support for external Kyber implementations (liboqs and pqm4)
This commit is contained in:
134
configure.ac
134
configure.ac
@@ -963,6 +963,53 @@ 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
|
# KYBER
|
||||||
# Used:
|
# Used:
|
||||||
# - SHA3, Shake128 and Shake256, or
|
# - SHA3, Shake128 and Shake256, or
|
||||||
@@ -1013,24 +1060,33 @@ done
|
|||||||
if test "$ENABLED_KYBER" != "no"
|
if test "$ENABLED_KYBER" != "no"
|
||||||
then
|
then
|
||||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_KYBER"
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_KYBER"
|
||||||
if test "$ENABLED_KYBER512" = ""; then
|
if test "$ENABLED_WC_KYBER" = "yes"
|
||||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER512"
|
then
|
||||||
fi
|
if test "$ENABLED_KYBER512" = ""; then
|
||||||
if test "$ENABLED_KYBER768" = ""; then
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER512"
|
||||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER768"
|
fi
|
||||||
fi
|
if test "$ENABLED_KYBER768" = ""; then
|
||||||
if test "$ENABLED_KYBER1024" = ""; then
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER768"
|
||||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER1024"
|
fi
|
||||||
fi
|
if test "$ENABLED_KYBER1024" = ""; then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_KYBER1024"
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$ENABLED_KYBER_90S" != "yes"; then
|
if test "$ENABLED_KYBER_90S" != "yes"; then
|
||||||
test "$enable_sha3" = "" && enable_sha3=yes
|
test "$enable_sha3" = "" && enable_sha3=yes
|
||||||
test "$enable_shake128" = "" && enable_shake128=yes
|
test "$enable_shake128" = "" && enable_shake128=yes
|
||||||
test "$enable_shake256" = "" && enable_shake256=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
|
else
|
||||||
test "$enable_sha256" = "" && enable_sha256=yes
|
# Default is to use liboqs. Make sure its enabled.
|
||||||
test "$enable_sha512" = "" && enable_sha512=yes
|
if test "$ENABLED_LIBOQS" = "no"; then
|
||||||
test "$enable_aesctr" = "" && enable_aesctr=yes
|
AC_MSG_ERROR([The default implementation for kyber is liboqs.
|
||||||
|
Please use --with-liboqs.])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4604,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=""
|
||||||
|
@@ -687,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
|
||||||
|
18
src/tls.c
18
src/tls.c
@@ -53,15 +53,17 @@
|
|||||||
#include <wolfssl/wolfcrypt/kyber.h>
|
#include <wolfssl/wolfcrypt/kyber.h>
|
||||||
#ifdef WOLFSSL_WC_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#include <wolfssl/wolfcrypt/wc_kyber.h>
|
#include <wolfssl/wolfcrypt/wc_kyber.h>
|
||||||
#endif
|
|
||||||
#elif defined(HAVE_LIBOQS)
|
#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
|
||||||
|
|
||||||
@@ -7058,7 +7060,7 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
static int kyber_id2type(int id, int *type)
|
static int kyber_id2type(int id, int *type)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -7183,7 +7185,7 @@ 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 WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -8084,7 +8086,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
/* Process the Kyber key share extension on the client side.
|
/* Process the Kyber key share extension on the client side.
|
||||||
*
|
*
|
||||||
* ssl The SSL/TLS object.
|
* ssl The SSL/TLS object.
|
||||||
@@ -8881,7 +8883,7 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
|
static int server_generate_pqc_ciphertext(WOLFSSL* ssl,
|
||||||
KeyShareEntry* keyShareEntry, byte* data, word16 len)
|
KeyShareEntry* keyShareEntry, byte* data, word16 len)
|
||||||
{
|
{
|
||||||
@@ -9534,7 +9536,7 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#ifdef WOLFSSL_KYBER512
|
#ifdef WOLFSSL_KYBER512
|
||||||
case WOLFSSL_KYBER_LEVEL1:
|
case WOLFSSL_KYBER_LEVEL1:
|
||||||
#endif
|
#endif
|
||||||
@@ -9651,7 +9653,7 @@ 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_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#ifdef WOLFSSL_KYBER512
|
#ifdef WOLFSSL_KYBER512
|
||||||
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;
|
||||||
@@ -11733,7 +11735,7 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PQC
|
#ifdef HAVE_PQC
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#ifdef WOLFSSL_KYBER512
|
#ifdef WOLFSSL_KYBER512
|
||||||
if (ret == WOLFSSL_SUCCESS)
|
if (ret == WOLFSSL_SUCCESS)
|
||||||
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
|
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
|
||||||
|
@@ -269,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)
|
||||||
@@ -290,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>
|
||||||
|
676
wolfcrypt/src/ext_kyber.c
Normal file
676
wolfcrypt/src/ext_kyber.c
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@@ -271,6 +271,9 @@
|
|||||||
#ifdef WOLFSSL_WC_KYBER
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#include <wolfssl/wolfcrypt/wc_kyber.h>
|
#include <wolfssl/wolfcrypt/wc_kyber.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_LIBOQS) || defined(HAVE_PQM4)
|
||||||
|
#include <wolfssl/wolfcrypt/ext_kyber.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFCRYPT_HAVE_ECCSI
|
#ifdef WOLFCRYPT_HAVE_ECCSI
|
||||||
#include <wolfssl/wolfcrypt/eccsi.h>
|
#include <wolfssl/wolfcrypt/eccsi.h>
|
||||||
@@ -29855,6 +29858,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
|
|||||||
#endif /* HAVE_ED448 */
|
#endif /* HAVE_ED448 */
|
||||||
|
|
||||||
#ifdef WOLFSSL_HAVE_KYBER
|
#ifdef WOLFSSL_HAVE_KYBER
|
||||||
|
#ifdef WOLFSSL_WC_KYBER /* OQS and PQM4 do not support KATs */
|
||||||
#ifdef WOLFSSL_KYBER512
|
#ifdef WOLFSSL_KYBER512
|
||||||
static int kyber512_kat(void)
|
static int kyber512_kat(void)
|
||||||
{
|
{
|
||||||
@@ -33701,6 +33705,7 @@ static int kyber1024_kat(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_KYBER1024 */
|
#endif /* WOLFSSL_KYBER1024 */
|
||||||
|
#endif /* WOLFSSL_WC_KYBER */
|
||||||
|
|
||||||
WOLFSSL_TEST_SUBROUTINE int kyber_test(void)
|
WOLFSSL_TEST_SUBROUTINE int kyber_test(void)
|
||||||
{
|
{
|
||||||
@@ -33801,6 +33806,7 @@ WOLFSSL_TEST_SUBROUTINE int kyber_test(void)
|
|||||||
|
|
||||||
wc_FreeRng(&rng);
|
wc_FreeRng(&rng);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_WC_KYBER
|
||||||
#ifdef WOLFSSL_KYBER512
|
#ifdef WOLFSSL_KYBER512
|
||||||
ret = kyber512_kat();
|
ret = kyber512_kat();
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
@@ -33816,6 +33822,7 @@ WOLFSSL_TEST_SUBROUTINE int kyber_test(void)
|
|||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* WOLFSSL_WC_KYBER */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
62
wolfssl/wolfcrypt/ext_kyber.h
Normal file
62
wolfssl/wolfcrypt/ext_kyber.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
@@ -73,7 +73,8 @@ nobase_include_HEADERS+= \
|
|||||||
wolfssl/wolfcrypt/cpuid.h \
|
wolfssl/wolfcrypt/cpuid.h \
|
||||||
wolfssl/wolfcrypt/cryptocb.h \
|
wolfssl/wolfcrypt/cryptocb.h \
|
||||||
wolfssl/wolfcrypt/kyber.h \
|
wolfssl/wolfcrypt/kyber.h \
|
||||||
wolfssl/wolfcrypt/wc_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 \
|
||||||
|
Reference in New Issue
Block a user