From c8fd5d552e5c0e5240b82ad2dfb9c32e9a9f13e5 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 16 Aug 2021 13:05:56 -0700 Subject: [PATCH] IoTSafe Improvements. Use new hex to char functions in misc.c. Fix for arm-none-eabi missing nano specs. Cleanups for IoTSafe code, `README.md` and `user_settings.h`. Fix linker script to use flash at `0x8000000`. Support for TLS v1.3. --- .gitignore | 4 + IDE/iotsafe/Makefile | 3 +- IDE/iotsafe/README.md | 109 ++++++- IDE/iotsafe/memory-tls.c | 231 +++++++------- IDE/iotsafe/target.ld | 2 +- IDE/iotsafe/user_settings.h | 102 ++++--- wolfcrypt/src/port/iotsafe/iotsafe.c | 437 +++++++++++++++------------ 7 files changed, 540 insertions(+), 348 deletions(-) diff --git a/.gitignore b/.gitignore index 1a17d53d4..ecdde5219 100644 --- a/.gitignore +++ b/.gitignore @@ -327,6 +327,10 @@ IDE/HEXIWEAR/wolfSSL_HW/Debug # Linux-SGX IDE/LINUX-SGX/*.a +IDE/iotsafe/*.map +IDE/iotsafe/*.elf +IDE/iotsafe/*.bin + # Binaries wolfcrypt/src/port/intel/qat_test /mplabx/wolfssl.X/dist/default/ diff --git a/IDE/iotsafe/Makefile b/IDE/iotsafe/Makefile index 5f047abc6..0101eb1ca 100644 --- a/IDE/iotsafe/Makefile +++ b/IDE/iotsafe/Makefile @@ -16,7 +16,7 @@ WOLFSSL_BUILD=build/wolfssl OBJCOPY:=$(CROSS_COMPILE)objcopy -CFLAGS:=-mthumb -g -ggdb -Wall -Wno-main -Wstack-usage=65535 -Wno-unused -I$(WOLFSSL_ROOT) -I. +CFLAGS:=-mthumb -g -ggdb -Wall -Wextra -Wno-main -fsigned-char -Wstack-usage=65535 -Wno-unused -I$(WOLFSSL_ROOT) -I. CFLAGS+=-lc -lg -lm -Wno-pointer-sign #CFLAGS+=-mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -lm CFLAGS+=-mcpu=cortex-m3 @@ -26,6 +26,7 @@ LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -mthumb -mthumb-inte #LDFLAGS+=-mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -lm LDFLAGS+=-mcpu=cortex-m3 LDFLAGS+=-lc -lg -lm +LDFLAGS+=--specs=nosys.specs OBJS:=main.o startup.o devices.o memory-tls.o diff --git a/IDE/iotsafe/README.md b/IDE/iotsafe/README.md index 847d98d1f..e594d03e9 100644 --- a/IDE/iotsafe/README.md +++ b/IDE/iotsafe/README.md @@ -5,11 +5,13 @@ * ST [P-L496G-CELL02](https://www.st.com/en/evaluation-tools/p-l496g-cell02.html) -including: +Including: * STM32L496AGI6-based low-power discovery mother board - * STMiQuectel BG96 modem, plugged into the 'STMod+' connector + * STM Quectel BG96 modem, plugged into the 'STMod+' connector * IoT-Safe capable SIM card +Note: The BG96 was tested using firmware `BG96MAR02A08M1G_01.012.01.012`. If having issues with the demo make sure your BG96 firmware is updated. + ### Description This example firmware will run an example TLS 1.2 server using wolfSSL, and a @@ -27,34 +29,32 @@ TLS session without the use of TCP/IP sockets. In this example, the client is the IoT-safe capable endpoint. First, it creates a wolfSSL context `cli_ctx` normally: -``` - wolfSSL_CTX_iotsafe_enable(cli_ctx); +```c +wolfSSL_CTX_iotsafe_enable(cli_ctx); ``` In order to activate IoT-safe support in this context, the following function is called: -``` - printf("Client: Enabling IoT Safe in CTX\n"); - wolfSSL_CTX_iotsafe_enable(cli_ctx); +```c +printf("Client: Enabling IoT Safe in CTX\n"); +wolfSSL_CTX_iotsafe_enable(cli_ctx); ``` Additionally, after the SSL session creation, shown below: -``` - printf("Creating new SSL\n"); - cli_ssl = wolfSSL_new(cli_ctx); +```c +printf("Creating new SSL\n"); +cli_ssl = wolfSSL_new(cli_ctx); ``` the client associates the pre-provisioned keys and the available slots in the IoT safe applet to the current session: -``` - wolfSSL_iotsafe_on(cli_ssl, PRIVKEY_ID, ECDH_KEYPAIR_ID, PEER_PUBKEY_ID, - PEER_CERT_ID); - +```c +wolfSSL_iotsafe_on(cli_ssl, PRIVKEY_ID, ECDH_KEYPAIR_ID, PEER_PUBKEY_ID, PEER_CERT_ID); ``` The applet that has been tested with this demo has the current configuration: @@ -79,5 +79,86 @@ The following file is used to read the client's certificate: From this directory, run 'make', then use your favorite flash programming software to upload the firmware `image.bin` to the target board. +1) Using the STM32CubeProgrammer open the `image.elf` and program to flash. +2) Using ST-Link virtual serial port connect at 115220 +3) Hit reset button. +4) The output should look similar to below: +``` +wolfSSL IoT-SAFE demo +Press a key to continue... +. +Initializing modem... +Modem booting... +Modem is on. +System up and running +Initializing wolfSSL... +Initializing modem port +Turning on VDDIO2 +Initializing IoTSafe I/O... +Initializing RNG... +Getting RND... +Random bytes: 08ECF538192218569876EAB9D690306C +Starting memory-tls test... +=== SERVER step 0 === +Setting TLSv1.3 for SECP256R1 key share +=== CLIENT step 0 === +Client: Creating new CTX +Client: Enabling IoT Safe in CTX +Loading CA +Loaded Server certificate from IoT-Safe, size = 676 +Server certificate successfully imported. +Loaded Client certificate from IoT-Safe, size = 867 +Client certificate successfully imported. +Creating new SSL object +Setting TLS options: turn on IoT-safe for this socket +Setting TLSv1.3 for SECP256R1 key share +Connecting to server... +=== Cli->Srv: 162 +=== SERVER step 1 === +=== Srv RX: 5 +=== Srv RX: 157 +=== Srv-Cli: 128 +=== Srv-Cli: 28 +=== Srv-Cli: 43 +=== Srv-Cli: 712 +=== Srv-Cli: 100 +=== Srv-Cli: 58 +=== CLIENT step 1 === +Connecting to server... +=== Cli RX: 5 +=== Cli RX: 123 +=== Cli RX: 5 +=== Cli RX: 23 +=== Cli RX: 5 +=== Cli RX: 38 +=== Cli RX: 5 +=== Cli RX: 707 +=== Cli RX: 5 +=== Cli RX: 95 +=== Cli RX: 5 +=== Cli RX: 53 +=== Cli->Srv: 902 +=== Cli->Srv: 101 +=== Cli->Srv: 58 +Client connected! +Sending message: hello iot-safe wolfSSL +=== Cli->Srv: 44 +wolfSSL client test success! +=== SERVER step 1 === +=== Srv RX: 5 +=== Srv RX: 897 +=== Srv RX: 5 +=== Srv RX: 96 +=== Srv RX: 5 +=== Srv RX: 53 +wolfSSL accept success! +=== Srv RX: 5 +=== Srv RX: 39 +++++++ Server received msg from client: 'hello iot-safe wolfSSL' +IoT-Safe TEST SUCCESSFUL +``` +## Support + +For questions please email support@wolfssl.com diff --git a/IDE/iotsafe/memory-tls.c b/IDE/iotsafe/memory-tls.c index e1c9422ad..e5f8036e8 100644 --- a/IDE/iotsafe/memory-tls.c +++ b/IDE/iotsafe/memory-tls.c @@ -77,10 +77,22 @@ * activates mutual authentication */ #define CLIENT_AUTH - #define CLIENT_IOTSAFE #define CA_ECC + +static int client_state = 0; +static int server_state = 0; + +static uint8_t cert_buffer[2048]; +static uint32_t cert_buffer_size; + +static WOLFSSL_CTX* srv_ctx = NULL; +static WOLFSSL* srv_ssl = NULL; +static WOLFSSL_CTX *cli_ctx = NULL; +static WOLFSSL *cli_ssl = NULL; + + /* client messages to server in memory */ #define TLS_BUFFERS_SZ (1024 * 8) static unsigned char to_server[TLS_BUFFERS_SZ]; @@ -89,18 +101,20 @@ static int server_write_idx; static int server_read_idx; /* server messages to client in memory */ -unsigned char to_client[TLS_BUFFERS_SZ]; -int client_bytes; -int client_write_idx; -int client_read_idx; +static unsigned char to_client[TLS_BUFFERS_SZ]; +static int client_bytes; +static int client_write_idx; +static int client_read_idx; + /* server send callback */ int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) { - if (client_write_idx + sz > TLS_BUFFERS_SZ) - return -SSL_ERROR_WANT_WRITE; + if (client_write_idx + sz > TLS_BUFFERS_SZ) { + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } printf("=== Srv-Cli: %d\n", sz); - memcpy(&to_client[client_write_idx], buf, sz); + XMEMCPY(&to_client[client_write_idx], buf, sz); client_write_idx += sz; client_bytes += sz; return sz; @@ -110,10 +124,10 @@ int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) /* server recv callback */ int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) { - - if (server_bytes - server_read_idx < sz) - return -SSL_ERROR_WANT_READ; - memcpy(buf, &to_server[server_read_idx], sz); + if (server_bytes - server_read_idx < sz) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } + XMEMCPY(buf, &to_server[server_read_idx], sz); server_read_idx += sz; if (server_read_idx == server_write_idx) { @@ -129,10 +143,10 @@ int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) { if (server_write_idx + sz > TLS_BUFFERS_SZ) - return -SSL_ERROR_WANT_WRITE; + return WOLFSSL_CBIO_ERR_WANT_WRITE; printf("=== Cli->Srv: %d\n", sz); - memcpy(&to_server[server_write_idx], buf, sz); + XMEMCPY(&to_server[server_write_idx], buf, sz); server_write_idx += sz; server_bytes += sz; @@ -143,11 +157,11 @@ int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) /* client recv callback */ int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) { + if (client_bytes - client_read_idx < sz) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } - if (client_bytes - client_read_idx < sz) - return -SSL_ERROR_WANT_READ; - - memcpy(buf, &to_client[client_read_idx], sz); + XMEMCPY(buf, &to_client[client_read_idx], sz); client_read_idx += sz; if (client_read_idx == client_write_idx) { @@ -158,28 +172,23 @@ int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) return sz; } -static int client_state = 0; -static int server_state = 0; - -static uint8_t cert_buffer[2048]; -static uint32_t cert_buffer_size; - - /* wolfSSL Client loop */ static int client_loop(void) { /* set up client */ int ret; - static WOLFSSL_CTX *cli_ctx = NULL; - static WOLFSSL *cli_ssl = NULL; - + const char* helloStr = "hello iot-safe wolfSSL"; printf("=== CLIENT step %d ===\n", client_state); if (client_state == 0) { printf("Client: Creating new CTX\n"); + #ifdef WOLFSSL_TLS13 + cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); + #else cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + #endif if (cli_ctx == NULL) { - printf("bad client ctx new"); + printf("Bad client ctx new"); return 0; } printf("Client: Enabling IoT Safe in CTX\n"); @@ -187,38 +196,39 @@ static int client_loop(void) printf("Loading CA\n"); ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256, - sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1); - if (ret != SSL_SUCCESS) { + sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { printf("Bad CA\n"); return -1; } - cert_buffer_size = wolfIoTSafe_GetCert(CRT_SERVER_FILE_ID, cert_buffer, 2048); + cert_buffer_size = wolfIoTSafe_GetCert(CRT_SERVER_FILE_ID, cert_buffer, + sizeof(cert_buffer)); if (cert_buffer_size < 1) { printf("Bad server cert\n"); return -1; } printf("Loaded Server certificate from IoT-Safe, size = %lu\n", cert_buffer_size); - WOLFSSL_BUFFER(cert_buffer, cert_buffer_size); if (wolfSSL_CTX_load_verify_buffer(cli_ctx, cert_buffer, cert_buffer_size, - SSL_FILETYPE_ASN1) != SSL_SUCCESS) { + WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Cannot load server cert\n"); return -1; } printf("Server certificate successfully imported.\n"); - wolfSSL_CTX_set_verify(cli_ctx, SSL_VERIFY_PEER, 0); + wolfSSL_CTX_set_verify(cli_ctx, WOLFSSL_VERIFY_PEER, NULL); #ifdef CLIENT_AUTH - cert_buffer_size = wolfIoTSafe_GetCert(CRT_CLIENT_FILE_ID, cert_buffer, 2048); + cert_buffer_size = wolfIoTSafe_GetCert(CRT_CLIENT_FILE_ID, cert_buffer, + sizeof(cert_buffer)); if (cert_buffer_size < 1) { - printf("Bad cli cert\n"); + printf("Bad client cert\n"); return -1; } - printf("Loaded Client certificate from IoT-Safe, size = %lu\n", cert_buffer_size); - WOLFSSL_BUFFER(cert_buffer, cert_buffer_size); + printf("Loaded Client certificate from IoT-Safe, size = %lu\n", + cert_buffer_size); if (wolfSSL_CTX_use_certificate_buffer(cli_ctx, cert_buffer, - cert_buffer_size, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { + cert_buffer_size, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Cannot load client cert\n"); return -1; } @@ -226,135 +236,140 @@ static int client_loop(void) #endif /* Setting IO Send/Receive functions to local memory-based message - * passing (ClientSend, ClientRecv) - */ - wolfSSL_SetIOSend(cli_ctx, ClientSend); - wolfSSL_SetIORecv(cli_ctx, ClientRecv); + * passing (ClientSend, ClientRecv) */ + wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend); + wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv); - printf("Creating new SSL\n"); + printf("Creating new SSL object\n"); cli_ssl = wolfSSL_new(cli_ctx); if (cli_ssl == NULL) { printf("bad client new"); return 0; } - printf("Setting SSL options: non blocking\n"); - wolfSSL_set_using_nonblock(cli_ssl, 1); - printf("Setting SSL options: turn on IoT-safe for this socket\n"); - wolfSSL_iotsafe_on(cli_ssl, PRIVKEY_ID, ECDH_KEYPAIR_ID, PEER_PUBKEY_ID, - PEER_CERT_ID); + + printf("Setting TLS options: turn on IoT-safe for this socket\n"); + wolfSSL_iotsafe_on(cli_ssl, PRIVKEY_ID, ECDH_KEYPAIR_ID, + PEER_PUBKEY_ID, PEER_CERT_ID); + + #ifdef WOLFSSL_TLS13 + printf("Setting TLSv1.3 for SECP256R1 key share\n"); + wolfSSL_UseKeyShare(cli_ssl, WOLFSSL_ECC_SECP256R1); + #endif + client_state++; } if (client_state == 1) { - int err; printf("Connecting to server...\n"); ret = wolfSSL_connect(cli_ssl); - if (ret != SSL_SUCCESS) { - if (wolfSSL_want_read(cli_ssl)) + if (ret != WOLFSSL_SUCCESS) { + if (wolfSSL_want_read(cli_ssl) || wolfSSL_want_write(cli_ssl)) { return 0; - printf("error in client tls connect: %d\n", wolfSSL_get_error(cli_ssl, ret)); + } + printf("Error in client tls connect: %d\n", + wolfSSL_get_error(cli_ssl, ret)); client_state = 0; - wolfSSL_free(cli_ssl); - wolfSSL_CTX_free(cli_ctx); - cli_ssl = NULL; - cli_ctx = NULL; return -1; } - printf("Client connected! Sending hello message...\n"); + printf("Client connected!\n"); client_state++; } - ret = wolfSSL_write(cli_ssl, "hello iot-safe wolfSSL",22); - if (ret >= 0) { - printf("wolfSSL client success!\n"); - } else if (wolfSSL_get_error(cli_ssl, ret) != SSL_ERROR_WANT_WRITE) { - printf("error in client tls write"); - client_state = 0; - wolfSSL_free(cli_ssl); - wolfSSL_CTX_free(cli_ctx); - cli_ssl = NULL; - cli_ctx = NULL; - return -1; - } - /* clean up */ - wolfSSL_free(cli_ssl); - wolfSSL_CTX_free(cli_ctx); - return 1; -} + if (client_state == 2) { + printf("Sending message: %s\n", helloStr); + ret = wolfSSL_write(cli_ssl, helloStr, XSTRLEN(helloStr)); + if (ret >= 0) { + printf("wolfSSL client test success!\n"); -uint8_t srv_cert[1260]; -uint32_t srv_cert_size; + wolfSSL_free(cli_ssl); cli_ssl = NULL; + wolfSSL_CTX_free(cli_ctx); cli_ctx = NULL; + client_state = 0; + } + else if (wolfSSL_get_error(cli_ssl, ret) != WOLFSSL_ERROR_WANT_WRITE) { + printf("Error in client tls write"); + client_state = 0; + return -1; + } + } + + return ret; +} /* wolfSSL Server Loop */ static int server_loop(void) { - static WOLFSSL_CTX* srv_ctx = NULL; - static WOLFSSL* srv_ssl = NULL; - unsigned char buf[80]; int ret; + unsigned char buf[80]; + printf("=== SERVER step %d ===\n", server_state); if (server_state == 0) { + #ifdef WOLFSSL_TLS13 + srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()); + #else srv_ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()); + #endif if (srv_ctx == NULL) { printf("bad server ctx new"); return -1; } #ifdef CLIENT_AUTH ret = wolfSSL_CTX_load_verify_buffer(srv_ctx, ca_ecc_cert_der_256, - sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1); - if (ret != SSL_SUCCESS) { + sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { printf("Bad CA load: %d\n", ret); } ret = wolfSSL_CTX_load_verify_buffer(srv_ctx, cliecc_cert_der_256, - sizeof_cliecc_cert_der_256, SSL_FILETYPE_ASN1); - if (ret != SSL_SUCCESS) { + sizeof_cliecc_cert_der_256, WOLFSSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { printf("Bad Client cert load: %d\n", ret); } - wolfSSL_CTX_set_verify(srv_ctx, SSL_VERIFY_PEER, 0); + wolfSSL_CTX_set_verify(srv_ctx, WOLFSSL_VERIFY_PEER, NULL); #endif if (wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256, - sizeof_ecc_key_der_256, SSL_FILETYPE_ASN1) - != SSL_SUCCESS) { + sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Cannot load server private key\n"); } if (wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256, - sizeof_serv_ecc_der_256, SSL_FILETYPE_ASN1) != SSL_SUCCESS) - { + sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("Cannot load server cert\n"); } - wolfSSL_SetIOSend(srv_ctx, ServerSend); - wolfSSL_SetIORecv(srv_ctx, ServerRecv); + wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend); + wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv); + srv_ssl = wolfSSL_new(srv_ctx); if (srv_ssl == NULL) { printf("bad server new"); return -1; } - wolfSSL_set_using_nonblock(srv_ssl, 1); + + #ifdef WOLFSSL_TLS13 + printf("Setting TLSv1.3 for SECP256R1 key share\n"); + wolfSSL_UseKeyShare(srv_ssl, WOLFSSL_ECC_SECP256R1); + #endif server_state++; } if (server_state == 1) { /* accept tls connection without tcp sockets */ ret = wolfSSL_accept(srv_ssl); - if (ret != SSL_SUCCESS) { - if (wolfSSL_want_read(srv_ssl)) + if (ret != WOLFSSL_SUCCESS) { + if (wolfSSL_want_read(srv_ssl) || wolfSSL_want_write(srv_ssl)) { return 0; - printf("error in server tls accept"); + } + printf("Error in server tls accept: %d\n", + wolfSSL_get_error(srv_ssl, ret)); server_state = 0; - wolfSSL_free(srv_ssl); - wolfSSL_CTX_free(srv_ctx); - srv_ssl = NULL; - srv_ctx = NULL; return -1; } printf("wolfSSL accept success!\n"); server_state++; } + if (server_state == 2) { ret = wolfSSL_read(srv_ssl, buf, sizeof(buf)-1); - if (wolfSSL_get_error(srv_ssl, ret) == SSL_ERROR_WANT_READ) { + if (wolfSSL_get_error(srv_ssl, ret) == WOLFSSL_ERROR_WANT_READ) { return 0; } if (ret < 0) { @@ -364,8 +379,14 @@ static int server_loop(void) if (ret > 0) { printf("++++++ Server received msg from client: '%s'\n", buf); printf("IoT-Safe TEST SUCCESSFUL\n"); + + wolfSSL_free(srv_ssl); srv_ssl = NULL; + wolfSSL_CTX_free(srv_ctx); srv_ctx = NULL; + + server_state = 0; } } + return 0; } @@ -378,7 +399,13 @@ int memory_tls_test(void) do { ret_s = server_loop(); ret_c = client_loop(); - } while ((ret_s >= 0) && (ret_c >= 0)); + + /* clean up */ + wolfSSL_free(cli_ssl); + wolfSSL_CTX_free(cli_ctx); + wolfSSL_free(srv_ssl); + wolfSSL_CTX_free(srv_ctx); + return 0; } diff --git a/IDE/iotsafe/target.ld b/IDE/iotsafe/target.ld index 710641c6a..474bf5b3e 100644 --- a/IDE/iotsafe/target.ld +++ b/IDE/iotsafe/target.ld @@ -26,7 +26,7 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1M SRAM1_STACK (rw) : ORIGIN = 0x20000000, LENGTH = 16K SRAM1(rw) : ORIGIN = 0x20000000 + 16K, LENGTH = 256K - 16K SRAM2 (rw) : ORIGIN = 0x20040000, LENGTH = 64K diff --git a/IDE/iotsafe/user_settings.h b/IDE/iotsafe/user_settings.h index 306b16d70..bf1ca9531 100644 --- a/IDE/iotsafe/user_settings.h +++ b/IDE/iotsafe/user_settings.h @@ -19,63 +19,70 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Example 'user-settings.h' for IoT-Safe demo */ +/* Example 'user_settings.h' for IoT-Safe demo */ #ifndef IOTSAFE_EXAMPLE_USER_SETTINGS_H #define IOTSAFE_EXAMPLE_USER_SETTINGS_H + #include +/* Platform */ #define WOLFSSL_IOTSAFE -#define HAVE_IOTSAFE_HWRNG -#define HAVE_HASHDRBG #define WOLFSSL_SMALL_STACK - #define WOLFSSL_GENERAL_ALIGNMENT 4 -#define DEBUG_WOLFSSL -#define WOLFSSL_LOG_PRINTF -#define DEBUG_WOLFSSL_VERBOSE #define SINGLE_THREADED #define WOLFSSL_USER_IO -#define TIME_OVERRIDES +/* Debugging */ +#define WOLFSSL_LOG_PRINTF +#if 0 + #define DEBUG_WOLFSSL + #define WOLFSSL_DEBUG_TLS + #define DEBUG_IOTSAFE +#endif +/* Features */ +#define HAVE_PK_CALLBACKS /* Connect IoT-safe with PK_CALLBACKS */ +#define SMALL_SESSION_CACHE +#define USE_CERT_BUFFERS_256 + +/* RNG */ +#define HAVE_IOTSAFE_HWRNG +#define HAVE_HASHDRBG +#define NO_OLD_RNGNAME + +/* Time porting */ +#define TIME_OVERRIDES extern volatile unsigned long jiffies; static inline long XTIME(long *x) { return jiffies;} -#define NO_ASN_TIME #define WOLFSSL_USER_CURRTIME -#define NO_OLD_RNGNAME -#define SMALL_SESSION_CACHE -#define WOLFSSL_SMALL_STACK -#define TFM_ARM +#define NO_ASN_TIME + +/* Math */ #define TFM_TIMING_RESISTANT -#define ECC_TIMING_RESISTANT - - -/* Connect IoT-safe with PK_CALLBACKS */ -#define HAVE_PK_CALLBACKS - -/* ECC definitions */ -# define HAVE_ECC -# define ECC_ALT_SIZE -# define WOLFSSL_HAVE_SP_ECC -# define USE_CERT_BUFFERS_256 - -/* SP math */ +#define TFM_ARM #define WOLFSSL_SP_MATH #define WOLFSSL_SP_MATH_ALL #define WOLFSSL_SP_SMALL #define WOLFSSL_HAVE_SP_DH +#define WOLFSSL_HAVE_SP_ECC #define SP_WORD_SIZE 32 +/* ECC */ +#define HAVE_ECC +#define ECC_ALT_SIZE +#define ECC_TIMING_RESISTANT + /* RSA */ #define RSA_LOW_MEM #define WC_RSA_BLINDING +#define WC_RSA_PSS +/* DH - on by default */ #define WOLFSSL_DH_CONST +#define HAVE_FFDHE_2048 -/* TLS settings */ -#define NO_OLD_TLS -#define HAVE_TLS_EXTENSIONS +/* AES */ #define HAVE_AES_DECRYPT #define HAVE_AESGCM #define GCM_SMALL @@ -83,25 +90,44 @@ static inline long XTIME(long *x) { return jiffies;} #define WOLFSSL_AES_COUNTER #define WOLFSSL_AES_DIRECT -/* TLS 1.3 */ -#define WOLFSSL_TLS13 -#define HAVE_SUPPORTED_CURVES -#define HAVE_HKDF -#define HAVE_AEAD -#define WC_RSA_PSS -#define HAVE_FFDHE_2048 +/* Hashing */ #define HAVE_SHA384 #define HAVE_SHA512 +#define HAVE_HKDF + +/* TLS */ +#if 0 + /* TLS v1.3 only */ + #define WOLFSSL_TLS13 + #define WOLFSSL_NO_TLS12 +#else + /* TLS v1.2 only */ +#endif +#define NO_OLD_TLS +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES + +/* Disable Features */ #define NO_WRITEV #define NO_FILESYSTEM #define NO_MAIN_DRIVER +//#define NO_ERROR_STRINGS -#define NO_RC4 +/* Disable Algorithms */ #define NO_DES3 +#define NO_DSA +#define NO_RC4 +#define NO_MD4 +#define NO_MD5 +#define NO_SHA +#define NO_HC128 +#define NO_RABBIT +#define NO_PKCS12 +/* helpers */ #define htons(x) __builtin_bswap16(x) #define ntohs(x) __builtin_bswap16(x) #define ntohl(x) __builtin_bswap32(x) #define htonl(x) __builtin_bswap32(x) -#endif /* IOTSAFE_EXAMPLE_USER_SETTINGS_H */ +#endif /* !IOTSAFE_EXAMPLE_USER_SETTINGS_H */ diff --git a/wolfcrypt/src/port/iotsafe/iotsafe.c b/wolfcrypt/src/port/iotsafe/iotsafe.c index d7399755f..76a6ac97b 100644 --- a/wolfcrypt/src/port/iotsafe/iotsafe.c +++ b/wolfcrypt/src/port/iotsafe/iotsafe.c @@ -22,7 +22,9 @@ /* IoT-safe module for communication with IoT-safe applet on SIM card */ #include + #ifdef WOLFSSL_IOTSAFE + #include #include #include @@ -30,6 +32,17 @@ #include #include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifdef DEBUG_IOTSAFE +#include +#endif + static int wolfIoT_initialized = 0; /* Modem APDU interface @@ -80,23 +93,14 @@ static int hex_to_bytes(const char *hex, unsigned char *output, unsigned long sz { word32 i; for (i = 0; i < sz; i++) { - output[i] = 0; - if ((hex[i * 2] >= 'A') && (hex[i * 2] <= 'F')) - output[i] += (hex[i * 2] - 'A' + 10) << 4; - else if (hex[i * 2] >= '0' && (hex[i * 2] <= '9')) - output[i] += (hex[i * 2] - '0') << 4; - else { + char ch1, ch2; + ch1 = HexCharToByte(hex[i * 2]); + ch2 = HexCharToByte(hex[i * 2 + 1]); + if (ch1 < 0 || ch2 < 0) { WOLFSSL_MSG("hex_to_bytes: syntax error"); return -1; } - if ((hex[i * 2 + 1] >= 'A') && (hex[i * 2 + 1] <= 'F')) - output[i] += (hex[i * 2 + 1] - 'A' + 10); - else if (hex[i * 2 + 1] >= '0' && (hex[i * 2 + 1] <= '9')) - output[i] += (hex[i * 2 + 1] - '0'); - else { - WOLFSSL_MSG("hex conversion: syntax error"); - return -1; - } + output[i] = (ch1 << 4) + ch2; } return (int)sz; } @@ -105,17 +109,7 @@ static int bytes_to_hex(const unsigned char *bytes, char *hex, unsigned long sz) { word32 i; for (i = 0; i < sz; i++) { - unsigned char val; - val = (bytes[i] >> 4) & 0x0F; - if (val > 9) - hex[2 * i] = 'A' + (val - 10); - else - hex[2 * i] = '0' + val; - val = (bytes[i] & 0x0F); - if (val > 9) - hex[2 * i + 1] = 'A' + (val - 10); - else - hex[2 * i + 1] = '0' + val; + ByteToHexStr(bytes[i], &hex[2 * i]); } return (int)(2 * sz); } @@ -125,10 +119,12 @@ static int expect_tok(const char *cmd, int size, const char *tok, char **repl) int ret = 0; char *r_found = NULL; static char parser_line[MAXBUF / 2]; - if (repl) + if (repl) { *repl = NULL; - if (cmd) + } + if (cmd) { ret = csim_write(cmd, size); + } while (ret > 0) { ret = csim_read(csim_read_buf, MAXBUF); if (tok && (ret > 0) && !r_found) { @@ -165,10 +161,7 @@ static int hexbuffer_conv(char *hex_str, unsigned char *output, unsigned long sz if (XSTRLEN(hex_str) != (2 * sz)) { return -1; } - ret = hex_to_bytes(hex_str, output, sz); - if (ret != (int)sz) - return ret; - return (int)sz; + return (int)hex_to_bytes(hex_str, output, sz); } /* Search a TLV by tag in a buffer */ @@ -221,11 +214,13 @@ static int iotsafe_cmd_add_tlv_ex(char *cmd, byte tag, uint16_t len, word32 cmdlen; cmdlen = XSTRLEN(cmd); - if (cmdlen < AT_CSIM_CMD_SIZE) + if (cmdlen < AT_CSIM_CMD_SIZE) { return BAD_FUNC_ARG; + } - if ((taglen_size < 1) || (taglen_size > 2)) + if ((taglen_size < 1) || (taglen_size > 2)) { return BAD_FUNC_ARG; + } /* Read out current CSIM len from the existing string. * The generated command may have the format: @@ -250,8 +245,9 @@ static int iotsafe_cmd_add_tlv_ex(char *cmd, byte tag, uint16_t len, /* Read out current Lc parameter in the CSIM command, last byte in the * header */ - if (hex_to_bytes(cmd + AT_CSIM_CMD_SIZE + AT_CMD_LC_POS, &cur_lc, 1) < 0) + if (hex_to_bytes(cmd + AT_CSIM_CMD_SIZE + AT_CMD_LC_POS, &cur_lc, 1) < 0) { return BAD_FUNC_ARG; + } /* Increase Lc and CSIM length according to the TLV len */ cur_lc += 1 + taglen_size + len; @@ -308,10 +304,11 @@ static int iotsafe_cmd_add_tlv(char *cmd, byte tag, byte len, const byte *val) static void iotsafe_cmd_complete(char *cmd) { - word32 cmdlen = XSTRLEN(cmd); + word32 cmdlen = (word32)XSTRLEN(cmd); char *out; - if (cmdlen + CSIM_CMD_ENDSTR_SIZE > IOTSAFE_CMDSIZE_MAX) + if (cmdlen + CSIM_CMD_ENDSTR_SIZE > IOTSAFE_CMDSIZE_MAX) { return; + } out = cmd + cmdlen; out[0] = '"'; out[1] = '\r'; @@ -335,11 +332,13 @@ static int expect_csim_response(const char *cmd, word32 size, char **reply) while (ret == 0) { ret = expect_tok("AT\r\n", 4, csim_response_hdr, &csim_reply); } - if (ret < 1) + if (ret < 1) { return ret; + } payload = XSTRSTR(csim_reply, "\""); - if (!payload) + if (payload == NULL) { return -1; + } payload++; if (XSTRNCMP(payload, "61", 2) == 0) { if (hex_to_bytes(payload + 2, &len, 1) == 1) { @@ -352,7 +351,7 @@ static int expect_csim_response(const char *cmd, word32 size, char **reply) if (ret < 1) return -1; payload = XSTRSTR(*reply, "\""); - if (!payload) + if (payload == NULL) return -1; payload++; } @@ -360,7 +359,7 @@ static int expect_csim_response(const char *cmd, word32 size, char **reply) ret -= 2; if (ret >= 4) { endstr = XSTRSTR(payload, "9000\""); - if (!endstr) + if (endstr == NULL) endstr = XSTRSTR(payload, "\""); if (endstr) { *endstr = 0; @@ -391,12 +390,12 @@ static int iotsafe_init(void) if (ret < 0) return ret; - WOLFSSL_MSG("ATE0 OK!\n"); + WOLFSSL_MSG("ATE0 OK!"); if (expect_csim_response(atcmd_load_applet_str, (word32)XSTRLEN(atcmd_load_applet_str), &reply) < 1) { - WOLFSSL_MSG("FAIL: no Applet code response from iot-safe init\n"); + WOLFSSL_MSG("FAIL: no Applet code response from iot-safe init"); } else { - WOLFSSL_MSG("IoT Safe Applet INIT OK\r\n"); + WOLFSSL_MSG("IoT Safe Applet INIT OK"); } if (expect_tok(NULL, 0, NULL, NULL) < 0) return -1; @@ -435,8 +434,7 @@ static int iotsafe_readfile(uint8_t file_id, unsigned char *content, WOLFSSL_MSG("Stat successful on file"); } - if (file_sz > max_size) - { + if (file_sz > max_size) { WOLFSSL_MSG("iotsafe_readfile: insufficient space in buffer"); return -1; } @@ -472,12 +470,13 @@ static int iotsafe_getrandom(unsigned char* output, unsigned long sz) char *resp = NULL; int ret; byte len = (byte)sz; - if (sz == 0) + if (sz == 0) { return BAD_FUNC_ARG; - if ( !wolfIoT_initialized) - { - if (iotsafe_init() < 0) + } + if (!wolfIoT_initialized) { + if (iotsafe_init() < 0) { return WC_HW_E; + } } iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_GETRANDOM,0,0); @@ -486,7 +485,6 @@ static int iotsafe_getrandom(unsigned char* output, unsigned long sz) iotsafe_cmd_complete(csim_cmd); ret = expect_csim_response(csim_cmd, (word32)GETRAND_CMD_SIZE, &resp); - if (ret <= 0) { WOLFSSL_MSG("Unexpected reply from RAND"); ret = WC_HW_E; @@ -497,8 +495,9 @@ static int iotsafe_getrandom(unsigned char* output, unsigned long sz) else ret = 0; } - if (expect_tok(NULL, 0, NULL, NULL) < 0) - return WC_HW_E; + if (expect_tok(NULL, 0, NULL, NULL) < 0) { + ret = WC_HW_E; + } return ret; } @@ -543,19 +542,19 @@ static int iotsafe_get_public_key(byte idx, ecc_key *key) return BAD_STATE_E; } rkey = search_tlv(resp, ret, IOTSAFE_TAG_ECC_KEY_FIELD); - if (!rkey) { + if (rkey == NULL) { WOLFSSL_MSG("IoT safe Error in rkey response"); return MISSING_KEY; } ktype = search_tlv(rkey + 4, IOTSAFE_TAG_ECC_KEY_FIELD_SZ, IOTSAFE_TAG_ECC_KEY_TYPE); - if (!ktype) { + if (ktype == NULL) { WOLFSSL_MSG("IoT safe Error in ktype response"); return MISSING_KEY; } payload_str = search_tlv(ktype + 4, IOTSAFE_TAG_ECC_KEY_TYPE_SZ, IOTSAFE_TAG_ECC_KEY_XY); - if (!payload_str) { + if (payload_str == NULL) { WOLFSSL_MSG("IoT safe: Error in payload response"); return MISSING_KEY; } @@ -574,7 +573,7 @@ static int iotsafe_get_public_key(byte idx, ecc_key *key) WOLFSSL_MSG("Could not import raw key into ecc key"); return ret; } - WOLFSSL_MSG("Get Public key: OK.\n"); + WOLFSSL_MSG("Get Public key: OK"); return 0; } @@ -582,7 +581,7 @@ static int iotsafe_put_public_key(byte idx, ecc_key *key) { char *resp; int ret; - word32 qxlen=IOTSAFE_ECC_KSIZE, qylen=IOTSAFE_ECC_KSIZE; + word32 qxlen = IOTSAFE_ECC_KSIZE, qylen = IOTSAFE_ECC_KSIZE; byte ecc_pub_raw[IOTSAFE_TAG_ECC_KEY_FIELD_SZ] = { IOTSAFE_TAG_ECC_KEY_TYPE, IOTSAFE_TAG_ECC_KEY_TYPE_SZ, @@ -592,8 +591,9 @@ static int iotsafe_put_public_key(byte idx, ecc_key *key) }; /* Export raw Qx, Qy values */ - ret = wc_ecc_export_public_raw(key, ecc_pub_raw + 5, &qxlen, - ecc_pub_raw + 5 + IOTSAFE_ECC_KSIZE, &qylen); + ret = wc_ecc_export_public_raw(key, + ecc_pub_raw + 5, &qxlen, + ecc_pub_raw + 5 + IOTSAFE_ECC_KSIZE, &qylen); if (ret != 0) { WOLFSSL_MSG("IoT Safe: Could not export public key: Error"); return ret; @@ -606,30 +606,32 @@ static int iotsafe_put_public_key(byte idx, ecc_key *key) iotsafe_cmd_complete(csim_cmd); if (expect_ok(csim_cmd, (word32)XSTRLEN(csim_cmd)) <= 0) { WOLFSSL_MSG("Unexpected reply when storing public key"); - ret = WC_HW_E; - } else { - do { - ret = expect_ok("AT\r\n", 4); - } while (ret == 0); - if (ret > 0) { - /* Put Public Update */ - iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_PUT_PUBLIC_UPDATE, - IOTSAFE_DATA_LAST, 0); - iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_ECC_KEY_FIELD, - IOTSAFE_TAG_ECC_KEY_FIELD_SZ, ecc_pub_raw); + return WC_HW_E; + } + + do { + ret = expect_ok("AT\r\n", 4); + } while (ret == 0); + + if (ret > 0) { + /* Put Public Update */ + iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_PUT_PUBLIC_UPDATE, + IOTSAFE_DATA_LAST, 0); + iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_ECC_KEY_FIELD, + IOTSAFE_TAG_ECC_KEY_FIELD_SZ, ecc_pub_raw); + iotsafe_cmd_complete(csim_cmd); + if (expect_csim_response(csim_cmd, + (word32)XSTRLEN(csim_cmd), &resp) < 0) { + WOLFSSL_MSG("Unexpected reply when storing public key (update)"); + ret = WC_HW_E; + } else { + iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, + IOTSAFE_INS_PUT_PUBLIC_INIT, 1, 0); iotsafe_cmd_complete(csim_cmd); - if (expect_csim_response(csim_cmd, - (word32)XSTRLEN(csim_cmd), &resp) < 0) { - WOLFSSL_MSG("Unexpected reply when storing public key (update)"); + if (expect_ok(csim_cmd, (word32)XSTRLEN(csim_cmd)) <= 0) { ret = WC_HW_E; } else { - iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_PUT_PUBLIC_INIT, - 1, 0); - iotsafe_cmd_complete(csim_cmd); - if (expect_ok(csim_cmd, (word32)XSTRLEN(csim_cmd)) <= 0) - ret = WC_HW_E; - else - ret = 0; + ret = 0; } } } @@ -647,9 +649,11 @@ static int iotsafe_sign_hash(byte privkey_idx, uint16_t hash_algo, char R[2 * IOTSAFE_ECC_KSIZE + 1]; char S[2 * IOTSAFE_ECC_KSIZE + 1]; - R[2*IOTSAFE_ECC_KSIZE] = 0; - S[2*IOTSAFE_ECC_KSIZE] = 0; + R[2*IOTSAFE_ECC_KSIZE] = '\0'; + S[2*IOTSAFE_ECC_KSIZE] = '\0'; + WOLFSSL_MSG("Enter iotsafe_sign_hash"); + iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_SIGN_INIT, 0, 1); iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_PRIVKEY_ID, 1, &privkey_idx); iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_MODE_OF_OPERATION, 1, @@ -659,10 +663,10 @@ static int iotsafe_sign_hash(byte privkey_idx, uint16_t hash_algo, iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_SIGN_ALGO, 1, &sign_algo); iotsafe_cmd_complete(csim_cmd); - if (sign_algo == IOTSAFE_SIGN_ECDSA) { - if (*sigLen < 2 * IOTSAFE_ECC_KSIZE) + if (*sigLen < 2 * IOTSAFE_ECC_KSIZE) { return -1; + } if (expect_ok(csim_cmd, (word32)XSTRLEN(csim_cmd)) <= 0) { WOLFSSL_MSG("Unexpected reply from IoTsafe EC sign"); return WC_HW_E; @@ -681,8 +685,8 @@ static int iotsafe_sign_hash(byte privkey_idx, uint16_t hash_algo, if (hex_to_bytes(resp, sig_hdr, 3) < 0) { ret = BAD_FUNC_ARG; } else if ((sig_hdr[0] == IOTSAFE_TAG_SIGNATURE_FIELD) && - (sig_hdr[1] == 0) && - (sig_hdr[2] == 2 * IOTSAFE_ECC_KSIZE)) { + (sig_hdr[1] == 0) && + (sig_hdr[2] == 2 * IOTSAFE_ECC_KSIZE)) { XSTRNCPY(R, resp + 6, IOTSAFE_ECC_KSIZE * 2); XSTRNCPY(S, resp + 6 + IOTSAFE_ECC_KSIZE * 2, IOTSAFE_ECC_KSIZE * 2); @@ -788,15 +792,22 @@ static int wolfIoT_ecc_keygen(WOLFSSL* ssl, struct ecc_key* key, { int ret; IOTSAFE *iotsafe = wolfSSL_get_iotsafe_ctx(ssl); - if (!iotsafe) + + if (iotsafe == NULL) { return BAD_FUNC_ARG; + } WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_keygen"); - (void)ctx; + +#ifdef DEBUG_IOTSAFE + printf("IOTSAFE PK ECC KeyGen: keySz %d, Curve ID %d, Slot %d\n", + keySz, ecc_curve, iotsafe->ecdh_keypair_slot); +#endif + if (iotsafe->enabled) { ret = iotsafe_gen_keypair(iotsafe->ecdh_keypair_slot); - if (ret < 0) - return ret; - ret = iotsafe_get_public_key(iotsafe->ecdh_keypair_slot, key); + if (ret == 0) { + ret = iotsafe_get_public_key(iotsafe->ecdh_keypair_slot, key); + } } else { WC_RNG *rng = wolfSSL_GetRNG(ssl); ret = wc_ecc_init(key); @@ -805,6 +816,7 @@ static int wolfIoT_ecc_keygen(WOLFSSL* ssl, struct ecc_key* key, ret = wc_ecc_make_key_ex(rng, keySz, key, ecc_curve); } } + (void)ctx; return ret; } @@ -817,40 +829,50 @@ static int wolfIoT_ecc_sign(WOLFSSL* ssl, { int ret; IOTSAFE *iotsafe = wolfSSL_get_iotsafe_ctx(ssl); - if (!iotsafe) + WC_RNG *rng; + word32 idx = 0; + ecc_key *myKey; + byte* keyBuf = (byte*)keyDer; +#ifndef WOLFSSL_SMALL_STACK + ecc_key _myKey; +#endif + + if (iotsafe == NULL) { return BAD_FUNC_ARG; - (void)ctx; + } WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_sign\n"); +#ifdef DEBUG_IOTSAFE + printf("IOTSAFE PK ECC Sign: InSz %d, KeySz %d\n", inSz, keySz); +#endif + if (iotsafe->enabled) { ret = iotsafe_sign_hash(iotsafe->privkey_id, IOTSAFE_HASH_SHA256, IOTSAFE_SIGN_ECDSA, in, inSz, out, outSz); return ret; - } else { - WC_RNG *rng; - word32 idx = 0; - ecc_key *myKey; - byte* keyBuf = (byte*)keyDer; -#ifndef WOLFSSL_SMALL_STACK - ecc_key _myKey; - myKey = &_myKey; -#else - myKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC); - if (myKey == NULL) - return MEMORY_E; -#endif - rng = wolfSSL_GetRNG(ssl); - ret = wc_ecc_init(myKey); - if (ret == 0) - ret = wc_EccPrivateKeyDecode(keyBuf, &idx, myKey, keySz); - if (ret == 0) - ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, myKey); - wc_ecc_free(myKey); -#ifdef WOLFSSL_SMALL_STACK - XFREE(myKey, NULL, DYNAMIC_TYPE_ECC); -#endif } + +#ifndef WOLFSSL_SMALL_STACK + myKey = &_myKey; +#else + myKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC); + if (myKey == NULL) + return MEMORY_E; +#endif + + rng = wolfSSL_GetRNG(ssl); + ret = wc_ecc_init(myKey); + if (ret == 0) + ret = wc_EccPrivateKeyDecode(keyBuf, &idx, myKey, keySz); + if (ret == 0) + ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, myKey); + wc_ecc_free(myKey); +#ifdef WOLFSSL_SMALL_STACK + XFREE(myKey, NULL, DYNAMIC_TYPE_ECC); +#endif + + (void)ctx; return ret; } @@ -865,19 +887,34 @@ static int wolfIoT_ecc_verify(WOLFSSL *ssl, ecc_key *key; word32 r_size = IOTSAFE_ECC_KSIZE, s_size = IOTSAFE_ECC_KSIZE; word32 inOutIdx = 0; - IOTSAFE *iot = wolfSSL_get_iotsafe_ctx(ssl); - byte pubkey_slot = iot->peer_cert_slot; + IOTSAFE *iotsafe = wolfSSL_get_iotsafe_ctx(ssl); + byte pubkey_slot; byte *sig_raw; #ifndef WOLFSSL_SMALL_STACK byte _sig_raw[IOTSAFE_ECC_KSIZE* 2]; ecc_key _key; + sig_raw = _sig_raw; key = &_key; - if (!iot) - return BAD_FUNC_ARG; -#else - if (!iot) +#endif + + if (iotsafe == NULL) { return BAD_FUNC_ARG; + } + + pubkey_slot = iotsafe->peer_cert_slot; + + WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_verify"); + +#ifdef DEBUG_IOTSAFE + printf("IOTSAFE PK ECC Verify: SigSz %d, HashSz %d, KeySz %d, Slot %d\n", + sigSz, hashSz, keySz, pubkey_slot); +#endif + + /* Invalidate verification, by default. */ + *result = 0; + +#ifdef WOLFSSL_SMALL_STACK sig_raw = (byte*)XMALLOC(IOTSAFE_ECC_KSIZE * 2, NULL, DYNAMIC_TYPE_SIGNATURE); if (sig_raw == NULL) return MEMORY_E; @@ -887,27 +924,27 @@ static int wolfIoT_ecc_verify(WOLFSSL *ssl, return MEMORY_E; } #endif - (void)ctx; + ret = wc_ecc_init(key); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_ECC); + XFREE(sig_raw, NULL, DYNAMIC_TYPE_SIGNATURE); + #endif + return ret; + } + + if (iotsafe->enabled) { + /* Store the server's public key in IoT-safe vault + * Create an ecc object to handle the key */ - /* Invalidate verification, by default. */ - *result = 0; - if (iot->enabled) { - WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_verify\n"); /* Convert ECC signature into R,S */ - ret = wc_ecc_sig_to_rs(sig, sigSz, sig_raw, &r_size, sig_raw - + IOTSAFE_ECC_KSIZE, &s_size); - if (ret < 0) { - WOLFSSL_MSG("Unable to convert signature to R+S"); - return ret; + ret = wc_ecc_sig_to_rs(sig, sigSz, + sig_raw, &r_size, + sig_raw + IOTSAFE_ECC_KSIZE, &s_size); + if (ret == 0) { + /* Import from keyDer argument */ + ret = wc_EccPublicKeyDecode(keyDer, &inOutIdx, key, keySz); } - /* Store the server's public key in IoT-safe vault */ - /* Create an ecc object to handle the key */ - ret = wc_ecc_init(key); - if (ret != 0) - return ret; - - /* Import from keyDer argument */ - ret = wc_EccPublicKeyDecode(keyDer, &inOutIdx, key, keySz); if (ret == 0) { /* Store public key in IoT-safe slot */ ret = iotsafe_put_public_key(pubkey_slot, key); @@ -919,20 +956,19 @@ static int wolfIoT_ecc_verify(WOLFSSL *ssl, hash, hashSz, sig_raw, 2 * IOTSAFE_ECC_KSIZE, result); } - } else { - word32 idx = 0; - ret = wc_ecc_init(key); - if (ret == 0) - ret = wc_EccPublicKeyDecode(keyDer, &idx, key, keySz); - if (ret == 0) - ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, - key); + } + else { + ret = wc_EccPublicKeyDecode(keyDer, &inOutIdx, key, keySz); + if (ret == 0) { + ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, key); + } } wc_ecc_free(key); #ifdef WOLFSSL_SMALL_STACK - XFREE(sig_raw, NULL, DYNAMIC_TYPE_SIGNATURE); XFREE(key, NULL, DYNAMIC_TYPE_ECC); + XFREE(sig_raw, NULL, DYNAMIC_TYPE_SIGNATURE); #endif + (void)ctx; return ret; } @@ -943,7 +979,7 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, { int ret; char *resp; - ecc_key *tmpKey; + ecc_key *tmpKey; IOTSAFE *iotsafe = wolfSSL_get_iotsafe_ctx(ssl); byte keypair_slot; byte pubkey_idx; @@ -951,8 +987,17 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, ecc_key _tmpKey; tmpKey = &_tmpKey; #endif - if (iotsafe == NULL) + + if (iotsafe == NULL) { return BAD_FUNC_ARG; + } + + WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_shared_secret\n"); + +#ifdef DEBUG_IOTSAFE + printf("IOTSAFE PK ECC PMS: Side %s, Peer Curve %d\n", + side == WOLFSSL_CLIENT_END ? "client" : "server", otherKey->dp->id); +#endif #ifdef WOLFSSL_SMALL_STACK tmpKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC); @@ -961,31 +1006,34 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, #endif ret = wc_ecc_init(tmpKey); if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(tmpKey, NULL, DYNAMIC_TYPE_ECC); + #endif return ret; } - (void)ctx; - WOLFSSL_MSG("IOTSAFE: Called wolfIoT_ecc_shared_secret\n"); if (iotsafe->enabled) { - WOLFSSL_MSG("Generating ECDH key pair"); keypair_slot = iotsafe->ecdh_keypair_slot; pubkey_idx = iotsafe->peer_pubkey_slot; - ret = iotsafe_gen_keypair(keypair_slot); - if (ret < 0) { - WOLFSSL_MSG("Error generating IoT-safe key pair"); - } - if (ret == 0) { - /* Importing generated public key */ - ret = iotsafe_get_public_key(keypair_slot, tmpKey); + /* TLS v1.3 calls key gen already, so don't do it here */ + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + WOLFSSL_MSG("Generating ECDH key pair"); + ret = iotsafe_gen_keypair(keypair_slot); if (ret < 0) { - ret = WC_HW_E; + WOLFSSL_MSG("Error generating IoT-safe key pair"); + } + if (ret == 0) { + /* Importing generated public key */ + ret = iotsafe_get_public_key(keypair_slot, tmpKey); + if (ret < 0) { + ret = WC_HW_E; + } + } + if (ret == 0) { + /* Exporting generated public key into DER buffer */ + ret = wc_ecc_export_x963(tmpKey, pubKeyDer, pubKeySz); } - } - - if (ret == 0) { - /* Exporting generated public key into DER buffer */ - ret = wc_ecc_export_x963(tmpKey, pubKeyDer, pubKeySz); } if (ret == 0) { @@ -1007,7 +1055,7 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, } } if (ret <= 0) { - WOLFSSL_MSG("Unexpected reply in DH command"); + WOLFSSL_MSG("Unexpected reply in ECDH command"); ret = WC_HW_E; } else { int out_len = hex_to_bytes(resp, out, ret / 2); @@ -1023,18 +1071,23 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, ecc_key* pubKey = NULL; /* for client: create and export public key */ if (side == WOLFSSL_CLIENT_END) { - WC_RNG *rng; privKey = tmpKey; pubKey = otherKey; - rng = wolfSSL_GetRNG(ssl); - ret = wc_ecc_make_key_ex(rng, 0, privKey, otherKey->dp->id); - if (ret == 0) - ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); + + /* TLS v1.3 calls key gen already, so don't do it here */ + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + WC_RNG *rng = wolfSSL_GetRNG(ssl); + ret = wc_ecc_make_key_ex(rng, 0, privKey, otherKey->dp->id); + if (ret == 0) { + ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); + } + } } /* for server: import public key */ else if (side == WOLFSSL_SERVER_END) { privKey = otherKey; pubKey = tmpKey; + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, otherKey->dp->id); } @@ -1050,6 +1103,7 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey, #ifdef WOLFSSL_SMALL_STACK XFREE(tmpKey, NULL, DYNAMIC_TYPE_ECC); #endif + (void)ctx; return ret; } @@ -1155,29 +1209,28 @@ void wolfIoTSafe_SetCSIM_write_cb(wolfSSL_IOTSafe_CSIM_write_cb wf) /* API to equip target wolfSSL CTX to the IoT-Safe subsystem. */ int wolfSSL_CTX_iotsafe_enable(WOLFSSL_CTX *ctx) { - - if ( !wolfIoT_initialized) - { + if ( !wolfIoT_initialized) { if (iotsafe_init() < 0) return WC_HW_E; } - #if defined(HAVE_PK_CALLBACKS) - #ifdef HAVE_ECC - wolfSSL_CTX_SetEccSignCb(ctx, wolfIoT_ecc_sign); - wolfSSL_CTX_SetEccVerifyCb(ctx, wolfIoT_ecc_verify); - wolfSSL_CTX_SetEccKeyGenCb(ctx, wolfIoT_ecc_keygen); - wolfSSL_CTX_SetEccSharedSecretCb(ctx, wolfIoT_ecc_shared_secret); - #ifndef NO_DH - wolfSSL_CTX_SetDhAgreeCb(ctx, wolfIoT_dh_agree); - #endif /* NO_DH */ - WOLFSSL_MSG("ECC callbacks set to IoT_safe interface"); - #endif - #ifndef NO_RSA - /* wolfSSL_CTX_SetRsaSignCb(wolfIoT_rsa_sign); // TODO: RSA callbacks */ - #endif - #else - (void)ctx; + +#if defined(HAVE_PK_CALLBACKS) + #ifdef HAVE_ECC + wolfSSL_CTX_SetEccSignCb(ctx, wolfIoT_ecc_sign); + wolfSSL_CTX_SetEccVerifyCb(ctx, wolfIoT_ecc_verify); + wolfSSL_CTX_SetEccKeyGenCb(ctx, wolfIoT_ecc_keygen); + wolfSSL_CTX_SetEccSharedSecretCb(ctx, wolfIoT_ecc_shared_secret); + #ifndef NO_DH + wolfSSL_CTX_SetDhAgreeCb(ctx, wolfIoT_dh_agree); + #endif /* NO_DH */ + WOLFSSL_MSG("ECC callbacks set to IoT_safe interface"); #endif + #ifndef NO_RSA + /* wolfSSL_CTX_SetRsaSignCb(wolfIoT_rsa_sign); // TODO: RSA callbacks */ + #endif +#else + (void)ctx; +#endif return 0; }