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.

pull/4250/head
David Garske 2021-08-16 13:05:56 -07:00
parent 490eeb4003
commit c8fd5d552e
7 changed files with 540 additions and 348 deletions

4
.gitignore vendored
View File

@ -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/

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 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 */

View File

@ -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;
#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;
}