forked from wolfSSL/wolfssl
Merge pull request #4856 from anhu/stm32u5
Enable support for STM32U585 and PQC for STM32
This commit is contained in:
@ -128,7 +128,7 @@ extern ${variable.value} ${variable.name};
|
||||
#define HAL_CONSOLE_UART huart2
|
||||
#define NO_STM32_RNG
|
||||
#define WOLFSSL_GENSEED_FORTEST
|
||||
#elif defined(STM32U575xx)
|
||||
#elif defined(STM32U575xx) || defined(STM32U585xx)
|
||||
#define HAL_CONSOLE_UART huart1
|
||||
#define WOLFSSL_STM32U5
|
||||
#define STM32_HAL_V2
|
||||
@ -275,6 +275,14 @@ extern ${variable.value} ${variable.name};
|
||||
#define NO_SESSION_CACHE
|
||||
#endif
|
||||
|
||||
/* Post Quantum
|
||||
* Note: PQM4 is compatible with STM32. The project can be found at:
|
||||
* https://github.com/mupq/pqm4
|
||||
*/
|
||||
#if defined(WOLF_CONF_PQM4) && WOLF_CONF_PQM4 == 1
|
||||
#define HAVE_PQM4
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Crypto */
|
||||
|
@ -105,7 +105,8 @@
|
||||
#endif /* WOLFSSL_STATIC_MEMORY */
|
||||
|
||||
|
||||
/* UART definitions */
|
||||
/* This sets which UART to use for the console. It is something you will have
|
||||
* to configure in STMCubeIDE and then change here. */
|
||||
#ifndef HAL_CONSOLE_UART
|
||||
#define HAL_CONSOLE_UART huart4
|
||||
#endif
|
||||
@ -121,10 +122,12 @@ typedef struct func_args {
|
||||
} func_args;
|
||||
|
||||
const char menu1[] = "\n"
|
||||
"\tt. WolfCrypt Test\n"
|
||||
"\tb. WolfCrypt Benchmark\n"
|
||||
"\tl. WolfSSL TLS Bench\n"
|
||||
"\te. Show Cipher List\n";
|
||||
"\tt. wolfCrypt Test\n"
|
||||
"\tb. wolfCrypt Benchmark\n"
|
||||
"\tl. wolfSSL TLS Bench\n"
|
||||
"\te. Show Cipher List\n"
|
||||
"\ts. Run TLS 1.3 Server over UART\n"
|
||||
"\tc. Run TLS 1.3 Client over UART\n";
|
||||
|
||||
static void PrintMemStats(void);
|
||||
double current_time(void);
|
||||
@ -1468,25 +1471,304 @@ static void PrintMemStats(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void* wolfMallocCb(size_t size)
|
||||
{
|
||||
void* ptr = malloc(size);
|
||||
if (ptr == NULL) {
|
||||
printf("BREAK!\n");
|
||||
}
|
||||
return ptr;
|
||||
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_TLS13) && !defined(NO_TLS_UART_TEST)
|
||||
/* UART DMA IO Routines */
|
||||
#ifndef B115200
|
||||
#define B115200 115200
|
||||
#endif
|
||||
|
||||
/* Max buffer for a single TLS frame */
|
||||
#ifndef MAX_RECORD_SIZE
|
||||
#define MAX_RECORD_SIZE (16 * 1024)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int curr_index;
|
||||
int data_len;
|
||||
char buf[MAX_RECORD_SIZE];
|
||||
} tls13_buf;
|
||||
|
||||
/* This sets which UART to do the TLS 1.3 connection over. It is something you
|
||||
* will have to configure in STMCubeIDE and then change here. */
|
||||
#ifndef TLS_UART
|
||||
#define TLS_UART huart2
|
||||
#endif
|
||||
extern UART_HandleTypeDef TLS_UART;
|
||||
|
||||
static int msg_length = 0;
|
||||
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
|
||||
if (huart->Instance == TLS_UART.Instance) {
|
||||
msg_length = Size;
|
||||
}
|
||||
}
|
||||
static void wolfFreeCb(void *ptr)
|
||||
|
||||
static int uartIORx(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||
{
|
||||
free(ptr);
|
||||
HAL_StatusTypeDef status;
|
||||
tls13_buf *tb = ctx;
|
||||
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("UART Read: In %d\n", sz);
|
||||
#endif
|
||||
|
||||
if (tb->curr_index + sz <= tb->data_len) {
|
||||
XMEMCPY(buf, tb->buf + tb->curr_index, sz);
|
||||
tb->curr_index += sz;
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("UART Read1: Out %d\n", sz);
|
||||
#endif
|
||||
return sz;
|
||||
}
|
||||
|
||||
msg_length = 0;
|
||||
XMEMSET(tb, 0, sizeof(*tb));
|
||||
|
||||
/* Now setup the DMA RX. */
|
||||
status = HAL_UARTEx_ReceiveToIdle_DMA(&TLS_UART, (uint8_t *)tb->buf, MAX_RECORD_SIZE);
|
||||
if (status != HAL_OK) {
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
} else {
|
||||
/* We now go into an infinite loop waiting for msg_length to be set to a
|
||||
* value other than 0. This will be done when the other side writes to
|
||||
* UART and then idles. That will trigger HAL_UARTEx_RxEventCallback()
|
||||
* which will set msg_length to the length of data written.
|
||||
*
|
||||
* If you mistakenly get stuck here, please simply reset the board.
|
||||
*/
|
||||
while(msg_length == 0) {
|
||||
HAL_Delay(10);
|
||||
}
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("Message received! length = %d\n", msg_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* now return the number of bytes requested. */
|
||||
XMEMCPY(buf, tb->buf, sz);
|
||||
tb->data_len = msg_length;
|
||||
tb->curr_index = sz;
|
||||
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("UART Read2: Out %d\n", tb->data_len);
|
||||
#endif
|
||||
|
||||
return sz;
|
||||
}
|
||||
static void* wolfReallocCb(void *ptr, size_t size)
|
||||
|
||||
static int uartIOTx(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
HAL_StatusTypeDef status;
|
||||
int ret = sz;
|
||||
(void)ctx;
|
||||
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("UART Write: In %d\n", sz);
|
||||
#endif
|
||||
|
||||
status = HAL_UART_Transmit(&TLS_UART, (uint8_t *)buf, sz, 0xFFFF);
|
||||
if (status != HAL_OK) {
|
||||
ret = WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UART_IO
|
||||
printf("UART Write: Out %d\n", ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* UART TLS 1.3 client and server */
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
static int tls13_uart_server(void)
|
||||
{
|
||||
int ret = -1, err;
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
byte echoBuffer[100];
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
tls13_buf *tbuf = (tls13_buf *) XMALLOC(sizeof(*tbuf), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (tbuf == NULL) {
|
||||
printf("Memory allocation error\n");
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
tls13_buf tbuf[1];
|
||||
#endif
|
||||
|
||||
XMEMSET(tbuf, 0, sizeof(*tbuf));
|
||||
|
||||
ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
|
||||
if (ctx == NULL) {
|
||||
printf("Error creating WOLFSSL_CTX\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Register wolfSSL send/recv callbacks */
|
||||
wolfSSL_CTX_SetIOSend(ctx, uartIOTx);
|
||||
wolfSSL_CTX_SetIORecv(ctx, uartIORx);
|
||||
|
||||
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_key_der_256,
|
||||
sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("error loading server private key\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wolfSSL_CTX_use_certificate_buffer(ctx, serv_ecc_der_256,
|
||||
sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("error loading server certificate\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
printf("Error creating WOLFSSL\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
wolfSSL_SetIOReadCtx(ssl, tbuf);
|
||||
|
||||
printf("Waiting for client\n");
|
||||
do {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("TLS accept error %d\n", err);
|
||||
goto done;
|
||||
}
|
||||
printf("TLS Accept handshake done\n");
|
||||
|
||||
/* Waiting for data to echo */
|
||||
XMEMSET(echoBuffer, 0, sizeof(echoBuffer));
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, echoBuffer, sizeof(echoBuffer)-1);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
printf("Read (%d): %s\n", err, echoBuffer);
|
||||
|
||||
do {
|
||||
ret = wolfSSL_write(ssl, echoBuffer, XSTRLEN((char*)echoBuffer));
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
printf("Sent (%d): %s\n", err, echoBuffer);
|
||||
|
||||
ret = 0; /* Success */
|
||||
|
||||
done:
|
||||
if (ssl) {
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
}
|
||||
if (ctx) {
|
||||
wolfSSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (tbuf != NULL) {
|
||||
XFREE(tbuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
static int tls13_uart_client(void)
|
||||
{
|
||||
int ret = -1, err;
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
const char testStr[] = "Testing 1, 2 and 3\r\n";
|
||||
byte readBuf[100];
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
tls13_buf *tbuf = (tls13_buf *) XMALLOC(sizeof(*tbuf), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (tbuf == NULL) {
|
||||
printf("Memory allocation error\n");
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
tls13_buf tbuf[1];
|
||||
#endif
|
||||
|
||||
XMEMSET(tbuf, 0, sizeof(*tbuf));
|
||||
|
||||
ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
|
||||
if (ctx == NULL) {
|
||||
printf("Error creating WOLFSSL_CTX\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Register wolfSSL send/recv callbacks */
|
||||
wolfSSL_CTX_SetIOSend(ctx, uartIOTx);
|
||||
wolfSSL_CTX_SetIORecv(ctx, uartIORx);
|
||||
|
||||
/* Load the root certificate. */
|
||||
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
printf("Error creating WOLFSSL\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
wolfSSL_SetIOReadCtx(ssl, tbuf);
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_KYBER_LEVEL1) != WOLFSSL_SUCCESS) {
|
||||
printf("wolfSSL_UseKeyShare Error!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("TLS connect error %d\n", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
printf("TLS Connect handshake done\n");
|
||||
printf("Sending test string\n");
|
||||
do {
|
||||
ret = wolfSSL_write(ssl, testStr, XSTRLEN(testStr));
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
printf("Sent (%d): %s\n", err, testStr);
|
||||
|
||||
XMEMSET(readBuf, 0, sizeof(readBuf));
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, readBuf, sizeof(readBuf)-1);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
printf("Read (%d): %s\n", err, readBuf);
|
||||
|
||||
ret = 0; /* Success */
|
||||
|
||||
done:
|
||||
if (ssl) {
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
}
|
||||
if (ctx) {
|
||||
wolfSSL_CTX_free(ctx);
|
||||
}
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (tbuf != NULL) {
|
||||
XFREE(tbuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif /* !WOLFCRYPT_ONLY && WOLFSSL_TLS13 && !NO_TLS_UART_TEST */
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
@ -1596,7 +1878,27 @@ void wolfCryptDemo(const void* argument)
|
||||
printf("Not compiled in\n");
|
||||
#endif
|
||||
break;
|
||||
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_TLS13) && !defined(NO_TLS_UART_TEST)
|
||||
case 's':
|
||||
#if !defined(NO_WOLFSSL_SERVER)
|
||||
printf("Running TLS 1.3 server...\n");
|
||||
args.return_code = tls13_uart_server();
|
||||
#else
|
||||
args.return_code = NOT_COMPILED_IN;
|
||||
#endif
|
||||
printf("TLS 1.3 Server: Return code %d\n", args.return_code);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
#if !defined(NO_WOLFSSL_CLIENT)
|
||||
printf("Running TLS 1.3 client...\n");
|
||||
args.return_code = tls13_uart_client();
|
||||
#else
|
||||
args.return_code = NOT_COMPILED_IN;
|
||||
#endif
|
||||
printf("TLS 1.3 Client: Return code %d\n", args.return_code);
|
||||
break;
|
||||
#endif
|
||||
// All other cases go here
|
||||
default:
|
||||
printf("\nSelection out of range\n");
|
||||
|
@ -6734,11 +6734,11 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
|
||||
wc_curve448_free((curve448_key*)*pKey);
|
||||
break;
|
||||
#endif /* HAVE_CURVE448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case DYNAMIC_TYPE_FALCON:
|
||||
wc_falcon_free((falcon_key*)*pKey);
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
#ifndef NO_DH
|
||||
case DYNAMIC_TYPE_DH:
|
||||
wc_FreeDhKey((DhKey*)*pKey);
|
||||
@ -6801,7 +6801,7 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
|
||||
sz = sizeof(curve448_key);
|
||||
break;
|
||||
#endif /* HAVE_CURVE448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case DYNAMIC_TYPE_FALCON:
|
||||
sz = sizeof(falcon_key);
|
||||
break;
|
||||
@ -6851,7 +6851,7 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
|
||||
ret = 0;
|
||||
break;
|
||||
#endif /* HAVE_CURVE448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case DYNAMIC_TYPE_FALCON:
|
||||
wc_falcon_init((falcon_key*)*pKey);
|
||||
ret = 0;
|
||||
@ -6882,7 +6882,7 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
|
||||
|
||||
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
|
||||
defined(HAVE_CURVE25519) || defined(HAVE_ED448) || \
|
||||
defined(HAVE_CURVE448) || defined(HAVE_PQC)
|
||||
defined(HAVE_CURVE448) || (defined(HAVE_PQC) && defined(HAVE_FALCON))
|
||||
static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -6928,12 +6928,12 @@ static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
|
||||
ret = wc_curve448_init((curve448_key*)pKey);
|
||||
break;
|
||||
#endif /* HAVE_CURVE448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case DYNAMIC_TYPE_FALCON:
|
||||
wc_falcon_free((falcon_key*)pKey);
|
||||
ret = wc_falcon_init((falcon_key*)pKey);
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
#ifndef NO_DH
|
||||
case DYNAMIC_TYPE_DH:
|
||||
wc_FreeDhKey((DhKey*)pKey);
|
||||
@ -11843,7 +11843,7 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args)
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_ED448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
if (ssl->options.minFalconKeySz < 0 ||
|
||||
FALCON_LEVEL1_KEY_SIZE < (word16)ssl->options.minFalconKeySz) {
|
||||
@ -11860,7 +11860,7 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args)
|
||||
ret = FALCON_KEY_SIZE_E;
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
default:
|
||||
WOLFSSL_MSG("Key size not checked");
|
||||
/* key not being checked for size if not in
|
||||
@ -13075,7 +13075,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
case FALCON_LEVEL5k:
|
||||
{
|
||||
@ -13120,7 +13120,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
WOLFSSL_MSG("Peer Falcon key is too small");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -22624,7 +22624,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if (ssl->buffers.keyType == falcon_level1_sa_algo ||
|
||||
ssl->buffers.keyType == falcon_level5_sa_algo ||
|
||||
ssl->buffers.keyType == 0) {
|
||||
@ -22684,7 +22684,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
|
||||
goto exit_dpk;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
(void)idx;
|
||||
(void)keySz;
|
||||
|
12
src/ssl.c
12
src/ssl.c
@ -5068,7 +5068,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_ED448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
if (cm->minFalconKeySz < 0 ||
|
||||
FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
|
||||
@ -5083,7 +5083,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
||||
WOLFSSL_MSG("\tCA Falcon level 5 key size error");
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("\tNo key size check done on CA");
|
||||
@ -5944,7 +5944,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
|
||||
(*keyFormat == FALCON_LEVEL5k))) {
|
||||
/* make sure Falcon key can be used */
|
||||
@ -6010,7 +6010,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6530,7 +6530,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_ED448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
case FALCON_LEVEL5k:
|
||||
/* Falcon is fixed key size */
|
||||
@ -6550,7 +6550,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("No key size check done on certificate");
|
||||
|
389
src/tls.c
389
src/tls.c
@ -51,6 +51,12 @@
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
#include <oqs/kem.h>
|
||||
#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
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -120,7 +126,6 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
|
||||
#define HSHASH_SZ FINISHED_SZ
|
||||
#endif
|
||||
|
||||
|
||||
int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -6891,7 +6896,6 @@ static void findEccPqc(int *ecc, int *pqc, int group)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBOQS
|
||||
/* Create a key share entry using liboqs parameters group.
|
||||
* Generates a key pair.
|
||||
*
|
||||
@ -6899,7 +6903,8 @@ static void findEccPqc(int *ecc, int *pqc, int group)
|
||||
* kse The key share entry object.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int TLSX_KeyShare_GenOqsKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
#ifdef HAVE_LIBOQS
|
||||
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
{
|
||||
int ret = 0;
|
||||
const char* algName = NULL;
|
||||
@ -7000,7 +7005,94 @@ static int TLSX_KeyShare_GenOqsKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_LIBOQS */
|
||||
#elif defined(HAVE_PQM4)
|
||||
static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
{
|
||||
/* This assumes KYBER LEVEL 1 (512) implementation is compiled in. */
|
||||
int ret = 0;
|
||||
byte* pubKey = NULL;
|
||||
byte* privKey = NULL;
|
||||
KeyShareEntry *ecc_kse = NULL;
|
||||
int oqs_group = 0;
|
||||
int ecc_group = 0;
|
||||
|
||||
findEccPqc(&ecc_group, &oqs_group, kse->group);
|
||||
|
||||
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 fail, no error message, TLSX_KeyShare_GenEccKey will do it. */
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + PQM4_PUBLIC_KEY_LENGTH,
|
||||
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (pubKey == NULL) {
|
||||
WOLFSSL_MSG("pubkey memory allocation failure");
|
||||
ret = MEMORY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
privKey = (byte*)XMALLOC(PQM4_PRIVATE_KEY_LENGTH,
|
||||
ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (privKey == NULL) {
|
||||
WOLFSSL_MSG("privkey memory allocation failure");
|
||||
ret = MEMORY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (crypto_kem_keypair(pubKey + ecc_kse->pubKeyLen, privKey) == 0) {
|
||||
XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
|
||||
kse->pubKey = pubKey;
|
||||
kse->pubKeyLen = ecc_kse->pubKeyLen +
|
||||
(word32) PQM4_PUBLIC_KEY_LENGTH;
|
||||
pubKey = NULL;
|
||||
|
||||
/* Note we are saving the PQ 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;
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("liboqs keygen failure");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Public PQM4 Key");
|
||||
WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
#endif /* HAVE_PQM4 */
|
||||
#endif /* HAVE_PQC */
|
||||
|
||||
/* Generate a secret/key using the key share entry.
|
||||
@ -7019,10 +7111,8 @@ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
|
||||
else if (kse->group == WOLFSSL_ECC_X448)
|
||||
ret = TLSX_KeyShare_GenX448Key(ssl, kse);
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
else if (kse->group >= WOLFSSL_PQC_MIN && kse->group <= WOLFSSL_PQC_MAX)
|
||||
ret = TLSX_KeyShare_GenOqsKey(ssl, kse);
|
||||
#endif
|
||||
ret = TLSX_KeyShare_GenPqcKey(ssl, kse);
|
||||
#endif
|
||||
else
|
||||
ret = TLSX_KeyShare_GenEccKey(ssl, kse);
|
||||
@ -7589,7 +7679,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
* keyShareEntry The key share entry object to use to calculate shared secret.
|
||||
* returns 0 on success and other values indicate failure.
|
||||
*/
|
||||
static int TLSX_KeyShare_ProcessOqs(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
{
|
||||
int ret = 0;
|
||||
const char* algName = NULL;
|
||||
@ -7732,8 +7822,138 @@ static int TLSX_KeyShare_ProcessOqs(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
OQS_KEM_free(kem);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_PQM4)
|
||||
static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
{
|
||||
int ret = 0;
|
||||
byte* sharedSecret = NULL;
|
||||
word32 sharedSecretLen = 0;
|
||||
int oqs_group = 0;
|
||||
int ecc_group = 0;
|
||||
ecc_key eccpubkey;
|
||||
word32 outlen = 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);
|
||||
|
||||
sharedSecretLen = (word32)PQM4_SHARED_SECRET_LENGTH;
|
||||
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.");
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap,
|
||||
DYNAMIC_TYPE_TLSX);
|
||||
if (sharedSecret == NULL) {
|
||||
WOLFSSL_MSG("Memory allocation error.");
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == 0 && crypto_kem_dec(sharedSecret + outlen,
|
||||
keyShareEntry->ke + keyShareEntry->keLen -
|
||||
PQM4_CIPHERTEXT_LENGTH,
|
||||
keyShareEntry->privKey) != 0) {
|
||||
WOLFSSL_MSG("PQM4 decapsulation failure.");
|
||||
ret = BAD_FUNC_ARG;
|
||||
} else {
|
||||
WOLFSSL_MSG("PQM4 decapsulation SUCCESS!!!!!");
|
||||
}
|
||||
|
||||
if (ecc_group != 0) {
|
||||
if (ret == 0) {
|
||||
/* Point is validated by import function. */
|
||||
ret = wc_ecc_import_x963(keyShareEntry->ke,
|
||||
keyShareEntry->keLen -
|
||||
(word32)PQM4_CIPHERTEXT_LENGTH,
|
||||
&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
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
ret = wc_ecc_shared_secret(keyShareEntry->key, &eccpubkey, sharedSecret, &outlen);
|
||||
PRIVATE_KEY_LOCK();
|
||||
if (outlen != sharedSecretLen - PQM4_SHARED_SECRET_LENGTH) {
|
||||
WOLFSSL_MSG("ECC shared secret derivation error.");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sharedSecretLen > ENCRYPT_LEN) {
|
||||
WOLFSSL_MSG("shared secret is too long.\n");
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_PQM4 */
|
||||
#endif /* HAVE_PQC */
|
||||
|
||||
/* Process the key share extension on the client side.
|
||||
*
|
||||
@ -7761,11 +7981,9 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
|
||||
else if (keyShareEntry->group == WOLFSSL_ECC_X448)
|
||||
ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
else if (keyShareEntry->group >= WOLFSSL_PQC_MIN &&
|
||||
keyShareEntry->group <= WOLFSSL_PQC_MAX)
|
||||
ret = TLSX_KeyShare_ProcessOqs(ssl, keyShareEntry);
|
||||
#endif
|
||||
ret = TLSX_KeyShare_ProcessPqc(ssl, keyShareEntry);
|
||||
#endif
|
||||
else
|
||||
ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
|
||||
@ -8071,7 +8289,7 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
static int server_generate_oqs_ciphertext(WOLFSSL* ssl,
|
||||
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
|
||||
@ -8215,8 +8433,134 @@ static int server_generate_oqs_ciphertext(WOLFSSL* ssl,
|
||||
OQS_KEM_free(kem);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_PQM4)
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group);
|
||||
ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Could not do ECC public key initialization.");
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
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 && len != PQM4_PUBLIC_KEY_LENGTH + ecc_kse->pubKeyLen) {
|
||||
WOLFSSL_MSG("Invalid public key.");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen + PQM4_SHARED_SECRET_LENGTH,
|
||||
ssl->heap, DYNAMIC_TYPE_TLSX);
|
||||
ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + PQM4_CIPHERTEXT_LENGTH,
|
||||
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 - PQM4_PUBLIC_KEY_LENGTH,
|
||||
&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
|
||||
#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 &&
|
||||
crypto_kem_enc(ciphertext + ecc_kse->pubKeyLen,
|
||||
sharedSecret + outlen,
|
||||
data + ecc_kse->pubKeyLen) != 0) {
|
||||
WOLFSSL_MSG("PQM4 Encapsulation failure.");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (keyShareEntry->ke != NULL) {
|
||||
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
}
|
||||
|
||||
keyShareEntry->ke = sharedSecret;
|
||||
keyShareEntry->keLen = outlen + (word32)PQM4_SHARED_SECRET_LENGTH;
|
||||
sharedSecret = NULL;
|
||||
|
||||
XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
|
||||
keyShareEntry->pubKey = ciphertext;
|
||||
keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen +
|
||||
PQM4_CIPHERTEXT_LENGTH);
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_PQM4 */
|
||||
#endif /* HAVE_PQC */
|
||||
|
||||
/* Use the data to create a new key share object in the extensions.
|
||||
*
|
||||
@ -8266,17 +8610,15 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
|
||||
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
if (group >= WOLFSSL_PQC_MIN &&
|
||||
group <= WOLFSSL_PQC_MAX &&
|
||||
ssl->options.side == WOLFSSL_SERVER_END) {
|
||||
ret = server_generate_oqs_ciphertext(ssl, keyShareEntry, data,
|
||||
ret = server_generate_pqc_ciphertext(ssl, keyShareEntry, data,
|
||||
len);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
if (data != NULL) {
|
||||
if (keyShareEntry->ke != NULL) {
|
||||
@ -8429,6 +8771,7 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_PQC
|
||||
#ifdef HAVE_LIBOQS
|
||||
case WOLFSSL_KYBER_LEVEL1:
|
||||
case WOLFSSL_KYBER_LEVEL3:
|
||||
case WOLFSSL_KYBER_LEVEL5:
|
||||
@ -8455,14 +8798,16 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
|
||||
case WOLFSSL_P256_KYBER_90S_LEVEL1:
|
||||
case WOLFSSL_P384_KYBER_90S_LEVEL3:
|
||||
case WOLFSSL_P521_KYBER_90S_LEVEL5:
|
||||
#ifdef HAVE_LIBOQS
|
||||
findEccPqc(NULL, &namedGroup, namedGroup);
|
||||
if (! OQS_KEM_alg_is_enabled(OQS_ID2name(namedGroup))) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#elif defined(HAVE_PQM4)
|
||||
case WOLFSSL_KYBER_LEVEL1:
|
||||
break;
|
||||
#endif
|
||||
#endif /* HAVE_PQC */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -8534,6 +8879,7 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
|
||||
*/
|
||||
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))
|
||||
@ -8584,7 +8930,8 @@ 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;
|
||||
#endif
|
||||
#endif /* HAVE_LIBOQS */
|
||||
#endif /* HAVE_PQC */
|
||||
}
|
||||
|
||||
for (i = 0; i < ssl->numGroups; i++)
|
||||
@ -10424,6 +10771,7 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
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);
|
||||
@ -10500,6 +10848,7 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
|
||||
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_90S_LEVEL5,
|
||||
ssl->heap);
|
||||
|
||||
#endif /* HAVE_LIBOQS */
|
||||
#endif /* HAVE_PQC */
|
||||
|
||||
(void)ssl;
|
||||
|
14
src/tls13.c
14
src/tls13.c
@ -6137,7 +6137,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
|
||||
else if (ssl->hsType == DYNAMIC_TYPE_ED448)
|
||||
args->sigAlgo = ed448_sa_algo;
|
||||
#endif
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
else if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
|
||||
falcon_key* fkey = (falcon_key*)ssl->hsKey;
|
||||
byte level = 0;
|
||||
@ -6231,11 +6231,11 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
|
||||
sig->length = ED448_SIG_SIZE;
|
||||
}
|
||||
#endif /* HAVE_ED448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
|
||||
sig->length = FALCON_MAX_SIG_SIZE;
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_DO;
|
||||
@ -6287,7 +6287,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
|
||||
args->length = (word16)sig->length;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
|
||||
ret = wc_falcon_sign_msg(args->sigData, args->sigDataSz,
|
||||
args->verify + HASH_SIG_SIZE +
|
||||
@ -6295,7 +6295,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
|
||||
(falcon_key*)ssl->hsKey);
|
||||
args->length = (word16)sig->length;
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
#ifndef NO_RSA
|
||||
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
|
||||
ret = RsaSign(ssl, sig->buffer, (word32)sig->length,
|
||||
@ -6787,7 +6787,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if (ssl->peerFalconKeyPresent) {
|
||||
int res = 0;
|
||||
WOLFSSL_MSG("Doing Falcon peer cert verify");
|
||||
@ -6801,7 +6801,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
|
||||
ssl->peerFalconKeyPresent = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
/* Check for error */
|
||||
if (ret != 0) {
|
||||
|
@ -245,7 +245,7 @@
|
||||
#ifdef HAVE_LIBOQS
|
||||
#include <oqs/kem.h>
|
||||
#endif
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
#include <wolfssl/wolfcrypt/falcon.h>
|
||||
#endif
|
||||
|
||||
@ -1617,7 +1617,7 @@ static void bench_stats_asym_finish(const char* algo, int strength,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
|
||||
static void bench_stats_pq_asym_finish(const char* algo, int doAsync, int count,
|
||||
double start, int ret)
|
||||
{
|
||||
@ -2276,7 +2276,7 @@ static void* benchmarks_do(void* args)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
|
||||
if (bench_all || (bench_pq_asym_algs & BENCH_FALCON_LEVEL1_SIGN))
|
||||
bench_falconKeySign(1);
|
||||
if (bench_all || (bench_pq_asym_algs & BENCH_FALCON_LEVEL5_SIGN))
|
||||
@ -6905,7 +6905,7 @@ void bench_sakke(void)
|
||||
#endif /* WOLFCRYPT_SAKKE_CLIENT */
|
||||
#endif /* WOLFCRYPT_HAVE_SAKKE */
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
|
||||
static void bench_pqcKemInit(word32 alg, byte **priv_key, byte **pub_key,
|
||||
const char **wolf_name, OQS_KEM **kem)
|
||||
{
|
||||
@ -7155,7 +7155,7 @@ void bench_falconKeySign(byte level)
|
||||
|
||||
wc_falcon_free(&key);
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_LIBOQS */
|
||||
|
||||
#ifndef HAVE_STACK_SIZE
|
||||
#if defined(_WIN32) && !defined(INTIME_RTOS)
|
||||
|
@ -6266,7 +6266,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
falcon_key* key_pair = NULL;
|
||||
@ -6319,7 +6319,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
@ -13280,7 +13280,7 @@ void FreeSignatureCtx(SignatureCtx* sigCtx)
|
||||
sigCtx->key.ed448 = NULL;
|
||||
break;
|
||||
#endif /* HAVE_ED448 */
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
case FALCON_LEVEL5k:
|
||||
wc_falcon_free(sigCtx->key.falcon);
|
||||
@ -13288,7 +13288,7 @@ void FreeSignatureCtx(SignatureCtx* sigCtx)
|
||||
DYNAMIC_TYPE_FALCON);
|
||||
sigCtx->key.falcon = NULL;
|
||||
break;
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
default:
|
||||
break;
|
||||
} /* switch (keyOID) */
|
||||
@ -13732,7 +13732,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
{
|
||||
sigCtx->verify = 0;
|
||||
@ -13781,7 +13781,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
default:
|
||||
WOLFSSL_MSG("Verify Key type unknown");
|
||||
ret = ASN_UNKNOWN_OID_E;
|
||||
@ -13883,7 +13883,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
case FALCON_LEVEL1k:
|
||||
case FALCON_LEVEL5k:
|
||||
{
|
||||
@ -21604,7 +21604,7 @@ int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
|
||||
}
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
|
||||
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
/* Encode the public part of an Falcon key in DER.
|
||||
*
|
||||
* Pass NULL for output to get the size of the encoding.
|
||||
@ -21647,7 +21647,7 @@ int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output, word32 inLen,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
@ -28627,6 +28627,12 @@ enum {
|
||||
#define edKeyASN_Length (sizeof(edKeyASN) / sizeof(ASNItem))
|
||||
#endif
|
||||
|
||||
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \
|
||||
|| (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \
|
||||
|| (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
|
||||
|| (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
|
||||
|| (defined(HAVE_PQC) && defined(HAVE_FALCON)))
|
||||
|
||||
static int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
|
||||
byte* privKey, word32* privKeyLen,
|
||||
byte* pubKey, word32* pubKeyLen, int keyType)
|
||||
@ -28858,6 +28864,7 @@ static int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz,
|
||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif /* WC_ENABLE_ASYM_KEY_IMPORT */
|
||||
|
||||
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
|
||||
@ -29194,7 +29201,7 @@ int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
|
||||
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||
falcon_key* key, word32 inSz)
|
||||
{
|
||||
@ -29261,7 +29268,7 @@ int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
|
||||
int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||
@ -29328,7 +29335,7 @@ int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
|
||||
|
||||
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
|
||||
|
||||
#if defined(HAVE_PQC)
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
int wc_Falcon_KeyToDer(falcon_key* key, byte* output, word32 inLen)
|
||||
{
|
||||
if (key == NULL) {
|
||||
@ -29367,7 +29374,7 @@ int wc_Falcon_PrivateKeyToDer(falcon_key* key, byte* output, word32 inLen)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
|
||||
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
|
||||
/* Write private Curve448 key to DER format,
|
||||
|
@ -669,7 +669,7 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
|
||||
(defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)) || \
|
||||
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)) || \
|
||||
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)) || \
|
||||
(defined(HAVE_PQC)))
|
||||
(defined(HAVE_PQC) && defined(HAVE_FALCON)))
|
||||
#define WC_ENABLE_ASYM_KEY_EXPORT
|
||||
#endif
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef HAVE_PQC
|
||||
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
|
||||
|
||||
#ifdef HAVE_LIBOQS
|
||||
#include <oqs/oqs.h>
|
||||
@ -129,5 +129,5 @@ int wc_falcon_sig_size(falcon_key* key);
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_PQC */
|
||||
#endif /* HAVE_PQC && HAVE_FALCON */
|
||||
#endif /* WOLF_CRYPT_FALCON_H */
|
||||
|
@ -2592,12 +2592,22 @@ extern void uITRON4_free(void *p) ;
|
||||
* group */
|
||||
#ifdef HAVE_LIBOQS
|
||||
#define HAVE_PQC
|
||||
#define HAVE_FALCON
|
||||
#define HAVE_KYBER
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PQC) && !defined(HAVE_LIBOQS)
|
||||
#error "You must have a post-quantum cryptography implementation to use PQC."
|
||||
#ifdef HAVE_PQM4
|
||||
#define HAVE_PQC
|
||||
#define HAVE_KYBER
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PQC) && !defined(HAVE_LIBOQS) && !defined(HAVE_PQM4)
|
||||
#error Please do not define HAVE_PQC yourself.
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS) && defined(HAVE_PQM4)
|
||||
#error Please do not define both HAVE_LIBOQS and HAVE_PQM4.
|
||||
#endif
|
||||
|
||||
/* SRTP requires DTLS */
|
||||
#if defined(WOLFSSL_SRTP) && !defined(WOLFSSL_DTLS)
|
||||
|
Reference in New Issue
Block a user