diff --git a/IDE/STM32Cube/default_conf.ftl b/IDE/STM32Cube/default_conf.ftl index d87510cc2..a9e9098b9 100644 --- a/IDE/STM32Cube/default_conf.ftl +++ b/IDE/STM32Cube/default_conf.ftl @@ -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 */ diff --git a/IDE/STM32Cube/wolfssl_example.c b/IDE/STM32Cube/wolfssl_example.c index 14bf496a5..89c40ee6c 100644 --- a/IDE/STM32Cube/wolfssl_example.c +++ b/IDE/STM32Cube/wolfssl_example.c @@ -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"); diff --git a/src/internal.c b/src/internal.c index acc94d46f..8bf04ccf8 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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; diff --git a/src/ssl.c b/src/ssl.c index 00604c48e..d82852351 100644 --- a/src/ssl.c +++ b/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"); diff --git a/src/tls.c b/src/tls.c index b0383cd17..4323c4f0a 100644 --- a/src/tls.c +++ b/src/tls.c @@ -51,6 +51,12 @@ #ifdef HAVE_PQC #ifdef HAVE_LIBOQS #include +#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; diff --git a/src/tls13.c b/src/tls13.c index 5fd0ac1e5..2f41b7eec 100644 --- a/src/tls13.c +++ b/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) { diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 6a2547b47..368f26f1d 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -245,7 +245,7 @@ #ifdef HAVE_LIBOQS #include #endif -#ifdef HAVE_PQC +#if defined(HAVE_PQC) && defined(HAVE_FALCON) #include #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) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3e7776e87..7c0b432e8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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, diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index c80e7317a..feff07cb3 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -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 diff --git a/wolfssl/wolfcrypt/falcon.h b/wolfssl/wolfcrypt/falcon.h index 136976e3f..8b42948ac 100644 --- a/wolfssl/wolfcrypt/falcon.h +++ b/wolfssl/wolfcrypt/falcon.h @@ -31,7 +31,7 @@ #include -#ifdef HAVE_PQC +#if defined(HAVE_PQC) && defined(HAVE_FALCON) #ifdef HAVE_LIBOQS #include @@ -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 */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 965a4d9ca..724a59ad7 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.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)