forked from wolfSSL/wolfssl
Multiple fixes for IoT-SAFE
- Tested with a different SIM: - 16bit IDs - Directly retrieving public key from keygen function - larger response buffers (up to 256 bytes in ReadFile) - Fixed hardcoded length in ID buffers
This commit is contained in:
@@ -144,10 +144,10 @@ static int client_loop(void)
|
||||
int ret;
|
||||
const char* helloStr = "hello iot-safe wolfSSL";
|
||||
#if (IOTSAFE_ID_SIZE == 1)
|
||||
byte cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id;
|
||||
byte cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id, serv_cert_id;
|
||||
byte ca_cert_id;
|
||||
#else
|
||||
word16 cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id;
|
||||
word16 cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id, serv_cert_id;
|
||||
word16 ca_cert_id;
|
||||
#endif
|
||||
cert_file_id = CRT_CLIENT_FILE_ID;
|
||||
@@ -156,6 +156,7 @@ static int client_loop(void)
|
||||
peer_pubkey_id = PEER_PUBKEY_ID;
|
||||
peer_cert_id = PEER_CERT_ID;
|
||||
ca_cert_id = CRT_SERVER_FILE_ID;
|
||||
serv_cert_id = CRT_SERVER_FILE_ID;
|
||||
|
||||
|
||||
printf("=== CLIENT step %d ===\n", client_state);
|
||||
@@ -174,20 +175,44 @@ static int client_loop(void)
|
||||
wolfSSL_CTX_iotsafe_enable(cli_ctx);
|
||||
|
||||
printf("Loading CA\n");
|
||||
#ifdef SOFT_SERVER_CA
|
||||
ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
|
||||
sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Bad CA\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cert_buffer_size = wolfIoTSafe_GetCert_ex(&ca_cert_id,IOTSAFE_ID_SIZE,
|
||||
cert_buffer,
|
||||
sizeof(cert_buffer));
|
||||
#else
|
||||
cert_buffer_size = wolfIoTSafe_GetCert_ex(&ca_cert_id, IOTSAFE_ID_SIZE,
|
||||
cert_buffer,
|
||||
sizeof(cert_buffer));
|
||||
if (cert_buffer_size < 1) {
|
||||
printf("Bad server cert\n");
|
||||
return -1;
|
||||
}
|
||||
printf("Loaded Server CA from IoT-Safe, size = %lu\n",
|
||||
cert_buffer_size);
|
||||
#endif
|
||||
|
||||
|
||||
printf("Loading Server Certificate\n");
|
||||
#ifdef SOFT_SERVER_CERT
|
||||
/*
|
||||
ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, serv_ecc_der_256,
|
||||
sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Bad Server certificate!\n");
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
#else
|
||||
cert_buffer_size = wolfIoTSafe_GetCert_ex(&serv_cert_id,IOTSAFE_ID_SIZE,
|
||||
cert_buffer,
|
||||
sizeof(cert_buffer));
|
||||
if (cert_buffer_size < 1) {
|
||||
printf("Bad server certificate!\n");
|
||||
return -1;
|
||||
}
|
||||
printf("Loaded Server certificate from IoT-Safe, size = %lu\n",
|
||||
cert_buffer_size);
|
||||
if (wolfSSL_CTX_load_verify_buffer(cli_ctx, cert_buffer, cert_buffer_size,
|
||||
@@ -195,6 +220,7 @@ static int client_loop(void)
|
||||
printf("Cannot load server cert\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
printf("Server certificate successfully imported.\n");
|
||||
wolfSSL_CTX_set_verify(cli_ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
|
||||
@@ -381,7 +407,8 @@ int memory_tls_test(void)
|
||||
printf("Starting memory-tls test...\n");
|
||||
do {
|
||||
ret_s = server_loop();
|
||||
ret_c = client_loop();
|
||||
if (ret_s >= 0)
|
||||
ret_c = client_loop();
|
||||
} while ((ret_s >= 0) && (ret_c >= 0));
|
||||
|
||||
/* clean up */
|
||||
|
@@ -26,20 +26,31 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* Uncomment next line to enable 2-bytes ID demo */
|
||||
//#define TWO_BYTES_ID_DEMO
|
||||
/* #define TWO_BYTES_ID_DEMO */
|
||||
|
||||
|
||||
/* IOT-Safe slot configuration for this example
|
||||
/* IOT-Safe slot configurations for this example:
|
||||
* - TWO_BYTES_ID_DEMO: two-bytes ID sim, with hardcoded CA
|
||||
* - Default: one-byte ID sim, with hardcoded server certificate
|
||||
*/
|
||||
|
||||
#ifdef TWO_BYTES_ID_DEMO
|
||||
#define IOTSAFE_ID_SIZE 2
|
||||
#define CRT_CLIENT_FILE_ID 0x3430 /* pre-provisioned */
|
||||
#define CRT_SERVER_FILE_ID 0x3330
|
||||
#define PRIVKEY_ID 0x3230 /* pre-provisioned */
|
||||
#define PRIVKEY_ID 0x3230 /* pre-provisioned */
|
||||
#define ECDH_KEYPAIR_ID 0x3330
|
||||
#define PEER_PUBKEY_ID 0x3430
|
||||
#define PEER_CERT_ID 0x3530
|
||||
|
||||
/* In this version of the demo, the server certificate is
|
||||
* stored in a buffer, while the CA is read from a file slot in IoT-SAFE
|
||||
*/
|
||||
#define SOFT_SERVER_CERT
|
||||
|
||||
/* DELME */
|
||||
#define SOFT_SERVER_CA
|
||||
|
||||
#else
|
||||
#define IOTSAFE_ID_SIZE 1
|
||||
#define CRT_CLIENT_FILE_ID 0x03 /* pre-provisioned */
|
||||
@@ -48,6 +59,11 @@
|
||||
#define ECDH_KEYPAIR_ID 0x03
|
||||
#define PEER_PUBKEY_ID 0x04
|
||||
#define PEER_CERT_ID 0x05
|
||||
|
||||
/* In this version of the demo, the server certificate is
|
||||
* read from a file slot in IoT-SAFE, while the CA is stored in buffer in memory
|
||||
*/
|
||||
#define SOFT_SERVER_CA
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -70,7 +70,7 @@ static wolfSSL_IOTSafe_CSIM_write_cb csim_write_cb = NULL;
|
||||
#define CSIM_CMD_ENDSTR_SIZE 4
|
||||
|
||||
/* Buffer for CSIM RX APDU */
|
||||
#define MAXBUF 1024
|
||||
#define MAXBUF 2048
|
||||
static char csim_read_buf[MAXBUF];
|
||||
static char csim_cmd[IOTSAFE_CMDSIZE_MAX];
|
||||
|
||||
@@ -85,7 +85,9 @@ static int csim_read(char *buf, int len)
|
||||
|
||||
static int csim_write(const char *buf, int len)
|
||||
{
|
||||
//printf(">>> %s\n", buf);
|
||||
#ifdef DEBUG_IOTSAFE
|
||||
printf(">>> %s\n", buf);
|
||||
#endif
|
||||
if (csim_write_cb)
|
||||
return csim_write_cb(buf, len);
|
||||
else
|
||||
@@ -132,12 +134,12 @@ static int expect_tok(const char *cmd, int size, const char *tok, char **repl)
|
||||
}
|
||||
while (ret > 0) {
|
||||
ret = csim_read(csim_read_buf, MAXBUF);
|
||||
/*
|
||||
#ifdef DEBUG_IOTSAFE
|
||||
if (ret > 0)
|
||||
printf("<<< %s\n", csim_read_buf);
|
||||
else
|
||||
printf("<<< csim_read returned %d\n", ret);
|
||||
*/
|
||||
#endif
|
||||
if (tok && (ret > 0) && !r_found) {
|
||||
/* Mark the beginning of the match in the reply. */
|
||||
r_found = XSTRSTR(csim_read_buf, tok);
|
||||
@@ -352,6 +354,8 @@ static int expect_csim_response(const char *cmd, word32 size, char **reply)
|
||||
payload++;
|
||||
if (XSTRNCMP(payload, "61", 2) == 0) {
|
||||
if (hex_to_bytes(payload + 2, &len, 1) == 1) {
|
||||
if (len == 0)
|
||||
len = 256;
|
||||
iotsafe_cmd_start(csim_cmd,1,IOTSAFE_INS_GETRESPONSE, 0, 0);
|
||||
bytes_to_hex(&len, csim_cmd + AT_CSIM_CMD_SIZE + AT_CMD_LC_POS, 1);
|
||||
csim_cmd[AT_CSIM_CMD_SIZE + AT_CMD_HDR_SIZE] = 0;
|
||||
@@ -442,6 +446,7 @@ static int iotsafe_readfile(uint8_t *file_id, uint16_t file_id_sz,
|
||||
return -1;
|
||||
file_sz = (fs_msb << 8) + fs_lsb;
|
||||
WOLFSSL_MSG("Stat successful on file");
|
||||
printf("File size: %d (%04x)", file_sz, file_sz);
|
||||
}
|
||||
|
||||
if (file_sz > max_size) {
|
||||
@@ -459,8 +464,10 @@ static int iotsafe_readfile(uint8_t *file_id, uint16_t file_id_sz,
|
||||
iotsafe_cmd_complete(csim_cmd);
|
||||
ret = expect_csim_response(csim_cmd, (word32)XSTRLEN(csim_cmd), &resp);
|
||||
if (ret > 0) {
|
||||
/*
|
||||
if (ret > 2 * 0xF3)
|
||||
ret = 2 * 0xF3;
|
||||
*/
|
||||
if (ret > 2 * (file_sz - off))
|
||||
ret = 2 * (file_sz - off);
|
||||
if (hex_to_bytes(resp, content + off, (ret / 2)) < 0) {
|
||||
@@ -518,44 +525,16 @@ static int iotsafe_getrandom(unsigned char* output, unsigned long sz)
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
|
||||
static int iotsafe_gen_keypair(byte *wr_slot, unsigned long id_size)
|
||||
{
|
||||
char *resp;
|
||||
int ret = WC_HW_E;
|
||||
iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_GEN_KEYPAIR, 0, 0);
|
||||
iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_PRIVKEY_ID, id_size, wr_slot);
|
||||
iotsafe_cmd_complete(csim_cmd);
|
||||
if (expect_csim_response(csim_cmd, (word32)XSTRLEN(csim_cmd), &resp) < 1) {
|
||||
WOLFSSL_MSG("Unexpected reply from Keygen");
|
||||
ret = WC_HW_E;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iotsafe_get_public_key(byte *pubkey_id, unsigned long id_size,
|
||||
ecc_key *key)
|
||||
static int iotsafe_parse_public_key(char* resp, int len, ecc_key *key)
|
||||
{
|
||||
int ret;
|
||||
char *resp;
|
||||
char *rkey, *ktype, *payload_str;
|
||||
char Qx[IOTSAFE_ECC_KSIZE * 2 + 1], Qy[IOTSAFE_ECC_KSIZE * 2 + 1];
|
||||
|
||||
/* exporting generated public key */
|
||||
iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_READ_KEY,0, 0);
|
||||
iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_PUBKEY_ID, id_size, pubkey_id);
|
||||
iotsafe_cmd_complete(csim_cmd);
|
||||
ret = expect_csim_response(csim_cmd, (word32)XSTRLEN(csim_cmd), &resp);
|
||||
if (ret < 1) {
|
||||
WOLFSSL_MSG("Error exporting EPH public key from IoT-Safe");
|
||||
return WC_HW_E;
|
||||
}
|
||||
if (ret < IOTSAFE_TAG_ECC_KEY_FIELD_SZ + 2) {
|
||||
if (len < IOTSAFE_TAG_ECC_KEY_FIELD_SZ + 2) {
|
||||
WOLFSSL_MSG("Response from iot-safe: too short");
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
rkey = search_tlv(resp, ret, IOTSAFE_TAG_ECC_KEY_FIELD);
|
||||
rkey = search_tlv(resp, len, IOTSAFE_TAG_ECC_KEY_FIELD);
|
||||
if (rkey == NULL) {
|
||||
WOLFSSL_MSG("IoT safe Error in rkey response");
|
||||
return MISSING_KEY;
|
||||
@@ -588,9 +567,51 @@ static int iotsafe_get_public_key(byte *pubkey_id, unsigned long id_size,
|
||||
return ret;
|
||||
}
|
||||
WOLFSSL_MSG("Get Public key: OK");
|
||||
printf("public key: %s, %s\n", Qx, Qy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iotsafe_gen_keypair(byte *wr_slot, unsigned long id_size,
|
||||
ecc_key *key)
|
||||
{
|
||||
char *resp;
|
||||
int ret = WC_HW_E;
|
||||
iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_GEN_KEYPAIR, 0, 0);
|
||||
iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_PRIVKEY_ID, id_size, wr_slot);
|
||||
iotsafe_cmd_complete(csim_cmd);
|
||||
ret = expect_csim_response(csim_cmd, (word32)XSTRLEN(csim_cmd), &resp);
|
||||
if (ret < 1) {
|
||||
WOLFSSL_MSG("Unexpected reply from Keygen");
|
||||
ret = WC_HW_E;
|
||||
} else {
|
||||
if (!iotsafe_parse_public_key(resp, ret, key)) {
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iotsafe_get_public_key(byte *pubkey_id, unsigned long id_size,
|
||||
ecc_key *key)
|
||||
{
|
||||
int ret;
|
||||
char *resp;
|
||||
|
||||
/* exporting generated public key */
|
||||
iotsafe_cmd_start(csim_cmd, IOTSAFE_CLASS, IOTSAFE_INS_READ_KEY,0, 0);
|
||||
iotsafe_cmd_add_tlv(csim_cmd, IOTSAFE_TAG_PUBKEY_ID, id_size, pubkey_id);
|
||||
iotsafe_cmd_complete(csim_cmd);
|
||||
ret = expect_csim_response(csim_cmd, (word32)XSTRLEN(csim_cmd), &resp);
|
||||
if (ret < 1) {
|
||||
WOLFSSL_MSG("Error exporting EPH public key from IoT-Safe");
|
||||
return WC_HW_E;
|
||||
}
|
||||
|
||||
return iotsafe_parse_public_key(resp, ret, key);
|
||||
}
|
||||
|
||||
#define PUT_PK_SID 0x02
|
||||
static int iotsafe_put_public_key(byte *pubkey_id, unsigned long id_size,
|
||||
ecc_key *key)
|
||||
@@ -608,8 +629,8 @@ static int iotsafe_put_public_key(byte *pubkey_id, unsigned long id_size,
|
||||
|
||||
/* 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);
|
||||
ecc_pub_raw + 4 + id_size, &qxlen,
|
||||
ecc_pub_raw + 4 + id_size + IOTSAFE_ECC_KSIZE, &qylen);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("IoT Safe: Could not export public key: Error");
|
||||
return ret;
|
||||
@@ -858,7 +879,7 @@ static int wolfIoT_ecc_keygen(WOLFSSL* ssl, struct ecc_key* key,
|
||||
#endif
|
||||
|
||||
if (iotsafe->enabled) {
|
||||
ret = iotsafe_gen_keypair((byte *)&iotsafe->ecdh_keypair_slot, IOTSAFE_ID_SIZE);
|
||||
ret = iotsafe_gen_keypair((byte *)&iotsafe->ecdh_keypair_slot, IOTSAFE_ID_SIZE, key);
|
||||
if (ret == 0) {
|
||||
ret = iotsafe_get_public_key((byte *)&iotsafe->ecdh_keypair_slot,
|
||||
IOTSAFE_ID_SIZE, key);
|
||||
@@ -1080,26 +1101,38 @@ static int wolfIoT_ecc_shared_secret(WOLFSSL* ssl, struct ecc_key* otherKey,
|
||||
/* 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, id_size);
|
||||
ret = iotsafe_gen_keypair(keypair_slot, id_size, tmpKey);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Error generating IoT-safe key pair");
|
||||
}
|
||||
if (ret == 0) {
|
||||
WOLFSSL_MSG("Public key not yet retrieved, using GetPublic");
|
||||
/* Importing generated public key */
|
||||
ret = iotsafe_get_public_key(keypair_slot, id_size, tmpKey);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Error retrieving public key via GetPublic");
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
} else if (ret == 1) {
|
||||
ret = 0;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Exporting generated public key into DER buffer */
|
||||
ret = wc_ecc_export_x963(tmpKey, pubKeyDer, pubKeySz);
|
||||
if (ret == 0) {
|
||||
WOLFSSL_MSG("IoT-SAFE: Key pair generated, public key exported");
|
||||
} else {
|
||||
WOLFSSL_MSG("IoT-SAFE: Error storing Public key.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Store received public key from other endpoint in applet */
|
||||
ret = iotsafe_put_public_key(pubkey_idx, id_size, otherKey);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("IoT-SAFE: Error in PutPublic");
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
do {
|
||||
@@ -1243,7 +1276,11 @@ int wc_iotsafe_ecc_verify_hash_ex(byte *sig, word32 siglen, byte *hash,
|
||||
|
||||
int wc_iotsafe_ecc_gen_k_ex(byte *key_id, uint16_t id_size)
|
||||
{
|
||||
return iotsafe_gen_keypair(key_id, id_size);
|
||||
int ret = 0;
|
||||
ecc_key* key = XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
|
||||
ret = iotsafe_gen_keypair(key_id, id_size, key);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_ECC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_iotsafe_ecc_import_public(ecc_key *key, byte key_id)
|
||||
@@ -1272,7 +1309,11 @@ int wc_iotsafe_ecc_verify_hash(byte *sig, word32 siglen, byte *hash,
|
||||
}
|
||||
int wc_iotsafe_ecc_gen_k(byte key_id)
|
||||
{
|
||||
return iotsafe_gen_keypair(&key_id, 1);
|
||||
int ret = 0;
|
||||
ecc_key* key = XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
|
||||
ret = iotsafe_gen_keypair(&key_id, 1, key);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_ECC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC */
|
||||
@@ -1369,6 +1410,7 @@ int wolfSSL_iotsafe_on_ex(WOLFSSL *ssl, byte *privkey_id,
|
||||
(void)ecdh_keypair_slot;
|
||||
(void)peer_cert_slot;
|
||||
(void)peer_pubkey_slot;
|
||||
(void)id_size;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user