Browse Source

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.

David Garske 2 years ago
parent
commit
c8fd5d552e
7 changed files with 536 additions and 344 deletions
  1. 4 0
      .gitignore
  2. 2 1
      IDE/iotsafe/Makefile
  3. 95 14
      IDE/iotsafe/README.md
  4. 128 101
      IDE/iotsafe/memory-tls.c
  5. 1 1
      IDE/iotsafe/target.ld
  6. 65 39
      IDE/iotsafe/user_settings.h
  7. 241 188
      wolfcrypt/src/port/iotsafe/iotsafe.c

+ 4 - 0
.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/

+ 2 - 1
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

+ 95 - 14
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

+ 128 - 101
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;
+    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");
+
+            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;
+        }
     }
-    /* clean up */
-    wolfSSL_free(cli_ssl);
-    wolfSSL_CTX_free(cli_ctx);
-    return 1;
-}
 
-uint8_t srv_cert[1260];
-uint32_t srv_cert_size;
+    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;
 }

+ 1 - 1
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

+ 65 - 39
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 <stdint.h>
 
+/* 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 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
+#define NO_ASN_TIME
 
-/* SP math */
+/* Math */
+#define TFM_TIMING_RESISTANT
+#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 */

+ 241 - 188
wolfcrypt/src/port/iotsafe/iotsafe.c

@@ -22,7 +22,9 @@
 /* IoT-safe module for communication with IoT-safe applet on SIM card */
 
 #include <wolfssl/wolfcrypt/settings.h>
+
 #ifdef WOLFSSL_IOTSAFE
+
 #include <wolfssl/wolfcrypt/random.h>
 #include <wolfssl/wolfcrypt/ecc.h>
 #include <wolfssl/wolfcrypt/error-crypt.h>
@@ -30,6 +32,17 @@
 #include <wolfssl/wolfcrypt/port/iotsafe/iotsafe.h>
 #include <wolfssl/internal.h>
 
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef DEBUG_IOTSAFE
+#include <stdio.h>
+#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;
+    myKey = &_myKey;
 #else
-        myKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
-        if (myKey == NULL)
-            return MEMORY_E;
+    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);
+
+    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);
+    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;
 }