From 9c6c6cae6350d35572f1abb8576ea98f1038ee4e Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Tue, 29 Aug 2023 11:21:14 -0400 Subject: [PATCH 01/10] Update to include initial provisioning support --- ccb_vaultic/Makefile | 10 +- ccb_vaultic/ccb_vaultic.c | 898 ++++++++++++++++++++++++++++--- ccb_vaultic/ccb_vaultic.h | 186 ++++++- ccb_vaultic/ccb_vaultic_config.h | 299 ++++++++++ ccb_vaultic/main-load.c | 160 ++++++ ccb_vaultic/main-prov.c | 124 +++++ 6 files changed, 1593 insertions(+), 84 deletions(-) create mode 100644 ccb_vaultic/ccb_vaultic_config.h create mode 100644 ccb_vaultic/main-load.c create mode 100644 ccb_vaultic/main-prov.c diff --git a/ccb_vaultic/Makefile b/ccb_vaultic/Makefile index c17b79680..bc6162911 100644 --- a/ccb_vaultic/Makefile +++ b/ccb_vaultic/Makefile @@ -53,7 +53,7 @@ TEST_OBJS:=$(WOLFSSL_DIR)/wolfcrypt/test/test.o main-test.o BENCH_OBJS:=$(WOLFSSL_DIR)/wolfcrypt/benchmark/benchmark.o main-bench.o #Makefile rules -all: wolfcrypt-test wolfcrypt-benchmark +all: wolfcrypt-test wolfcrypt-benchmark vlt-load vlt-prov wolfcrypt-test: $(OBJS) $(TEST_OBJS) $(CC) -o $@ $^ $(LDFLAGS) @@ -61,7 +61,13 @@ wolfcrypt-test: $(OBJS) $(TEST_OBJS) wolfcrypt-benchmark: $(OBJS) $(BENCH_OBJS) $(CC) -o $@ $^ $(LDFLAGS) +vlt-load: $(OBJS) main-load.o + $(CC) -o $@ $^ $(LDFLAGS) + +vlt-prov: $(OBJS) main-prov.o + $(CC) -o $@ $^ $(LDFLAGS) + clean: - rm -f *.o *.d wolfcrypt-test wolfcrypt-benchmark + rm -f *.o *.d wolfcrypt-test wolfcrypt-benchmark vlt-load vlt-prov rm -f $(WOLFSSL_DIR)/wolfcrypt/benchmark/*.o rm -f $(WOLFSSL_DIR)/wolfcrypt/test/*.o diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index 74e51994f..b65196412 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -67,6 +67,9 @@ /* Local include */ #include "ccb_vaultic.h" +/* Provide default config struct if needed */ +static const ccbVaultIc_Config gDefaultConfig = CCBVAULTIC_CONFIG_DEFAULT; + /* Debug defines */ #ifdef CCBVAULTIC_DEBUG_ALL #ifndef CCBVAULTIC_DEBUG @@ -84,45 +87,66 @@ #endif - /* wolfcrypt includes */ -#include "wolfssl/wolfcrypt/types.h" /* types and X-defines */ +#include "wolfssl/wolfcrypt/types.h" /* types and X-defines */ -#ifndef CCBVAULTIC_NO_SHA -#include "wolfssl/wolfcrypt/hash.h" /* For HASH_FLAGS and types */ -#endif +#include "wolfssl/wolfcrypt/hmac.h" /* For HMACSHA256 */ +/* Always need hash and hmac for kdf auth */ +#include "wolfssl/wolfcrypt/hash.h" /* For HASH_FLAGS and types */ #ifndef CCBVAULTIC_NO_RSA -#include "wolfssl/wolfcrypt/rsa.h" /* For RSA_MAX_SIZE and types */ +#include "wolfssl/wolfcrypt/rsa.h" /* For RSA_MAX_SIZE and types */ #endif #ifndef CCBVAULTIC_NO_AES -#include "wolfssl/wolfcrypt/aes.h" /* For AES_BLOCK_SIZE and types */ +#include "wolfssl/wolfcrypt/aes.h" /* For AES_BLOCK_SIZE and types */ #endif -#ifdef CCBVAULTIC_DEBUG_TIMING - #ifndef XNOW - #include - #include - #define XNOW(...) _now(__VA_ARGS__) - - static uint64_t _now(void) - { - struct timespec t; - if (clock_gettime(CLOCK_MONOTONIC, &t) < 0) - /* Return 0 on error */ - return 0; - return (uint64_t)t.tv_sec * 1000000000ull + t.tv_nsec; - } - #endif +#if defined(CCBVAULTIC_DEBUG_TIMING) && !defined(XNOW) +#include +#include +#define XNOW(...) _Now(__VA_ARGS__) + +static uint64_t _Now(void) +{ + struct timespec t; + if (clock_gettime(CLOCK_MONOTONIC, &t) < 0) + /* Return 0 on error */ + return 0; + return (uint64_t)t.tv_sec * 1000000000ull + t.tv_nsec; +} +#endif + +#ifdef CCBVAULTIC_DEBUG +/* Helper to provide simple _HexDump */ +static void _HexDump(const char* p, size_t data_len) +{ + XPRINTF(" HD:%p for %lu bytes\n",p, data_len); + if ( (p == NULL) || (data_len == 0)) + return; + size_t off = 0; + for (off = 0; off < data_len; off++) + { + if ((off % 16) == 0) + XPRINTF(" "); + XPRINTF("%02X ", p[off]); + if ((off % 16) == 15) + XPRINTF("\n"); + } + if ( (off%16) != 15) + XPRINTF("\n"); +} #endif + /* WiseKey VaultIC includes */ #include "vaultic_tls.h" #include "vaultic_config.h" #include "vaultic_common.h" #include "vaultic_api.h" #include "vaultic_structs.h" +#include "auth/vaultic_identity_authentication.h" +#include "vaultic_file_system.h" /* Key/Group ID's to support temporary wolfSSL usage */ #define CCBVAULTIC_WOLFSSL_GRPID 0xBB @@ -135,29 +159,8 @@ #define VAULTIC_PKV_ASSURED VLT_PKV_ASSURED_EXPLICIT_VALIDATION -#ifdef CCBVAULTIC_DEBUG -/* Helper to provide simple hexdump */ -static void hexdump(const unsigned char* p, size_t len) -{ - XPRINTF(" HD:%p for %lu bytes\n",p, len); - if ( (p == NULL) || (len == 0)) - return; - size_t off = 0; - for (off = 0; off < len; off++) - { - if ((off % 16) == 0) - XPRINTF(" "); - XPRINTF("%02X ", p[off]); - if ((off % 16) == 15) - XPRINTF("\n"); - } - if ( (off%16) != 15) - XPRINTF("\n"); -} -#endif - /* Helper to translate vlt return codes to wolfSSL code */ -static int translateError(int vlt_rc) +static int _TranslateError(int vlt_rc) { /* vlt return codes are defined in src/common/vaultic_err.h */ switch (vlt_rc) { @@ -165,14 +168,296 @@ static int translateError(int vlt_rc) case VLT_OK: return 0; default: - /* Default to point to hardware */ - return WC_HW_E; + /* Default to point to IO */ + return IO_FAILED_E; + } +} + +static int _GetInfo(ccbVaultIc_Context *c, VLT_TARGET_INFO *out_chipInfo) +{ + if ((c == NULL) || (out_chipInfo == NULL)) { + return BAD_FUNC_ARG; + } + XMEMSET(out_chipInfo, 0, sizeof(*out_chipInfo)); + + /* Get current chip info */ + c->vlt_rc = VltGetInfo(out_chipInfo); +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_GetInfo: vlt_rc:%04X serial:%p firmware:%.*s, \n" \ + "mode:%d, state:%02X, selftests:%d, space:%d\n", + c->vlt_rc, out_chipInfo->au8Serial, + (int)sizeof(out_chipInfo->au8Firmware), out_chipInfo->au8Firmware, + out_chipInfo->enMode, out_chipInfo->enState, out_chipInfo->enSelfTests, + (int)out_chipInfo->u32Space); + _HexDump((const char*)out_chipInfo->au8Serial, sizeof(out_chipInfo->au8Serial)); +#endif + return _TranslateError(c->vlt_rc); +} + +static VLT_USER_ID _AuthId2VltUserId(int id) +{ + switch(id) { + case 0: return VLT_USER0; + case 1: return VLT_USER1; + case 2: return VLT_USER2; + case 3: return VLT_USER3; + case 4: return VLT_USER4; + case 5: return VLT_USER5; + case 6: return VLT_USER6; + case 7: + default: break; + } + return VLT_USER7; +} +static VLT_ROLE_ID _AuthRole2VltRoleId(int role) +{ + switch(role) { + case CCBVAULTIC_AUTH_ROLE_NONE: return VLT_EVERYONE; + case CCBVAULTIC_AUTH_ROLE_APPROVED: return VLT_APPROVED_USER; + case CCBVAULTIC_AUTH_ROLE_UNAPPROVED: return VLT_NON_APPROVED_USER; + case CCBVAULTIC_AUTH_ROLE_MANUFACTURER: return VLT_MANUFACTURER; + default: + break; } + return VLT_EVERYONE; } -static void clearContext(ccbVaultIc_Context *c) +/* Perform HMAC SHA256 on input data to generate 2 keys up to 32 bytes total */ +static int _PerformKdf(int key_len, const char* key, + int in1_len, const char* in1, + int in2_len, const char* in2, + int in3_len, const char* in3, + int out1_len, char* out1, + int out2_len, char* out2) { + Hmac kdf; + int rc; + if ( (key_len == 0) || (key == NULL) || /* Key is required */ + ((in1_len <= 0) && (in1 == NULL)) || + ((in2_len <= 0) && (in2 == NULL)) || + ((in3_len <= 0) && (in3 == NULL)) || + ((out1_len <= 0) && (out1 == NULL)) || + ((out2_len <= 0) && (out2 == NULL)) ){ + return BAD_FUNC_ARG; + } + + rc = wc_HmacInit(&kdf, NULL, INVALID_DEVID); + if (rc == 0) { + int out_count=0; + byte digest[WC_SHA256_DIGEST_SIZE]; + XMEMSET(digest, 0, sizeof(digest)); + + rc = wc_HmacSetKey(&kdf, WC_SHA256, (const byte*)key, key_len); + if (rc == 0) { + rc = wc_HmacUpdate(&kdf, (const byte*)in1, in1_len); + } + if ((rc == 0) && (in2_len > 0) && (in2 != NULL)) { + rc = wc_HmacUpdate(&kdf, (const byte*)in2, in2_len); + } + if ((rc == 0) && (in3_len > 0) && (in3 != NULL)) { + rc = wc_HmacUpdate(&kdf, (const byte*)in3, in3_len); + } + if (rc == 0) { + rc = wc_HmacFinal(&kdf, digest); + if ((rc == 0) && (out1_len > 0)) { + int this_len = sizeof(digest) - out_count; + if (this_len > out1_len) this_len = out1_len; + XMEMCPY(out1, &digest[out_count], this_len); + XMEMSET(out1 + this_len, 0, out1_len - this_len); + out_count += this_len; + } + if ((rc == 0) && (out2_len > 0)) { + int this_len = sizeof(digest) - out_count; + if (this_len > out2_len) this_len = out2_len; + XMEMCPY(out2, &digest[out_count], this_len); + XMEMSET(out2 + this_len, 0, out2_len - this_len); + out_count += this_len; + } + } + wc_HmacFree(&kdf); + } +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_PerformKdf: rc:%d key_len:%d key:%p, \n" + "in1_len:%d in1:%p, in2_len:%d in2:%p,in3_len:%d in3:%p \n" + "out1_len:%d out1:%p, out2_len:%d out2:%p,\n", + rc, key_len, key, + in1_len, in1, in2_len, in2, in3_len, in3, + out1_len, out1, out2_len, out2); + _HexDump(key, key_len); + _HexDump(in1, in1_len); + _HexDump(in2, in2_len); + _HexDump(in3, in3_len); + _HexDump(out1, out1_len); + _HexDump(out2, out2_len); +#endif + + return rc; +} + +static int _AuthByPin( ccbVaultIc_Context *c, int id, int role, + int pin_len, const char* pin) +{ + if ((pin_len > CCBVAULTIC_AUTH_PIN_LEN_MAX) || + (pin_len < CCBVAULTIC_AUTH_PIN_LEN_MIN)) { + return BAD_FUNC_ARG; + } +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_AuthByPin: c:%p id:%d role:%d, pin_len:%d pin:%p\n", + c, id, role, pin_len, pin); + _HexDump(pin, pin_len); +#endif + /* Auth using password. */ + c->vlt_rc= VltSubmitPassword( + _AuthId2VltUserId(id), + _AuthRole2VltRoleId(role), + (VLT_U8) pin_len, + (VLT_PU8) pin); + return _TranslateError(c->vlt_rc); +} + +static int _AuthByScp03( ccbVaultIc_Context *c, int id, int role, + int mac_len, char* mac, + int enc_len, char* enc) +{ + KEY_BLOB macKey; + KEY_BLOB encKey; + KEY_BLOB_ARRAY keys; + +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_AuthByScp03: c:%p id:%d, role:%d, " + " mac_len:%d mac:%p, enc_len:%d enc:%p\n", + c, id, role, + mac_len, mac, enc_len, enc); + _HexDump(mac, mac_len); + _HexDump(enc, enc_len); +#endif + XMEMSET(&macKey, 0, sizeof(macKey)); + XMEMSET(&encKey, 0, sizeof(encKey)); + XMEMSET(&keys, 0, sizeof(keys)); + + macKey.keyType = VLT_KEY_AES_128; + macKey.keySize = (VLT_U16) mac_len; + macKey.keyValue = (VLT_PU8) mac; + + encKey.keyType = VLT_KEY_AES_128; + encKey.keySize = (VLT_U16) enc_len; + encKey.keyValue = (VLT_PU8) enc; + + keys.u8ArraySize = 2; + keys.pKeys[0] = &macKey; + keys.pKeys[1] = &encKey; + + c->vlt_rc=VltAuthInit( + VLT_AUTH_SCP03, + _AuthId2VltUserId(id), + _AuthRole2VltRoleId(role), + VLT_CMAC_CENC_RMAC_RENC, + keys); + return _TranslateError(c->vlt_rc); +} + +static int _AuthByKdf( ccbVaultIc_Context *c, int id, int role, + int key_len, const char* key, + int label_len, const char* label) +{ + char mac_data[CCBVAULTIC_AUTH_MAC_LEN]; + char enc_data[CCBVAULTIC_AUTH_ENC_LEN]; + +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_AuthByKdf: c:%p id:%d role:%d, " + "key_len:%d key:%p, label_len:%d label:%p\n", + c, id, role, + key_len, key, label_len, label); + _HexDump(key, key_len); + _HexDump(label, label_len); +#endif + + int rc = _PerformKdf( key_len, key, + label_len, label, + CCBVAULTIC_SERIAL_LEN, c->vlt_serial, + CCBVAULTIC_VERSION_LEN, c->vlt_version, + sizeof(mac_data), mac_data, + sizeof(enc_data), enc_data); + if (rc == 0) { + rc = _AuthByScp03( c, id, role, + sizeof(mac_data), mac_data, + sizeof(enc_data), enc_data); + } + return rc; +} + +/* Helper to perform auth as the provided user */ +static int _InitAuth(ccbVaultIc_Context *c, const ccbVaultIc_Auth *a) +{ + int rc = 0; + if ((c == NULL) || (c->initialized != 0) || (a == NULL)) { + return BAD_FUNC_ARG; + } + +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("_InitAuth: c:%p a:%p kind:%d\n", + c, a, a->kind); +#endif + + switch(a->kind) { + case CCBVAULTIC_AUTH_KIND_NONE: + { + /* Ok. Unexpected, but not an error */ + rc = 0; + }; break; + + case CCBVAULTIC_AUTH_KIND_PIN: + { + rc = _AuthByPin(c, a->id, a->role, + a->auth.pin.pin_len,a->auth.pin.pin); + };break; + + case CCBVAULTIC_AUTH_KIND_SCP03: + { + char mac_data[CCBVAULTIC_AUTH_MAC_LEN]; + char enc_data[CCBVAULTIC_AUTH_ENC_LEN]; + + if ( (a->auth.scp03.mac_len < sizeof(mac_data)) || + (a->auth.scp03.enc_len < sizeof(enc_data))) { + rc = BAD_FUNC_ARG; + break; + } + + /* Copy to temp buffer to support const auth */ + XMEMCPY(mac_data, a->auth.scp03.mac, sizeof(mac_data)); + XMEMCPY(enc_data, a->auth.scp03.enc, sizeof(enc_data)); + rc = _AuthByScp03( c, a->id, a->role, + sizeof(mac_data), mac_data, + sizeof(enc_data), enc_data); + };break; + + case CCBVAULTIC_AUTH_KIND_KDF: + { + rc = _AuthByKdf( c, a->id, a->role, + a->auth.kdf.key_len, a->auth.kdf.key, + a->auth.kdf.label_len, a->auth.kdf.label); + };break; + + default: + rc = BAD_FUNC_ARG; + } + return rc; +} + +/* Helper to check for NULL and uninitialized contexts */ +static int _CheckInitializedContext(ccbVaultIc_Context *c) +{ + if ((c == NULL) || (c->initialized == 0)) { + return BAD_FUNC_ARG; + } + return 0; +} + +static void _ClearContext(ccbVaultIc_Context *c) +{ + const ccbVaultIc_Config* saveConfig = c->config; XMEMSET(c, 0, sizeof(*c)); + c->config=saveConfig; c->m = NULL; c->aescbc_key = NULL; } @@ -181,28 +466,82 @@ int ccbVaultIc_Init(ccbVaultIc_Context *c) { int rc = 0; if (c == NULL) { - rc = BAD_FUNC_ARG; + return BAD_FUNC_ARG; } /* Already Initialized? */ - if ((rc == 0) && (c->initialized >0)) { + if (c->initialized > 0) { /* Increment use count */ c->initialized++; return 0; } + _ClearContext(c); + + /* Open the hardware and authenticate */ +#if 0 + c->vlt_rc = vlt_tls_init(); + rc = _TranslateError(c->vlt_rc); +#else + const ccbVaultIc_Config* config = &gDefaultConfig; + VLT_INIT_COMMS_PARAMS params; + + + /* Override config */ + if (c->config != NULL) { + config = c->config; + } + + /* Set timeout, checksum, and interface type */ + XMEMSET(¶ms, 0, sizeof(params)); + params.VltBlockProtocolParams.u16msSelfTestDelay = config->startup_delay_ms; + params.VltBlockProtocolParams.u32msTimeout = config->timeout_ms; + params.VltBlockProtocolParams.enCheckSumMode = BLK_PTCL_CHECKSUM_SUM8; + params.enCommsProtocol = VLT_SPI_COMMS; + params.VltSpiParams.u16BitRate = config->spi_rate_khz; + + /* Initialize the API and establish comms*/ + c->vlt_rc = VltApiInit(¶ms); + rc = _TranslateError(c->vlt_rc); if (rc == 0) { - clearContext(c); - /* Open the hardware and authenticate */ - c->vlt_rc = vlt_tls_init(); - rc = translateError(c->vlt_rc); + VLT_TARGET_INFO chipInfo; + + /* Cancel any active authentication, Ignore errors here */ + VltAuthClose(); + + /* Get current chip info */ + rc = _GetInfo(c, &chipInfo); + if (rc == 0) { +#ifdef CCBVAULTIC_DEBUG + XPRINTF("ccbVaultIc_Info: serial:%p firmware:%.*s, \n" \ + "mode:%d, state:%d, selftests:%d, space:%d\n", + chipInfo.au8Serial, + (int)sizeof(chipInfo.au8Firmware), chipInfo.au8Firmware, + chipInfo.enMode, chipInfo.enState, chipInfo.enSelfTests, + (int)chipInfo.u32Space); + _HexDump((const char*)chipInfo.au8Serial, sizeof(chipInfo.au8Serial)); +#endif + + /* Save this data to the context */ + XMEMCPY(c->vlt_serial, chipInfo.au8Serial, sizeof(chipInfo.au8Serial)); + XMEMCPY(c->vlt_version, chipInfo.au8Firmware, sizeof(chipInfo.au8Firmware)); + + /* Ensure chip is not TERMINATED and no one is auth'ed */ + if ( (chipInfo.enState == VLT_STATE_TERMINATED) || + (chipInfo.enRole != VLT_EVERYONE)){ + /* Nothing to do. Return hardware error */ + rc = WC_HW_E; + } + if (rc == 0) { + rc = _InitAuth(c, &config->auth); + } + } } +#endif + if (rc == 0) { c->initialized = 1; } - else { - /* Override with an init error */ - rc = WC_INIT_E; - } + #ifdef CCBVAULTIC_DEBUG XPRINTF("ccbVaultIc_Init: c:%p c->initialized:%d rc:%d vlt_rc:%d\n", c, @@ -236,13 +575,416 @@ void ccbVaultIc_Cleanup(ccbVaultIc_Context *c) if (c->aescbc_key != NULL) XFREE(c->aescbc_key, NULL, NULL); - clearContext(c); + _ClearContext(c); /* Set the return value in the struct */ /* Close the hardware */ c->vlt_rc = vlt_tls_close(); } +/* Helper. Missing XSTRNLEN */ +static int ccbVaultIc_Strnlen(const char *s, int n) +{ + int len = 0; + while( (len < n) && (s[len] != 0)) { + len++; + } + return len; +} + +static int _CheckFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f, + int userId, int adminId) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + if ( (f == NULL) || + (f->name_len < CCBVAULTIC_FILE_NAME_LEN_MIN) || + (f->name_len > CCBVAULTIC_FILE_NAME_LEN_MAX) || + (f->data_len > CCBVAULTIC_FILE_DATA_LEN_MAX) || + (userId < CCBVAULTIC_AUTH_ID_MIN) || + (userId > CCBVAULTIC_AUTH_ID_MAX) || + (adminId < CCBVAULTIC_AUTH_ID_MIN) || + (adminId > CCBVAULTIC_AUTH_ID_MAX)) { + rc = BAD_FUNC_ARG; + } + } + return rc; +} + +static int _OpenFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f, + int *out_dataLen) +{ + int rc = _CheckFile(c, f, + CCBVAULTIC_AUTH_ID_MIN, CCBVAULTIC_AUTH_ID_MIN /* Dummy Ids */ + ); + if (rc == 0) { + VLT_FS_ENTRY_PARAMS structFileEntry; + XMEMSET(&structFileEntry, 0, sizeof(structFileEntry)); + + c->vlt_rc = VltFsOpenFile( + (VLT_U16)f->name_len, + (VLT_U8*)f->name, + (VLT_BOOL)FALSE, /* No transaction */ + &structFileEntry); + rc = _TranslateError(c->vlt_rc); + +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("ccbVaultIc_OpenFile rc:%d (%x) c:%p f:%p name_len:%d name:%.*s, data_len:%d data:%p\n", + rc, c->vlt_rc, c, f, f->name_len, (int)f->name_len, f->name, f->data_len, f->data); +#endif + /* Update output on success */ + if ((rc == 0) && (out_dataLen != NULL)) { + *out_dataLen = structFileEntry.u32FileSize; + } + } + return rc; +} + +static void _SetVltUserAccessBit(VLT_USER_ACCESS* u, int userId) +{ + if (u == NULL) { + return; + } + switch(userId) { + case 0: u->user0 = 1; return; + case 1: u->user1 = 1; return; + case 2: u->user2 = 1; return; + case 3: u->user3 = 1; return; + case 4: u->user4 = 1; return; + case 5: u->user5 = 1; return; + case 6: u->user6 = 1; return; + case 7: u->user7 = 1; return; + default: break; + } +} + +int ccbVaultIc_CreateUserFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f, + int userId, int adminId) +{ + int rc = _CheckFile(c, f, userId, adminId); + if (rc == 0) { + VLT_USER_ACCESS priv; + VLT_FS_ENTRY_PARAMS entryParams; + + XMEMSET(&priv, 0, sizeof(priv)); + XMEMSET(&entryParams, 0, sizeof(entryParams)); + + /* All privileges for the user and the admin */ + _SetVltUserAccessBit(&priv, userId); + _SetVltUserAccessBit(&priv, adminId); + entryParams.filePriv.readPrivilege = priv; + entryParams.filePriv.writePrivilege = priv; + entryParams.filePriv.deletePrivilege = priv; + entryParams.filePriv.executePrivilege = priv; + entryParams.attribs.readOnly = 0; /* Read/Write */ + entryParams.attribs.system = 0; /* Non-system */ + entryParams.attribs.hidden = 0; /* Visible */ + entryParams.u32FileSize = 0; /* Empty */ + entryParams.u8EntryType = VLT_FILE_ENTRY; + + c->vlt_rc = VltFsCreate( + (VLT_U16)f->name_len, + (VLT_PU8)f->name, + &entryParams, + (VLT_USER_ID) userId); /* Owner */ + rc = _TranslateError(c->vlt_rc); +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("ccbVaultIc_CreateUserFile rc:%d (%x) c:%p f:%p name_len:%d name:%.*s\n", + rc, c->vlt_rc, c, f, f->name_len, (int)f->name_len, f->name); +#endif + } + return rc; +} + +int ccbVaultIc_DeleteFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f) +{ + + int rc = _CheckFile(c, f, + CCBVAULTIC_AUTH_ID_MIN, CCBVAULTIC_AUTH_ID_MIN /* Dummy Ids */ + ); + if (rc == 0) { + c->vlt_rc = VltFsDelete( + (VLT_U16)f->name_len, + (VLT_U8*)f->name, + (VLT_BOOL)FALSE); /* Not recursive */ + rc = _TranslateError(c->vlt_rc); +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("ccbVaultIc_DeleteFile rc:%d (%x) c:%p f:%p name_len:%d name:%.*s\n", + rc, c->vlt_rc, c, f, f->name_len, (int)f->name_len, f->name); +#endif + } + return rc; +} + +int ccbVaultIc_WriteFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f) +{ + int rc = _OpenFile(c, f, NULL); + if (rc == 0) { + c->vlt_rc = VltFsWriteFile( + (VLT_U32)VLT_SEEK_FROM_START, + (VLT_U8*)f->data, + (VLT_U32)f->data_len, + (VLT_BOOL)TRUE); /* Reclaim space */ + rc = _TranslateError(c->vlt_rc); +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("ccbVaultIc_WriteFile rc:%d (%x) c:%p f:%p name_len:%d name:%.*s, data_len:%d data:%p\n", + rc, c->vlt_rc, c, f, f->name_len, (int)f->name_len, f->name, f->data_len, f->data); + _HexDump(f->data, f->data_len); +#endif + + /* Close and ignore error here */ + VltFsCloseFile(); + } + return rc; +} + +int ccbVaultIc_ReadFile( ccbVaultIc_Context *c, + ccbVaultIc_File *f) +{ + int fileLen = 0; + int maxLen = f->data_len; + int rc = _OpenFile(c, f, &fileLen); + if (rc == 0) { + VLT_U32 readLen = fileLen; + if (readLen > maxLen) { + readLen = maxLen; + } + + /* Reset file struct data */ + XMEMSET(f->data, 0, maxLen); + + c->vlt_rc = VltFsReadFile( + (VLT_U32)VLT_SEEK_FROM_START, + (VLT_U8*) f->data, + &readLen); + rc = _TranslateError(c->vlt_rc); + + if (rc == 0) { + /* Success. Update file struct */ + f->data_len = readLen; + } +#ifdef CCBVAULTIC_DEBUG_ALL + XPRINTF("ccbVaultIc_ReadFile rc:%d (%x) c:%p f:%p name_len:%d name:%.*s, data_len:%d data:%p\n", + rc, c->vlt_rc, c, f, f->name_len, (int)f->name_len, f->name, f->data_len, f->data); + _HexDump(f->data, f->data_len); +#endif + + /* Close and ignore error here */ + VltFsCloseFile(); + } + return rc; +} + + +static int _SetState(ccbVaultIc_Context *c, VLT_STATE state) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + VLT_TARGET_INFO chipInfo; + rc = _GetInfo(c, &chipInfo); + if (rc == 0) { + if (chipInfo.enState != state) { + c->vlt_rc = VltSetStatus(state); + rc = _TranslateError(c->vlt_rc); + } + } + } + return rc; +} +static int _SetCreationState(ccbVaultIc_Context *c) +{ + return _SetState(c, VLT_STATE_CREATION); +} +static int _SetActivatedState(ccbVaultIc_Context *c) +{ + return _SetState(c, VLT_STATE_ACTIVATED); +} + +#if 0 +static int _CreatePinUser(ccbVaultIc_Context *c, + int user, int role, + int pin_len, const char* pin) +{ + +} + +static int _CreateScp03User(ccbVaultIc_Context *c, + int user, int role, + int ,a_len, const char* pin) +{ + +} + +static int _CreateKdfUser(ccbVaultIc_Context *c, + int user, int role, + int pin_len, const char* pin) +{ + +} + +static int _CreateUser( ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + if (a == NULL) { + rc = BAD_FUNC_ARG; + } + if(rc == 0) { + + } + } + + VLT_MANAGE_AUTH_DATA structAuthSetup; + structAuthSetup.enOperationID = VLT_DELETE_USER; + structAuthSetup.enUserID = VLT_USER0; + for ( VLT_USER_ID i = VLT_USER0; i <= VLT_USER6; i++) { + structAuthSetup.enUserID = i; + VltManageAuthenticationData(&structAuthSetup); + } + + // Create TLS user + //--------------------------------------------------------------------- + structAuthSetup.enOperationID = VLT_CREATE_USER; + structAuthSetup.u8TryCount = 5; + structAuthSetup.enSecurityOption = VLT_NO_DELETE_ON_LOCK; + structAuthSetup.enUserID = TLS_USER_ID; + structAuthSetup.enRoleID = VLT_NON_APPROVED_USER; + +#ifdef USE_SEC_CHANNEL + // SCP03 auth method + //--------------------------------------------------------------------- + VLT_U8 au8S_MacStaticKey[] = SMAC_KEY; + VLT_U8 au8S_EncStaticKey[] = SENC_KEY; + structAuthSetup.enMethod = VLT_AUTH_SCP03; + structAuthSetup.enChannelLevel = VLT_CMAC_CENC; + structAuthSetup.data.secret.u8NumberOfKeys = 2; + structAuthSetup.data.secret.aKeys[0].enKeyID = VLT_KEY_AES_128; + structAuthSetup.data.secret.aKeys[0].u8Mask = 0xBE; + structAuthSetup.data.secret.aKeys[0].u16KeyLength = sizeof(au8S_MacStaticKey); + structAuthSetup.data.secret.aKeys[0].pu8Key = au8S_MacStaticKey; + structAuthSetup.data.secret.aKeys[1].enKeyID = VLT_KEY_AES_128; + structAuthSetup.data.secret.aKeys[1].u8Mask = 0xEF; + structAuthSetup.data.secret.aKeys[1].u16KeyLength = sizeof(au8S_EncStaticKey); + structAuthSetup.data.secret.aKeys[1].pu8Key = au8S_EncStaticKey; + printf("Encrypted channel enabled, TLS_USER = USER%d (SCP03)\n",TLS_USER_ID); +#else + // Create user 00 with password auth method + //--------------------------------------------------------------------- + structAuthSetup.enMethod = VLT_AUTH_PASSWORD; + structAuthSetup.enChannelLevel = VLT_NO_CHANNEL; + structAuthSetup.data.password.u8PasswordLength = TLS_USER_PIN_LEN; + memset(structAuthSetup.data.password.u8Password, 0x00, sizeof (structAuthSetup.data.password.u8Password)); + memcpy(structAuthSetup.data.password.u8Password, (VLT_PU8) TLS_USER_PIN, TLS_USER_PIN_LEN); + printf("Encrypted channel disabled, TLS_USER = USER%d (PIN)\n",TLS_USER_ID); +#endif + + CHECK_STATUS("VltManageAuthenticationData Create Tls User" , VltManageAuthenticationData(&structAuthSetup),TRUE); + + +} + +static int _DeleteUser( ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + if (a == NULL) { + rc = BAD_FUNC_ARG; + } + if(rc == 0) { + VLT_MANAGE_AUTH_DATA authSetup; + XMEMSET(authSetup, 0, sizeof(authSetup)); + authSetup.enOperationID = VLT_DELETE_USER; + authSetup.enUserID = _AuthId2VltUserId(a->id); + c->vlt_rc = VltManageAuthenticationData(&authSetup); + rc = _TranslateError(c->vlt_rc); + } + } + return rc; +} +#endif + +/* Perform the load action as the currently authed user */ +int ccbVaultIc_LoadAction( ccbVaultIc_Context *c, + ccbVaultIc_Load *l) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + if (l == NULL) { + rc = BAD_FUNC_ARG; + } + /* Read file data into the load structure */ + if (rc == 0) { + int counter = 0; + for(counter = 0; counter < l->file_count; counter++) { + rc = ccbVaultIc_ReadFile(c, &l->file[counter]); + if (rc != 0) break; + } + } + } + return rc; +} + +/* Perform the provision action as the currently authed user */ +int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, + const ccbVaultIc_Provision *p) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + if (p == NULL) { + rc = BAD_FUNC_ARG; + } + + if (rc == 0) { + /* Setting creation mode should delete all users and their files */ + // rc = _SetCreationState(c); + } + + if (rc == 0) { + /* Update self test configuration */ + // rc = ccbVaultIc_SetSelfTest(c, p->self_test); + } + + /* Add User */ + if (rc == 0) { + /* Create the requested user */ + //ccbVaultIc_DeleteUser(c, &p->create); + // rc = ccbVaultIc_CreateUser(c, &p->create); + + } + + /* Create and write file data from the provision structure */ + if (rc == 0) { + int counter = 0; + int userId = p->create.id; + int adminId = c->config->auth.id; + for(counter = 0; counter < p->file_count; counter++) { + /* Delete any existing file. Ignore errors */ + ccbVaultIc_DeleteFile(c, &p->file[counter]); + + /* Create the file */ + rc = ccbVaultIc_CreateUserFile(c, &p->file[counter], + userId, adminId); + if (rc == 0) { + /* Write the file */ + rc = ccbVaultIc_WriteFile(c, &p->file[counter]); + } + if (rc != 0) break; + } + } + + if (rc == 0) { + /* Set Activated State */ + // rc = _SetActivatedState(c); + } + } + return rc; +} + #ifdef WOLF_CRYPTO_CB /* Forward declarations */ @@ -404,6 +1146,10 @@ static int HandleCmdCallback(int devId, wc_CryptoInfo* info, default: break; } +#if defined(CCBVAULTIC_DEBUG_ALL) + XPRINTF("HandleCmdCallback %d: c:%p rc:%d\n", info->cmd.type, c, rc); +#endif + return rc; } #endif @@ -460,9 +1206,9 @@ static int HandlePkCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" RSA Flatten Pub Key:%d, eSz:%u nSz:%u\n", rc, eSz, nSz); - hexdump(e,sizeof(e)); - hexdump(e_pad,sizeof(e_pad)); - hexdump(n,sizeof(n)); + _HexDump((const char*)e,sizeof(e)); + _HexDump((const char*)e_pad,sizeof(e_pad)); + _HexDump((const char*)n,sizeof(n)); #endif /* Set tmpRsaKey privileges */ keyPrivileges.u8Read = VAULTIC_KP_ALL; @@ -501,7 +1247,7 @@ static int HandlePkCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VLT PutKey:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -517,7 +1263,7 @@ static int HandlePkCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VLT InitAlgo:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -538,7 +1284,7 @@ static int HandlePkCallback(int devId, wc_CryptoInfo* info, XPRINTF(" VLT Encrypt:%x inSz:%u outSz:%lu\n", c->vlt_rc, info->pk.rsa.inLen, out_len); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -731,7 +1477,7 @@ static int HandleHashCallback(int devId, wc_CryptoInfo* info, (info->hash.inSz > 0)) { /* Buffer data */ if (c->m == NULL) { - c->m = XMALLOC(info->hash.inSz, NULL, NULL); + c->m = (unsigned char*)XMALLOC(info->hash.inSz, NULL, NULL); if (c->m == NULL) { /* Failure to allocate. Must return error */ #if defined(CCBVAULTIC_DEBUG) @@ -795,7 +1541,7 @@ static int HandleHashCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VltInit SHA256:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -811,7 +1557,7 @@ static int HandleHashCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VltUpdate SHA256:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -822,7 +1568,7 @@ static int HandleHashCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VltFinal SHA256:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; } @@ -835,9 +1581,9 @@ static int HandleHashCallback(int devId, wc_CryptoInfo* info, info->hash.digest); #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VltCompute SHA256:%x\n", c->vlt_rc); - hexdump(info->hash.digest, WC_SHA256_DIGEST_SIZE); + _HexDump(info->hash.digest, WC_SHA256_DIGEST_SIZE); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; } @@ -982,7 +1728,7 @@ static int HandleCipherCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" New AES Key: ckey:%p clen:%lu akey:%p alen:%u\n", c->aescbc_key,c->aescbc_keylen, aes->devKey, aes->keylen); - hexdump((void*)aes->devKey, aes->keylen); + _HexDump((void*)aes->devKey, aes->keylen); #endif /* Free the current key buffer if necessary */ if (c->aescbc_key != NULL) { @@ -992,7 +1738,7 @@ static int HandleCipherCallback(int devId, wc_CryptoInfo* info, } /* Allocate key buffer */ - c->aescbc_key = XMALLOC(aes->keylen, NULL, NULL); + c->aescbc_key = (unsigned char*)XMALLOC(aes->keylen, NULL, NULL); if (c->aescbc_key == NULL) { #if defined(CCBVAULTIC_DEBUG) XPRINTF(" Failed to allocate new AES Key of size:%u\n", @@ -1036,9 +1782,9 @@ static int HandleCipherCallback(int devId, wc_CryptoInfo* info, &tmpAesKey); #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VLT PutKey:%x\n", c->vlt_rc); - hexdump(c->aescbc_key, c->aescbc_keylen); + _HexDump((const char*)c->aescbc_key, c->aescbc_keylen); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; } @@ -1054,7 +1800,7 @@ static int HandleCipherCallback(int devId, wc_CryptoInfo* info, #if defined(CCBVAULTIC_DEBUG_ALL) XPRINTF(" VLT InitAlgo:%x\n", c->vlt_rc); #endif - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; @@ -1083,7 +1829,7 @@ static int HandleCipherCallback(int devId, wc_CryptoInfo* info, XPRINTF(" VLT Decrypt:%x\n", c->vlt_rc); #endif } - rc = translateError(c->vlt_rc); + rc = _TranslateError(c->vlt_rc); if (rc != 0) break; diff --git a/ccb_vaultic/ccb_vaultic.h b/ccb_vaultic/ccb_vaultic.h index f3d8d4db5..bec501c2f 100644 --- a/ccb_vaultic/ccb_vaultic.h +++ b/ccb_vaultic/ccb_vaultic.h @@ -36,9 +36,86 @@ * compiled in the proper hardware configuration. */ +/* Fixed sizes and values */ +enum { + CCBVAULTIC_SERIAL_LEN = 8, + CCBVAULTIC_VERSION_LEN = 32, +}; + +/* Configuration choices */ +enum { + CCBVAULTIC_FAST_START_MS = 700, + CCBVAULTIC_SLOW_START_MS = 5000, + CCBVAULTIC_APDU_TIMEOUT_MS = 5000, + CCBVAULTIC_SPI_RATE_KHZ = 5000, +}; + + +/* Authenticated User: + * + */ +enum { + CCBVAULTIC_AUTH_ID_MIN = 0, + CCBVAULTIC_AUTH_ID_MAX = 7, + + CCBVAULTIC_AUTH_ROLE_NONE = 0, + CCBVAULTIC_AUTH_ROLE_MANUFACTURER = 1, + CCBVAULTIC_AUTH_ROLE_UNAPPROVED = 2, + CCBVAULTIC_AUTH_ROLE_APPROVED = 3, + + CCBVAULTIC_AUTH_KIND_NONE = 0, + CCBVAULTIC_AUTH_KIND_PIN = 1, + CCBVAULTIC_AUTH_KIND_SCP03 = 2, + CCBVAULTIC_AUTH_KIND_KDF = 3, + + CCBVAULTIC_AUTH_PIN_LEN_MIN = 0x4, + CCBVAULTIC_AUTH_PIN_LEN_MAX = 0x20, + + CCBVAULTIC_AUTH_MAC_LEN = 0x10, /* AES128 keys only */ + CCBVAULTIC_AUTH_ENC_LEN = 0x10, /* AES128 keys only */ + + CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN = 0x10, + CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN = 0x0, +}; + +typedef struct { + int id; /* between CCBVAULTIC_AUTH_ID_MIN/MAX */ + int role; /* enum of CCBVAULTIC_AUTH_ROLE_xxx */ + int kind; /* enum of CCBVAULTIC_AUTH_KIND_xxx */ + union { /* based on kind */ + struct { + size_t pin_len; + char* pin; + } pin; + struct { + size_t mac_len; + char* mac; + size_t enc_len; + char* enc; + } scp03; + struct { + size_t key_len; + char* key; + size_t label_len; + char* label; + } kdf; + } auth; +} ccbVaultIc_Auth; + +typedef struct { + int startup_delay_ms; + int timeout_ms; + int spi_rate_khz; + + ccbVaultIc_Auth auth; +} ccbVaultIc_Config; + typedef struct { int initialized; + const ccbVaultIc_Config* config; int vlt_rc; + char vlt_serial[CCBVAULTIC_SERIAL_LEN]; + char vlt_version[CCBVAULTIC_VERSION_LEN]; /* Buffer to store message during SHA with will_copy flag set */ int hash_type; /* enum wc_HashType */ @@ -53,19 +130,89 @@ typedef struct { /* ccbVaultIc_Context static initializer */ #define CCBVAULTIC_CONTEXT_INITIALIZER \ { \ - .initialized = 0 \ + .initialized = 0, \ + .config = NULL \ } -/* Initialize the Wisekey VaultIC library and clear the context. + +enum { + CCBVAULTIC_FILE_NAME_LEN_MIN = 0x1, /* At least a NULL */ + CCBVAULTIC_FILE_NAME_LEN_MAX = 0x10, /* 16 byte limit for names */ + CCBVAULTIC_FILE_DATA_LEN_MAX = 0x10000, /* 16kB limit for files */ +}; +typedef struct { + int name_len; + char* name; /* Path, start with / */ + int data_len; + char* data; +} ccbVaultIc_File; + + +/* Provision Action + * Must authenticate as MANUFACTURER role first. Then invoke provision action: + * -sets chip to CREATION state: VltSetStatus(VLT_STATE_CREATION) + * -sets power on self test to self_test: VltSetConfig(...) + * -deletes all other users: VltManageAuthenticationData(...) + * -creates auth user using id, role, and auth kind + * -creates and copies file_count files from file[] with auth and current + * user id with all privs + * -sets chip to ACTIVATED state + */ +enum { + CCBVAULTIC_PROV_SELFTEST_OPTIONAL = 0, + CCBVAULTIC_PROV_SELFTEST_REQUIRED = 1, +}; + +/* Data provided to Provision action */ +typedef struct { + int self_test; + ccbVaultIc_Auth create; + int file_count; + const ccbVaultIc_File *file; +} ccbVaultIc_Provision; + +/* Data provided to Load action */ +typedef struct { + int file_count; + ccbVaultIc_File* file; +} ccbVaultIc_Load; + + +/* Initialize the VaultIC library and clear the context. * Returns: 0 on success * BAD_FUNC_ARGS with NULL context * WC_INIT_E on error initializing the VaultIC. * c->vlt_rc will have error code */ -int ccbVaultIc_Init(ccbVaultIc_Context *c); +int ccbVaultIc_Init( ccbVaultIc_Context *c); + +/* Close the VaultIC library. */ +void ccbVaultIc_Cleanup( ccbVaultIc_Context *c); + +/* Create a file on the VaultIc, accessible by only the user and manufacturer */ +int ccbVaultIc_CreateUserFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f, + int userId, int manuId); + +/* Delete a file on the VaultIC*/ +int ccbVaultIc_DeleteFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f); -/* Close the Wisekey VaultIC library. */ -void ccbVaultIc_Cleanup(ccbVaultIc_Context *c); +/* Write file data into the vaultic from the file struct */ +int ccbVaultIc_WriteFile( ccbVaultIc_Context *c, + const ccbVaultIc_File *f); + +/* Read file data from the vaultic into the file struct */ +int ccbVaultIc_ReadFile( ccbVaultIc_Context *c, + ccbVaultIc_File *f); + +/* Perform the load action as the currently authed user */ +int ccbVaultIc_LoadAction( ccbVaultIc_Context *c, + ccbVaultIc_Load *l); + +/* Perform the provision action as the currently authed user */ +int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, + const ccbVaultIc_Provision *p); #ifdef WOLF_CRYPTO_CB #include "wolfssl/wolfcrypt/cryptocb.h" /* For wc_CryptInfo */ @@ -77,7 +224,7 @@ void ccbVaultIc_Cleanup(ccbVaultIc_Context *c); * CCBVAULTIC420_DEVID, * ccbVaultIc_CryptoCb, * &ctx); - * wc_Aes aes={0}; + * wc_Aes aes; * wc_AesInit(&aes, NULL, CCBVAULTIC420_DEVID); * Returns: 0 on success * CRYPTOCB_UNAVAILABLE if not initialized or not implemented @@ -88,6 +235,33 @@ int ccbVaultIc_CryptoCb(int devId, void* ctx); #endif /* WOLF_CRYPTO_CB */ + + +#define CCBVAULTIC_AUTH_ID_DEFAULT 1 +#define CCBVAULTIC_SCP03_MAC_DEFAULT \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" +#define CCBVAULTIC_SCP03_ENC_DEFAULT \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" +#define CCBVAULTIC_AUTH_DEFAULT \ + { \ + .id = CCBVAULTIC_AUTH_ID_DEFAULT, \ + .kind = CCBVAULTIC_AUTH_KIND_SCP03, \ + .auth.scp03 = { \ + .mac_len = sizeof(CCBVAULTIC_SCP03_MAC_DEFAULT), \ + .mac = CCBVAULTIC_SCP03_ENC_DEFAULT, \ + .enc_len = sizeof(CCBVAULTIC_SCP03_MAC_DEFAULT), \ + .enc = CCBVAULTIC_SCP03_ENC_DEFAULT, \ + } \ + } + +#define CCBVAULTIC_CONFIG_DEFAULT \ + { \ + .startup_delay_ms = CCBVAULTIC_FAST_START_MS, \ + .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, \ + .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, \ + .auth = CCBVAULTIC_AUTH_DEFAULT, \ + } + #endif /* HAVE_CCBVAULTIC */ #endif /* CCB_VAULTIC_H_ */ diff --git a/ccb_vaultic/ccb_vaultic_config.h b/ccb_vaultic/ccb_vaultic_config.h new file mode 100644 index 000000000..87dba95e3 --- /dev/null +++ b/ccb_vaultic/ccb_vaultic_config.h @@ -0,0 +1,299 @@ +/* + * ccb_vaultic_config.h + * + * Copyright (C) 2023 wolfSSL Inc. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef CCB_VAULTIC_CONFIG_H +#define CCB_VAULTIC_CONFIG_H + +#include "ccb_vaultic.h" + +#ifdef HAVE_CCBVAULTIC + +/* + * Example configuration structures */ + +/* Configuration choices */ +enum { + _KDF_ID = 0, + _USER_ID = 1, + _MANU_ID = 7, +}; + +#define _KDF_KEY \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" +#define _KDF_LABEL \ + "KDF Label" + +#define _USER_MAC \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" +#define _USER_ENC \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + +#define _MANU_PIN \ + "\x00\x01\x02\x03\x04\x05\x06\x07" + +#define _KEY_NAME "/key.pem" +#define _CRT_NAME "/crt.pem" +#define _CA_NAME "/ca.pem" + +/* Storage for loaded files */ +char gLoadKey_data[CCBVAULTIC_FILE_DATA_LEN_MAX]; +char gLoadCrt_data[CCBVAULTIC_FILE_DATA_LEN_MAX]; +char gLoadCa_data[CCBVAULTIC_FILE_DATA_LEN_MAX]; + +/* Filthy preprocessor trick... */ +#define QUOTE(...) #__VA_ARGS__ + +/* From wolfssl/certs/client-key.pem */ +char gProvKey_data[] = QUOTE( +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwwPRK/45pDJFO1PIhCsqfHSavaoqUgdH1qY2sgcyjtC6aXvG +w0Se1IFI/S1oootnu6F1yDYsStIb94u6zw357+zxgR57mwNHmr9lzH9lJGmm6BSJ +W+Q098WwFJP1Z3s6enjhAVZWkaYTQo3SPECcTO/Rht83URsMoTv18aNKNeThzpbf +G36/TpfQEOioCDCBryALQxTFdGe0MoJvjYbCiECZNoO6HkByIhfXUmUkc7DO7xnN +rv94bHvAEgPUTnINUG07ozujmV6dyNkMhbPZitlUJttt+qy7/yVMxNF59HHThkAY +E7BjtXJOMMSXhIYtVi/XFfd/wK71/Fvl+6G60wIDAQABAoIBAQCi5thfEHFkCJ4u +bdFtHoXSCrGMR84sUWqgEp5T3pFMHW3qWXvyd6rZxtmKq9jhFuRjJv+1bBNZuOOl +yHIXLgyfb+VZP3ZvSbERwlouFikN3reO3EDVou7gHqH0vpfbhmOWFM2YCWAtMHac +PM3miO5HknkLWgDiXl8RfH35CLcgBokqXf0AqyLh8LO8JKleJg4fAC3+IZpTW23T +K6uUgmhDNtj2L8Yi/LVBXQ0zYOqkfX7oS1WRVtNcV48flBcvqt7pnqj0z4pMjqDk +VnOyz0+GxWk88yQgi1yWDPprEjuaZ8HfxpaypdWSDZsJQmgkEEXUUOQXOUjQNYuU +bRHej8pZAoGBAOokp/lpM+lx3FJ9iCEoL0neunIW6cxHeogNlFeEWBY6gbA/os+m +bB6wBikAj+d3dqzbysfZXps/JpBSrvw4kAAUu7QPWJTnL2p+HE9BIdQxWR9OihqN +p1dsItjl9H4yphDLZKVVA4emJwWMw9e2J7JNujDaR49U0z2LhI2UmFilAoGBANU4 +G8OPxZMMRwtvNZLFsI1GyJIYj/WACvfvof6AubUqusoYsF2lB9CTjdicBBzUYo6m +JoEB/86KKmM0NUCqbYDeiSNqV02ebq2TTlaQC22dc4sMric93k7wqsVseGdslFKc +N2dsLe+7r9+mkDzER8+Nlp6YqbSfxaZQ3LPw+3QXAoGAXoMJYr26fKK/QnT1fBzS +ackEDYV+Pj0kEsMYe/Mp818OdmxZdeRBhGmdMvPNIquwNbpKsjzl2Vi2Yk9d3uWe +CspTsiz3nrNrClt5ZexukU6SIPb8/Bbt03YM4ux/smkTa3gOWkZktF63JaBadTpL +78c8Pvf9JrggxJkKmnO+wxkCgYEAukSTFKw0GTtfkWCs97TWgQU2UVM96GXcry7c +YT7Jfbh/h/A7mwOCKTfOck4R1bHBDAegmZFKjX/sec/xObXphexi99p9vGRNIjwO +8tZR9YfYmcARIF0PKf1b4q7ZHNkhVm38hNBf7RAVHBgh58Q9S9fQnmqVzyLJA3ue +42AB/C8CgYAR0EvPG2e5nxB1R4ZlrjHCxjCsWQZQ2Q+1cAb38NPIYnyo2m72IT/T +f1/qiqs/2Spe81HSwjA34y2jdQ0eTSE01VdwXIm/cuxKbmjVzRh0M06MOkWP5pZA +62P5GYY6Ud2JS7Dz+Z9dKJU4vjWrylznk1M0oUVdEzllQkahn831vw== +-----END RSA PRIVATE KEY----- +); + +/* From wolfssl/certs/client-cert.pem */ +char gProvCrt_data[] = QUOTE( +-----BEGIN CERTIFICATE----- +MIIFHTCCBAWgAwIBAgIUc/tU1gN9TAeE4gARjN2Q3EiN6lMwDQYJKoZIhvcNAQEL +BQAwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC +b3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsMEFByb2dyYW1t +aW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJ +ARYQaW5mb0B3b2xmc3NsLmNvbTAeFw0yMjEyMTYyMTE3NDlaFw0yNTA5MTEyMTE3 +NDlaMIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwH +Qm96ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFt +bWluZy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0B +CQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDDA9Er/jmkMkU7U8iEKyp8dJq9qipSB0fWpjayBzKO0Lppe8bDRJ7UgUj9 +LWiii2e7oXXINixK0hv3i7rPDfnv7PGBHnubA0eav2XMf2UkaaboFIlb5DT3xbAU +k/Vnezp6eOEBVlaRphNCjdI8QJxM79GG3zdRGwyhO/Xxo0o15OHOlt8bfr9Ol9AQ +6KgIMIGvIAtDFMV0Z7Qygm+NhsKIQJk2g7oeQHIiF9dSZSRzsM7vGc2u/3hse8AS +A9ROcg1QbTujO6OZXp3I2QyFs9mK2VQm2236rLv/JUzE0Xn0cdOGQBgTsGO1ck4w +xJeEhi1WL9cV93/ArvX8W+X7obrTAgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUM9hF +Ztdohxh+VA1wJ5HHJteFZcAwgd4GA1UdIwSB1jCB04AUM9hFZtdohxh+VA1wJ5HH +JteFZcChgaSkgaEwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAw +DgYDVQQHDAdCb3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsM +EFByb2dyYW1taW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0G +CSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIUc/tU1gN9TAeE4gARjN2Q3EiN +6lMwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATAd +BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEB +ADbLvMVSmmbNkU2PJ5+zZIAOZLTLGs11noJ8VWfYn5CjNJaZQ/dJU6JYhaCzg0+v +uBWKiB7zYPR8lLVYaPEqE4A0wm+l+H52FoFPNovDWb1R3WCH1x2WRGkHPI8oVrER +XE6BP1cl/WXdB88XCgF+Tj+Oc9v+9PLF/6N2qHRGLkcNsO0KwMUKZdPcYrLgHo69 +872vr2aENpLiO4DQV6ZBo2LRpm0UbM2CscHBNVWuWUmoJlK97xssH505BNKCoGs5 +cVkzgrpVbJfyG1vgTeLPiecmuCxsn4PW7U4vdakwTgGVDU+DXsivf2fqU7/Kmx/U +/zaXAnGOM97iWCeqcAxb3g4= +-----END CERTIFICATE----- +); + +/* From wolfssl/certs/ca-cert.pem */ +char gProvCa_data[] = QUOTE( +-----BEGIN CERTIFICATE----- +MIIE/zCCA+egAwIBAgIULIDO20edB2aSPWjXyqyQT8ppQUswDQYJKoZIhvcNAQEL +BQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC +b3plbWFuMREwDwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEY +MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv +bGZzc2wuY29tMB4XDTIyMTIxNjIxMTc0OVoXDTI1MDkxMTIxMTc0OVowgZQxCzAJ +BgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREw +DwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwP +d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvwzKLRSyHoRCW804H0ry +TXUQ8bY1n9/KfQOY06zeA2buKvHYsH1uB1QLEJghTYDLEiDnzE/eRX3Jcncy6sqQ +u2lSEAMvqPOVxfGLYlYb72dvpBBBla0Km+OlwLDScHZQMFuo6AgsfO2nonqNOCkc +rMft8nyVsJWCfUlcOM13Je+9gHVTlDw9ymNbnxW10x0TLxnRPNt2Osy4fcnlwtfa +QG/YIdxzG0ItU5z+Gvx9q3o2P5jehHwFZ85qFDiHqfGMtWjLaH9xICv1oGP1Vi+j +JtK3b7FaF9c4mQj+k1hv/sMTSQgWC6dNZwBSMWcjTpjtUUUduQTZC+zYKLNLve02 +eQIDAQABo4IBRTCCAUEwHQYDVR0OBBYEFCeOZxF0wyYdP+0zY7Ok2B0w5ejVMIHU +BgNVHSMEgcwwgcmAFCeOZxF0wyYdP+0zY7Ok2B0w5ejVoYGapIGXMIGUMQswCQYD +VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjERMA8G +A1UECgwIU2F3dG9vdGgxEzARBgNVBAsMCkNvbnN1bHRpbmcxGDAWBgNVBAMMD3d3 +dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIU +LIDO20edB2aSPWjXyqyQT8ppQUswDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtl +eGFtcGxlLmNvbYcEfwAAATAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +DQYJKoZIhvcNAQELBQADggEBAK6wpDWOihum67OiV886H9xuvNLQpkqPiApudNXR +fNFEsdQ7FwMJWkbtCAjP8f0gB2fAl+w183XKIGGYPvVNvuaddR7kA62Mph497OQa +klv5o62Dyk/Nqji7bq6t+qdG8Ytz7AkjvPIY5beShj6kdWDHPQ8/gwDDBgic0VTW +um2VPTShviSRzCADEVtyHNRl0BGIdSYEJu9mcOY7OIecU3EbCVFwUJlMMQxiRFcw +YAT8EiyjJLT3EdUOtSEL7YYRZ002+legWVUhs23kd17sfvAJE46ZmLLhgrZLPg9B +pgzNSZl+5IrLN+1Tz4ZdqSao5QElWrS8JTXx+lpcztS4miw= +-----END CERTIFICATE----- +); + +/*************** Generated structures *******************/ + +/* Forward declarations, for readability */ +const ccbVaultIc_Config gKdfConfig; +const ccbVaultIc_Config gUserConfig; +const ccbVaultIc_Config gManuConfig; + +const ccbVaultIc_Provision gProvision; +ccbVaultIc_Load gLoad; + +/* KDF Auth */ +#define _KDF \ + { \ + .id = _KDF_ID, \ + .role = CCBVAULTIC_AUTH_ROLE_APPROVED, \ + .kind = CCBVAULTIC_AUTH_KIND_KDF, \ + .auth.kdf = \ + { \ + .key_len = sizeof(_KDF_KEY) - 1, \ + .key = _KDF_KEY, \ + .label_len = sizeof(_KDF_LABEL) - 1, \ + .label = _KDF_LABEL, \ + } \ + } + +/* User Auth */ +#define _USER \ + { \ + .id = _USER_ID, \ + .role = CCBVAULTIC_AUTH_ROLE_UNAPPROVED, \ + .kind = CCBVAULTIC_AUTH_KIND_SCP03, \ + .auth.scp03 = \ + { \ + .mac_len = sizeof(_USER_MAC) - 1, \ + .mac = _USER_MAC, \ + .enc_len = sizeof(_USER_ENC) - 1, \ + .enc = _USER_ENC, \ + } \ + } + +/* Manu Auth */ +#define _MANU \ + { \ + .id = _MANU_ID, \ + .role = CCBVAULTIC_AUTH_ROLE_MANUFACTURER, \ + .kind = CCBVAULTIC_AUTH_KIND_PIN, \ + .auth.pin = \ + { \ + .pin_len = sizeof(_MANU_PIN) - 1, \ + .pin = _MANU_PIN, \ + } \ + } + +const ccbVaultIc_Config gKdfConfig = + { + .startup_delay_ms = CCBVAULTIC_FAST_START_MS, + .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, + .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, + .auth = _KDF, + }; + +const ccbVaultIc_Config gUserConfig = + { + .startup_delay_ms = CCBVAULTIC_FAST_START_MS, + .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, + .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, + .auth = _USER, + }; + +const ccbVaultIc_Config gManuConfig = + { + .startup_delay_ms = CCBVAULTIC_FAST_START_MS, + .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, + .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, + .auth = _MANU, + }; + +ccbVaultIc_File gLoadFiles[] = + { + { + .name_len = sizeof(_KEY_NAME), + .name = _KEY_NAME, + .data_len = sizeof(gLoadKey_data), + .data = gLoadKey_data, + }, + { + .name_len = sizeof(_CRT_NAME), + .name = _CRT_NAME, + .data_len = sizeof(gLoadCrt_data), + .data = gLoadCrt_data, + }, + { + .name_len = sizeof(_CA_NAME), + .name = _CA_NAME, + .data_len = sizeof(gLoadCa_data), + .data = gLoadCa_data, + }, + }; + +ccbVaultIc_Load gLoad = + { + .file_count = sizeof(gLoadFiles) / sizeof(gLoadFiles[0]), + .file = gLoadFiles, + }; + +const ccbVaultIc_File gProvFiles[] = + { + { + .name_len = sizeof(_KEY_NAME), + .name = _KEY_NAME, + .data_len = sizeof(gProvKey_data), + .data = gProvKey_data, + }, + { + .name_len = sizeof(_CRT_NAME), + .name = _CRT_NAME, + .data_len = sizeof(gProvCrt_data), + .data = gProvCrt_data, + }, + { + .name_len = sizeof(_CA_NAME), + .name = _CA_NAME, + .data_len = sizeof(gProvCa_data), + .data = gProvCa_data, + }, + }; + +const ccbVaultIc_Provision gProvision = + { + .self_test = CCBVAULTIC_PROV_SELFTEST_OPTIONAL, + .create = _USER, + .file_count = sizeof(gProvFiles) / sizeof(gProvFiles[0]), + .file = gProvFiles, + }; + +#endif /* HAVE_CCBVAULTIC */ + +#endif /* CCB_VAULTIC_CONFIG_H_ */ diff --git a/ccb_vaultic/main-load.c b/ccb_vaultic/main-load.c new file mode 100644 index 000000000..3eaeedda1 --- /dev/null +++ b/ccb_vaultic/main-load.c @@ -0,0 +1,160 @@ +/* wolfCrypt load application for Wisekey VaultIC + * + * Copyright (C) 2023 wolfSSL Inc. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_USER_SETTINGS + #include "wolfssl/options.h" +#endif + +#include "wolfssl/ssl.h" + +#include "wolfssl/wolfcrypt/settings.h" /* For X-defines */ + +/* wolfCrypt includes */ +#include "wolfssl/wolfcrypt/wc_port.h" /* For Init/Cleanup */ + +#ifdef WOLF_CRYPTO_CB +#include "wolfssl/wolfcrypt/cryptocb.h" /* For Register/Unregister */ +#endif + +#ifdef HAVE_CCBVAULTIC +#include "ccb_vaultic.h" /* For devId and cryptocb */ +#endif + +/* Local include */ +#include "ccb_vaultic_config.h" /* For authentication and file data */ + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + int rc = 0; + + /* Initialize wolfSSL */ + rc = wolfSSL_Init(); + if (rc == WOLFSSL_SUCCESS) { + +#ifdef WOLF_CRYPTO_CB + /* Allocate/initialize context */ + void* c = NULL; + #if 1 + /* External allocation/initialization of hardware context */ + #ifdef HAVE_CCBVAULTIC + static ccbVaultIc_Context ctx_storage = CCBVAULTIC_CONTEXT_INITIALIZER; + c = &ctx_storage; + + ctx_storage.config = &gUserConfig; + rc = ccbVaultIc_Init(c); + #else + /* Add other elif hardware here */ + #endif + #endif /* WOLF_CRYPTO_CB_CMD */ + + if (rc == 0) { + /* Setup callback and devId */ + int devId = INVALID_DEVID; + CryptoDevCallbackFunc ccb = NULL; + #ifdef HAVE_CCBVAULTIC + devId = CCBVAULTIC420_DEVID; + ccb = ccbVaultIc_CryptoCb; + #else + /* Add other elif hardware here */ + #endif + + /* Register cryptocb */ + rc = wc_CryptoCb_RegisterDevice( + devId, + ccb, + c); +#endif /* WOLF_CRYPTO_CB */ + + if (rc == 0) { + /* Perform Load action */ + rc = ccbVaultIc_LoadAction(c, &gLoad); + + if (rc == 0) { + WOLFSSL_CTX* ctx = NULL; + int i; + for(i=0; i < gLoad.file_count; i++) { + printf("File %d: \n Name:%.*s\n Len:%d\n Data:%.*s\n---\n", + i, + gLoad.file[i].name_len, + gLoad.file[i].name, + gLoad.file[i].data_len, + gLoad.file[i].data_len, + gLoad.file[i].data + ); + } + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + if (ctx != NULL) { + rc = wolfSSL_CTX_use_PrivateKey_buffer( + ctx, + (const byte*)gLoad.file[0].data, + gLoad.file[0].data_len, + WOLFSSL_FILETYPE_PEM); + printf("Use PrivateKey with file %d returned %d\n",0,rc); + rc = wolfSSL_CTX_use_certificate_chain_buffer_format( + ctx, + (const byte*)gLoad.file[1].data, + gLoad.file[1].data_len, + WOLFSSL_FILETYPE_PEM); + printf("Use Certificate Chain with file %d returned %d\n",1,rc); + rc = wolfSSL_CTX_load_verify_chain_buffer_format( + ctx, + (const byte*)gLoad.file[2].data, + gLoad.file[2].data_len, + WOLFSSL_FILETYPE_PEM); + printf("Use Load Verify Chain with file %d returned %d\n",2,rc); + wolfSSL_CTX_free(ctx); + } + } + else + { + printf("Load failed with %d vlt_rc:%x\n", rc, ctx_storage.vlt_rc); + } + +#ifdef WOLF_CRYPTO_CB + /* Unregister the callback */ + wc_CryptoCb_UnRegisterDevice(devId); +#endif + } else { + printf("Failed to register cryptocb:%d (%x) "\ + " with devId:%x ccb:%p\n", + rc, rc, devId, ccb); + } + +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_CMD + /* External deallocation of hardware context */ + #ifdef HAVE_CCBVAULTIC + ccbVaultIc_Cleanup(c); + #else + /* Add other hardware cleanup here */ + #endif + #endif +#endif + } else { + printf(" Failed to initialize hardware: %d (%x)\n", rc, rc); + } + wolfSSL_Cleanup(); + }else { + printf("Failed to initialize wolfSSL: %d (%x)\n", rc, rc); + } + return rc; +} diff --git a/ccb_vaultic/main-prov.c b/ccb_vaultic/main-prov.c new file mode 100644 index 000000000..dca04cd4b --- /dev/null +++ b/ccb_vaultic/main-prov.c @@ -0,0 +1,124 @@ +/* wolfCrypt prov application for Wisekey VaultIC + * + * Copyright (C) 2023 wolfSSL Inc. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_USER_SETTINGS + #include "wolfssl/options.h" +#endif +#include "wolfssl/wolfcrypt/settings.h" /* For X-defines */ + +/* wolfCrypt includes */ +#include "wolfssl/wolfcrypt/wc_port.h" /* For Init/Cleanup */ + +#ifdef WOLF_CRYPTO_CB +#include "wolfssl/wolfcrypt/cryptocb.h" /* For Register/Unregister */ +#endif + +#ifdef HAVE_CCBVAULTIC +#include "ccb_vaultic.h" /* For devId and cryptocb */ +#endif + +/* Local include */ +#include "ccb_vaultic_config.h" /* For authentication and file data */ + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + int rc = 0; + + /* Initialize wolfCrypt */ + rc = wolfCrypt_Init(); + if (rc == 0) { + +#ifdef WOLF_CRYPTO_CB + /* Allocate/initialize context */ + void* ctx = NULL; + #if 1 + /* External allocation/initialization of hardware context */ + #ifdef HAVE_CCBVAULTIC + static ccbVaultIc_Context ctx_storage = CCBVAULTIC_CONTEXT_INITIALIZER; + ctx = &ctx_storage; + + ctx_storage.config = &gManuConfig; + rc = ccbVaultIc_Init(ctx); + #else + /* Add other elif hardware here */ + #endif + #endif /* WOLF_CRYPTO_CB_CMD */ + + if (rc == 0) { + /* Setup callback and devId */ + int devId = INVALID_DEVID; + CryptoDevCallbackFunc ccb = NULL; + #ifdef HAVE_CCBVAULTIC + devId = CCBVAULTIC420_DEVID; + ccb = ccbVaultIc_CryptoCb; + #else + /* Add other elif hardware here */ + #endif + + /* Register cryptocb */ + rc = wc_CryptoCb_RegisterDevice( + devId, + ccb, + ctx); +#endif /* WOLF_CRYPTO_CB */ + + if (rc == 0) { + /* Perform Load action */ + rc = ccbVaultIc_ProvisionAction(ctx, &gProvision); + + if (rc == 0) { + printf("Provision succeeded.\n"); + } + else + { + printf("Provision failed with %d vlt_rc:%x\n", rc, ctx_storage.vlt_rc); + } + +#ifdef WOLF_CRYPTO_CB + /* Unregister the callback */ + wc_CryptoCb_UnRegisterDevice(devId); +#endif + } else { + printf("Failed to register cryptocb:%d (%x) "\ + " with devId:%x ccb:%p\n", + rc, rc, devId, ccb); + } + +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_CMD + /* External deallocation of hardware context */ + #ifdef HAVE_CCBVAULTIC + ccbVaultIc_Cleanup(ctx); + #else + /* Add other hardware cleanup here */ + #endif + #endif +#endif + } else { + printf(" Failed to initialize hardware: %d (%x)\n", rc, rc); + } + wolfCrypt_Cleanup(); + }else { + printf("Failed to initialize wolfCrypt: %d (%x)\n", rc, rc); + } + return rc; +} From ba0c7032db31bae9a7e03ffa1da6629c49ea6a80 Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 30 Aug 2023 12:26:01 -0400 Subject: [PATCH 02/10] Initial update with working JNI as prototype interface. --- .../wolfssljni-ndk-gradle/app/CMakeLists.txt | 17 +++- .../wolfssljni-ndk-gradle/app/build.gradle | 2 + .../wolfssljni_ndk_gradle/MainActivity.java | 24 +++++- ccb_vaultic/Makefile | 2 +- ccb_vaultic/ccb_vaultic.c | 77 ++++++++++++++++++- ccb_vaultic/ccb_vaultic.h | 53 +++++++++---- .../com_wolfssl_ccbvaultic_ccbVaultIc.c | 52 +++++++++++++ .../com_wolfssl_ccbvaultic_ccbVaultIc.h | 21 +++++ .../com/wolfssl/ccbvaultic/ccbVaultIc.java | 10 +++ 9 files changed, 233 insertions(+), 25 deletions(-) create mode 100644 ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c create mode 100644 ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h create mode 100644 ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java diff --git a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt index 94df6162a..95bb55cdc 100644 --- a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt +++ b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt @@ -272,8 +272,8 @@ target_link_libraries( # --------------------------- wolfCrypt CryptoCb Source Files -------------------------------------- # set which cryptocb subsystem (if any) will be used -set(WOLFSSL_CRYPTOCB_TYPE "") -#set(WOLFSSL_CRYPTOCB_TYPE "ccb_vaultic") +#set(WOLFSSL_CRYPTOCB_TYPE "") +set(WOLFSSL_CRYPTOCB_TYPE "ccb_vaultic") # Support for ccb_vaultic if("${WOLFSSL_CRYPTOCB_TYPE}" MATCHES "ccb_vaultic") @@ -288,6 +288,9 @@ if("${WOLFSSL_CRYPTOCB_TYPE}" MATCHES "ccb_vaultic") add_library(ccbvaultic SHARED ${cryptocb_DIR}/ccb_vaultic.c) + add_library(ccbvaulticjni SHARED + ${cryptocb_DIR}/com_wolfssl_ccbvaultic_ccbVaultic.c) + # TODO Add support for other architectures if("${ANDROID_ABI}" MATCHES "arm64-v8a") add_definitions( @@ -295,8 +298,8 @@ if("${WOLFSSL_CRYPTOCB_TYPE}" MATCHES "ccb_vaultic") #-DCCBVAULTIC_NO_AES #-DCCBVAULTIC_NO_RSA -DCCBVAULTIC_NO_SHA - #-DCCBVAULTIC_DEBUG - #-DCCBVAULTIC_DEBUG_TIMING + -DCCBVAULTIC_DEBUG + -DCCBVAULTIC_DEBUG_TIMING ) set(VAULTIC_DIR ${cryptocb_DIR}/VaultIC-TLS_420/vaultic_tls-4xx) @@ -336,4 +339,10 @@ if("${WOLFSSL_CRYPTOCB_TYPE}" MATCHES "ccb_vaultic") wolfssljni ccbvaultic ) + # Link ccbvaulticjni to ccbvaultic + target_link_libraries( + ccbvaulticjni + ccbvaultic + ) + endif() #ccb_vaultic diff --git a/android/wolfssljni-ndk-gradle/app/build.gradle b/android/wolfssljni-ndk-gradle/app/build.gradle index 52fc94ca0..bfe17e1ff 100644 --- a/android/wolfssljni-ndk-gradle/app/build.gradle +++ b/android/wolfssljni-ndk-gradle/app/build.gradle @@ -32,6 +32,8 @@ android { sourceSets { // wolfSSL JNI Java source files are added here main.java.srcDirs += '../wolfssljni/src/java' + // ccbVaultIc JNI Java source files + main.java.srcDirs += '../../../ccb_vaultic/java' } namespace 'com.wolfssl.wolfssljni_ndk_gradle' } diff --git a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java index b18a4533c..febda2c29 100644 --- a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java +++ b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java @@ -7,9 +7,14 @@ import android.widget.TextView; import com.wolfssl.WolfSSL; +import com.wolfssl.provider.jsse.WolfSSLKeyX509; import com.wolfssl.provider.jsse.WolfSSLProvider; +import com.wolfssl.ccbvaultic.ccbVaultIc; + import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.security.KeyStore; import java.security.Security; import java.util.concurrent.Executors; @@ -88,11 +93,12 @@ private void appendDisplayText(String s) /* Select The devId which will be registered and used on every other invocation */ /* Unique devId's are compiled into wolfssljni */ - //int devId = 0x56490420; /* VaultIC 420 */ - int devId = WolfSSL.INVALID_DEVID; /* No hardware offload */ + int devId = 0x56490420; /* VaultIC 420 */ + //int devId = WolfSSL.INVALID_DEVID; /* No hardware offload */ /* Select if the cipher suites and protocols will be limited */ - boolean limitCipherProtocol = false; + boolean limitCipherProtocol = true; + //boolean limitCipherProtocol = false; long[] ts = new long[10]; @@ -108,6 +114,15 @@ private void appendDisplayText(String s) appendDisplayText("B. Using hardware offload\n"); wolfProv.registerDevId(devId); wolfProv.setDevId(devId); + + ccbVaultIc cv = new ccbVaultIc(); + ByteBuffer text = ByteBuffer.allocateDirect(1024); + long[] text_len = {1024}; + int rc = cv.GetInfoText(devId, text, text_len); + + byte[] data = new byte[1024]; + text.get(data,0,(int)(text_len[0])); + appendDisplayText("GetInfoText rc=" + rc +", text_len=" + text_len[0]+", text=" + new String(data)); } else { appendDisplayText("B. Using software crypto.\n"); wolfProv.setDevId(WolfSSL.INVALID_DEVID); @@ -119,6 +134,9 @@ private void appendDisplayText(String s) /* not setting up KeyStore or TrustStore, wolfJSSE will load * CA certs from the Android system KeyStore by default. */ SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); + + //WolfSSLKeyX509 key = new WolfSSLKeyX509(new KeyStore()); + ctx.init(null, null, null); SSLSocketFactory sf = ctx.getSocketFactory(); diff --git a/ccb_vaultic/Makefile b/ccb_vaultic/Makefile index bc6162911..0b53e0738 100644 --- a/ccb_vaultic/Makefile +++ b/ccb_vaultic/Makefile @@ -6,7 +6,7 @@ AR=${NDK_AR} LD=${NDK_LD} # Relative path to wolfSSL source -WOLFSSL_DIR?=../../wolfssl +WOLFSSL_DIR?=../../bill_wolfssl # Relative path to VaultIC dev kit source VAULTIC_DIR?=./VaultIC-TLS_420/vaultic_tls-4xx diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index b65196412..3d1c61d68 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -39,6 +39,7 @@ * CCBVAULTIC_NO_RSA: Do not handle RSA callback * CCBVAULTIC_NO_AES: Do not handle AES callback * + * * Expected wolfSSL/wolfCrypt defines from wolfcrypt/types.h or settings.h: * XMALLOC: malloc() equivalent * XREALLOC: realloc() equivalent @@ -68,7 +69,7 @@ #include "ccb_vaultic.h" /* Provide default config struct if needed */ -static const ccbVaultIc_Config gDefaultConfig = CCBVAULTIC_CONFIG_DEFAULT; +static ccbVaultIc_Config gDefaultConfig = CCBVAULTIC_CONFIG_DEFAULT; /* Debug defines */ #ifdef CCBVAULTIC_DEBUG_ALL @@ -194,6 +195,42 @@ static int _GetInfo(ccbVaultIc_Context *c, VLT_TARGET_INFO *out_chipInfo) return _TranslateError(c->vlt_rc); } +static int _GetInfoText(ccbVaultIc_Context* c, int text_len, char* text, + int *out_len) +{ + VLT_TARGET_INFO chipInfo; + int rc = _GetInfo(c, &chipInfo); + if ((rc == 0) && (text != NULL) && (text_len > 0)) { + int len = snprintf(text, text_len, + "VERSION:%.*s\n" + "SERIAL:%02X%02X%02X%02X%02X%02X%02X%02X\n" + "STATE:%02X\n" + "MODE:%02X\n" + "ROLE:%02X\n" + "SELFTEST:%02X\n" + "SPACE:%d\n", + (int)sizeof(chipInfo.au8Firmware), + (const char*)chipInfo.au8Firmware, + chipInfo.au8Serial[0], + chipInfo.au8Serial[1], + chipInfo.au8Serial[2], + chipInfo.au8Serial[3], + chipInfo.au8Serial[4], + chipInfo.au8Serial[5], + chipInfo.au8Serial[6], + chipInfo.au8Serial[7], + chipInfo.enState, + chipInfo.enMode, + chipInfo.enRole, + chipInfo.enSelfTests, + (int)chipInfo.u32Space); + if (out_len != NULL) { + *out_len = len; + } + } + return rc; +} + static VLT_USER_ID _AuthId2VltUserId(int id) { switch(id) { @@ -1143,6 +1180,44 @@ static int HandleCmdCallback(int devId, wc_CryptoInfo* info, rc = 0; }; break; + case CCBVAULTIC_CMD_INFO: + { + /* Issue an info command and convert the results to a text string */ + ccbVaultIc_Info* i = info->cmd.ctx; + + char* text = NULL; + int text_len = 0; + + if(i != NULL) { + text = i->text; + text_len = i->text_len; + } + + rc = _GetInfoText(c, text_len, text, &text_len); + if(i != NULL) { + i->text_len = text_len; + } + }; break; + + case CCBVAULTIC_CMD_LOADACTION: + { + if(_CheckInitializedContext(c) != 0) + break; + rc = ccbVaultIc_LoadAction(c, info->cmd.ctx); + }; break; + + case CCBVAULTIC_CMD_PROVISIONACTION: + { + if(_CheckInitializedContext(c) != 0) + break; + rc = ccbVaultIc_ProvisionAction(c, info->cmd.ctx); + }; break; + + case CCBVAULTIC_CMD_NVMREAD: + { + + }; break; + default: break; } diff --git a/ccb_vaultic/ccb_vaultic.h b/ccb_vaultic/ccb_vaultic.h index bec501c2f..74160ac1e 100644 --- a/ccb_vaultic/ccb_vaultic.h +++ b/ccb_vaultic/ccb_vaultic.h @@ -40,6 +40,14 @@ enum { CCBVAULTIC_SERIAL_LEN = 8, CCBVAULTIC_VERSION_LEN = 32, + + CCBVAULTIC_CMD_INFO = 0x8000, + CCBVAULTIC_CMD_LOADACTION = 0x8001, + CCBVAULTIC_CMD_PROVISIONACTION = 0x8002, + + CCBVAULTIC_CMD_NVMREAD = 0x8100, + + CCBVAULTIC_INFO_LEN = 64, }; /* Configuration choices */ @@ -177,6 +185,18 @@ typedef struct { ccbVaultIc_File* file; } ccbVaultIc_Load; +typedef struct { + int text_len; + char* text; +} ccbVaultIc_Info; + +typedef struct { + int index; + int label_len; + char* label; + int data_len; + char* data; +} ccbVaultIc_Nvm; /* Initialize the VaultIC library and clear the context. * Returns: 0 on success @@ -242,24 +262,25 @@ int ccbVaultIc_CryptoCb(int devId, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" #define CCBVAULTIC_SCP03_ENC_DEFAULT \ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" -#define CCBVAULTIC_AUTH_DEFAULT \ - { \ - .id = CCBVAULTIC_AUTH_ID_DEFAULT, \ - .kind = CCBVAULTIC_AUTH_KIND_SCP03, \ - .auth.scp03 = { \ - .mac_len = sizeof(CCBVAULTIC_SCP03_MAC_DEFAULT), \ - .mac = CCBVAULTIC_SCP03_ENC_DEFAULT, \ - .enc_len = sizeof(CCBVAULTIC_SCP03_MAC_DEFAULT), \ - .enc = CCBVAULTIC_SCP03_ENC_DEFAULT, \ - } \ +#define CCBVAULTIC_AUTH_DEFAULT \ + { \ + .id = CCBVAULTIC_AUTH_ID_DEFAULT, \ + .role = CCBVAULTIC_AUTH_ROLE_UNAPPROVED, \ + .kind = CCBVAULTIC_AUTH_KIND_SCP03, \ + .auth.scp03 = { \ + .mac_len = sizeof(CCBVAULTIC_SCP03_MAC_DEFAULT) - 1, \ + .mac = CCBVAULTIC_SCP03_MAC_DEFAULT, \ + .enc_len = sizeof(CCBVAULTIC_SCP03_ENC_DEFAULT) - 1, \ + .enc = CCBVAULTIC_SCP03_ENC_DEFAULT, \ + } \ } -#define CCBVAULTIC_CONFIG_DEFAULT \ - { \ - .startup_delay_ms = CCBVAULTIC_FAST_START_MS, \ - .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, \ - .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, \ - .auth = CCBVAULTIC_AUTH_DEFAULT, \ +#define CCBVAULTIC_CONFIG_DEFAULT \ + { \ + .startup_delay_ms = CCBVAULTIC_FAST_START_MS, \ + .timeout_ms = CCBVAULTIC_APDU_TIMEOUT_MS, \ + .spi_rate_khz = CCBVAULTIC_SPI_RATE_KHZ, \ + .auth = CCBVAULTIC_AUTH_DEFAULT, \ } #endif /* HAVE_CCBVAULTIC */ diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c new file mode 100644 index 000000000..51d25552c --- /dev/null +++ b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c @@ -0,0 +1,52 @@ +#include + +/* wolfSSL configuration */ +#ifndef WOLFSSL_USER_SETTINGS + #include "wolfssl/options.h" +#endif +#include "wolfssl/wolfcrypt/settings.h" + +/* wolfCrypt includes */ +#include "wolfssl/wolfcrypt/cryptocb.h" /* For wc_cryptInfo */ +#include "wolfssl/wolfcrypt/error-crypt.h" /* For error values */ + +#include "ccb_vaultic.h" + +#include "com_wolfssl_ccbvaultic_ccbVaultIc.h" +/* + * Class: com_wolfssl_ccbvaultic_ccbVaultIc + * Method: GetInfoText + * Signature: (I[B)I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText + (JNIEnv* jenv, jobject jcl, jint devId, jobject out, jlongArray outSz) +{ +#ifndef HAVE_CCBVAULTIC + (void)jenv; (void)jcl; (void)devId; (void)out; (void)outSz; + return (jint)CRYPTOCB_UNAVAILABLE; +#else + (void)jcl; + int rc = 0; + jlong jSize = 0; + + ccbVaultIc_Info info; + XMEMSET(&info, 0, sizeof(info)); + + /* Ok if this buffer is NULL */ + info.text = (*jenv)->GetDirectBufferAddress(jenv, out); + + /* Ok if this length is 0 */ + (*jenv)->GetLongArrayRegion(jenv, outSz, 0, 1, &jSize); + info.text_len = (int)jSize; + + /* Invoke the callback */ + rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_INFO, (void*) &info, NULL); + if(rc == 0) { + /* Update the output length */ + jSize = info.text_len; + (*jenv)->SetLongArrayRegion(jenv, outSz, 0, 1, (jlong*)&jSize); + } + return (jint)rc; +#endif +} + diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h new file mode 100644 index 000000000..29c31949e --- /dev/null +++ b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_wolfssl_ccbvaultic_ccbVaultIc */ + +#ifndef _Included_com_wolfssl_ccbvaultic_ccbVaultIc +#define _Included_com_wolfssl_ccbvaultic_ccbVaultIc +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_wolfssl_ccbvaultic_ccbVaultIc + * Method: GetInfoText + * Signature: (ILjava/nio/ByteBuffer;[J)I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText + (JNIEnv *, jobject, jint, jobject, jlongArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java new file mode 100644 index 000000000..67dc87d68 --- /dev/null +++ b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java @@ -0,0 +1,10 @@ +package com.wolfssl.ccbvaultic; + +import java.nio.ByteBuffer; + +public class ccbVaultIc { + static { + System.loadLibrary("ccbvaulticjni"); + } + public native int GetInfoText(int devId, ByteBuffer out, long[] outSz); +} From 558de63272cbdfbe765da4f9f44927c91f687a9a Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 30 Aug 2023 16:48:28 -0400 Subject: [PATCH 03/10] Updates to finalize JNI API with stubs. --- ccb_vaultic/ccb_vaultic.c | 9 + ccb_vaultic/ccb_vaultic.h | 10 +- .../com_wolfssl_ccbvaultic_ccbVaultIc.c | 60 +++++- .../com_wolfssl_ccbvaultic_ccbVaultIc.h | 21 -- .../com/wolfssl/ccbvaultic/ccbVaultIc.java | 204 ++++++++++++++++++ 5 files changed, 276 insertions(+), 28 deletions(-) delete mode 100644 ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index 3d1c61d68..8cb08db7d 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -499,6 +499,15 @@ static void _ClearContext(ccbVaultIc_Context *c) c->aescbc_key = NULL; } +int ccbVaultIc_GetDefaultConfig(ccbVaultIc_Config* *out_c) +{ + if (out_c == NULL) { + return BAD_FUNC_ARG; + } + *out_c = &gDefaultConfig; + return 0; +} + int ccbVaultIc_Init(ccbVaultIc_Context *c) { int rc = 0; diff --git a/ccb_vaultic/ccb_vaultic.h b/ccb_vaultic/ccb_vaultic.h index 74160ac1e..43ddf091a 100644 --- a/ccb_vaultic/ccb_vaultic.h +++ b/ccb_vaultic/ccb_vaultic.h @@ -47,7 +47,7 @@ enum { CCBVAULTIC_CMD_NVMREAD = 0x8100, - CCBVAULTIC_INFO_LEN = 64, + CCBVAULTIC_INFO_LEN = 128, }; /* Configuration choices */ @@ -83,7 +83,9 @@ enum { CCBVAULTIC_AUTH_ENC_LEN = 0x10, /* AES128 keys only */ CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN = 0x10, + CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX = 0x40, CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN = 0x0, + CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX = 0x40, }; typedef struct { @@ -198,6 +200,12 @@ typedef struct { char* data; } ccbVaultIc_Nvm; +/* Get a pointer to the default configuration data, which is used when the + * context passed into ccbVaultIc_Init has c->config == NULL. This will happen + * when the the CryptoCb_Register() is invoked with a NULL context. + */ +int ccbVaultIc_GetDefaultConfig(ccbVaultIc_Config* *out_c); + /* Initialize the VaultIC library and clear the context. * Returns: 0 on success * BAD_FUNC_ARGS with NULL context diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c index 51d25552c..3a281572b 100644 --- a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c +++ b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c @@ -12,12 +12,8 @@ #include "ccb_vaultic.h" -#include "com_wolfssl_ccbvaultic_ccbVaultIc.h" -/* - * Class: com_wolfssl_ccbvaultic_ccbVaultIc - * Method: GetInfoText - * Signature: (I[B)I - */ +/* Prototypes are in ccbVaultIc.java */ + JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText (JNIEnv* jenv, jobject jcl, jint devId, jobject out, jlongArray outSz) { @@ -50,3 +46,55 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText #endif } + +JNIEXPORT jint JNICALL +Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth(JNIEnv *env, jobject thiz, jint id, + jint role, jint kind, jobject in1, + jlongArray in1_sz, jobject in2, + jlongArray in2_sz) { + // TODO: implement UpdateDefaultAuth() + return (jint)CRYPTOCB_UNAVAILABLE; +} + +JNIEXPORT jint JNICALL +Java_com_wolfssl_ccbvaultic_ccbVaultIc_ProvisionAction(JNIEnv *env, jobject thiz, jint devId, + jboolean selftest, jint id, jint role, + jint kind, jstring in_name1, jobject in1, + jlongArray in1_sz, jstring in_name2, + jobject in2, jlongArray in2_sz, + jstring in_name3, jobject in3, + jlongArray in3_sz) { + // TODO: implement ProvisionAction() + + //ccbVaultIc_Provision prov; + //prov.self_test= selftest; + //switch(kind) + //{ + //setup auth. + //} + //Set the file data + + + /* Invoke the callback */ + //int rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_PROVISIONACTION, (void*) &info, NULL); + + //return (jint)rc; + return (jint)CRYPTOCB_UNAVAILABLE; +} + +JNIEXPORT jint JNICALL +Java_com_wolfssl_ccbvaultic_ccbVaultIc_LoadAction(JNIEnv *env, jobject thiz, jint devId, + jstring in_name1, jobject in1, jlongArray in1_sz, + jstring in_name2, jobject in2, jlongArray in2_sz, + jstring in_name3, jobject in3, + jlongArray in3_sz) { + // TODO: implement LoadAction() + //Handle null or emtpy strings + return (jint)CRYPTOCB_UNAVAILABLE; +} + +JNIEXPORT jint JNICALL +Java_com_wolfssl_ccbvaultic_ccbVaultIc_PerformSelfTest(JNIEnv *env, jobject thiz, jint devId) { + // TODO: implement PerformSelfTest() + return (jint)CRYPTOCB_UNAVAILABLE; +} \ No newline at end of file diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h deleted file mode 100644 index 29c31949e..000000000 --- a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class com_wolfssl_ccbvaultic_ccbVaultIc */ - -#ifndef _Included_com_wolfssl_ccbvaultic_ccbVaultIc -#define _Included_com_wolfssl_ccbvaultic_ccbVaultIc -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: com_wolfssl_ccbvaultic_ccbVaultIc - * Method: GetInfoText - * Signature: (ILjava/nio/ByteBuffer;[J)I - */ -JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText - (JNIEnv *, jobject, jint, jobject, jlongArray); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java index 67dc87d68..ad6fa6aaf 100644 --- a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java +++ b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java @@ -2,9 +2,213 @@ import java.nio.ByteBuffer; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; + public class ccbVaultIc { static { System.loadLibrary("ccbvaulticjni"); } + + /* From ccb_vaultic.h */ + public static final int CCBVAULTIC_SERIAL_LEN = 8; + public static final int CCBVAULTIC_VERSION_LEN = 32; + + public static final int CCBVAULTIC_CMD_INFO = 0x8000; + public static final int CCBVAULTIC_CMD_LOADACTION = 0x8001; + public static final int CCBVAULTIC_CMD_PROVISIONACTION = 0x8002; + + public static final int CCBVAULTIC_CMD_NVMREAD = 0x8100; + + public static final int CCBVAULTIC_INFO_LEN = 128; + public static final int CCBVAULTIC_FAST_START_MS = 700; + public static final int CCBVAULTIC_SLOW_START_MS = 5000; + public static final int CCBVAULTIC_APDU_TIMEOUT_MS = 5000; + public static final int CCBVAULTIC_SPI_RATE_KHZ = 5000; + public static final int CCBVAULTIC_FILE_NAME_LEN_MIN = 0x1; /* At least a NULL */ + public static final int CCBVAULTIC_FILE_NAME_LEN_MAX = 0x10; /* 16 byte limit for names */ + public static final int CCBVAULTIC_FILE_DATA_LEN_MAX = 0x10000; /* 16kB limit for files */ + public static final int CCBVAULTIC_AUTH_ID_MIN = 0; + public static final int CCBVAULTIC_AUTH_ID_MAX = 7; + + public static final int CCBVAULTIC_AUTH_ROLE_NONE = 0; + public static final int CCBVAULTIC_AUTH_ROLE_MANUFACTURER = 1; + public static final int CCBVAULTIC_AUTH_ROLE_UNAPPROVED = 2; + public static final int CCBVAULTIC_AUTH_ROLE_APPROVED = 3; + + public static final int CCBVAULTIC_AUTH_KIND_NONE = 0; + public static final int CCBVAULTIC_AUTH_KIND_PIN = 1; + public static final int CCBVAULTIC_AUTH_KIND_SCP03 = 2; + public static final int CCBVAULTIC_AUTH_KIND_KDF = 3; + + public static final int CCBVAULTIC_AUTH_PIN_LEN_MIN = 0x4; + public static final int CCBVAULTIC_AUTH_PIN_LEN_MAX = 0x20; + + public static final int CCBVAULTIC_AUTH_MAC_LEN = 0x10; /* AES128 keys only */ + public static final int CCBVAULTIC_AUTH_ENC_LEN = 0x10; /* AES128 keys only */ + + public static final int CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN = 0x10; + public static final int CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX = 0x40; + public static final int CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN = 0x0; + public static final int CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX = 0x40; + + public static final int CCBVAULTIC_AUTH_ROLE_MANU = CCBVAULTIC_AUTH_ROLE_MANUFACTURER; + public static final int CCBVAULTIC_AUTH_ROLE_APP = CCBVAULTIC_AUTH_ROLE_APPROVED; + public static final int CCBVAULTIC_AUTH_ROLE_DEBUG = CCBVAULTIC_AUTH_ROLE_UNAPPROVED; + + public static final int CCBVAULTIC_AUTH_ID_MANU = 7; + public static final int CCBVAULTIC_AUTH_ID_APP = 0; + public static final int CCBVAULTIC_AUTH_ID_DEBUG = 1; + + + /* Buffer should be at least CCBVAULTIC_INFO_LEN bytes */ public native int GetInfoText(int devId, ByteBuffer out, long[] outSz); + + public int GetInfoText(int devId, byte[] out) + { + ByteBuffer text = ByteBuffer.allocateDirect(CCBVAULTIC_INFO_LEN); + long[] text_len = {CCBVAULTIC_INFO_LEN}; + int rc = GetInfoText(devId, text, text_len); + + if (rc == 0) { + text.get(out, 0, (int)text_len[0]); + } + return rc; + } + + public native int UpdateDefaultAuth(int id, int role, int kind, + ByteBuffer in1, long[] in1Sz, + ByteBuffer in2, long[] in2Sz); + + public int UpdateDefaultAuth_Pin(int id, int role, byte[] pin) + { + ByteBuffer pinBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_PIN_LEN_MAX); + pinBytes.put(pin, 0, pin.length); + long[] pinLen = {(long)pin.length}; + + return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_PIN, + pinBytes, pinLen, + null, null); + } + + /* Role should be CCBVAULTIC_AUTH_ROLE_APPROVED or _UNAPPROVED */ + public int UpdateDefaultAuth_SCP03(int id, int role, byte[] mac, byte[] enc) + { + ByteBuffer macBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_MAC_LEN); + macBytes.put(mac, 0, mac.length); + long[] macLen = {(long)mac.length}; + + ByteBuffer encBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_ENC_LEN); + encBytes.put(enc, 0, enc.length); + long[] encLen = {(long)enc.length}; + + return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_SCP03, + macBytes, macLen, + encBytes, encLen); + } + + /* Role should be CCBVAULTIC_AUTH_ROLE_APPROVED or _UNAPPROVED */ + public int UpdateDefaultAuth_KDF(int id, int role, byte[] key, byte[] label) + { + ByteBuffer keyBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX); + keyBytes.put(key, 0, key.length); + long[] keyLen = {(long)key.length}; + + ByteBuffer labelBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX); + labelBytes.put(label, 0, label.length); + long[] labelLen = {(long)label.length}; + + return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_KDF, + keyBytes, keyLen, + labelBytes, labelLen); + } + + /* Manufacturer login */ + public int UpdateDefaultAuth_Manu(byte[] pin) + { + return UpdateDefaultAuth_Pin( + CCBVAULTIC_AUTH_ID_MANU, + CCBVAULTIC_AUTH_ROLE_MANU, + pin); + } + + /* App Login */ + public int UpdateDefaultAuth_App(byte[] key, byte[] label) + { + return UpdateDefaultAuth_KDF( + CCBVAULTIC_AUTH_ID_APP, + CCBVAULTIC_AUTH_ROLE_APP, + key, label); + } + + /* Debug */ + public int UpdateDefaultAuth_Debug(byte[] mac, byte[] enc) + { + return UpdateDefaultAuth_SCP03( + CCBVAULTIC_AUTH_ID_DEBUG, + CCBVAULTIC_AUTH_ROLE_DEBUG, + mac, enc); + } + + + public native int ProvisionAction(int devId, + boolean poweron_selftest, + int id, int role, int kind, //create user data + ByteBuffer userin1, long[] userin1Sz, + ByteBuffer userin2, long[] userin2Sz, + String inName1, ByteBuffer in1, long[] in1Sz, + String inName2, ByteBuffer in2, long[] in2Sz, + String inName3, ByteBuffer in3, long[] in3Sz); + public int ProvisionAction_KDF(int devId, + boolean poweron_selftest, + int id, int role, //create user data + byte[] key, byte[] label, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3) + { + //return ProvisionAction(devId, poweron_selftest, id, role, CCBVAULTIC_AUTH_KIND_KDF, + // keyBytes, keyLen, labelBytes, labelLen, + // inName1, in1Bytes, in1Len, + // inName1, in2Bytes, in2Len, + // inName1, in3Bytes, in3Len,) + return -1; + } + public int ProvisionAction_App(int devId, boolean poweron_selftest, + byte[] key, byte[] label, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3) + { + return ProvisionAction_KDF(devId, poweron_selftest, + CCBVAULTIC_AUTH_ID_APP,CCBVAULTIC_AUTH_ROLE_APP, + key, label,inName1, in1, inName2, in2, inName3, in3); + } + public native int LoadAction(int devId, + String inName1, ByteBuffer in1, long[] in1Sz, + String inName2, ByteBuffer in2, long[] in2Sz, + String inName3, ByteBuffer in3, long[] in3Sz); + + public int LoadAction(int devId, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3) + { + //return LoadAction(devId, inName1, in1Bytes, in1Len, + // inName2, in2Bytes, in2Len, + // inName3, in3Bytes, in3Len); + return -1; + } + public KeyManager GenerateKM(byte[] keyFile, byte[] crtFile) + { + return null; + } + + public TrustManager GenerateTM(byte[] cafile) + { + return null; + } + + public native int PerformSelfTest(int devId); + } From 828097a5e499f1fecbae6a47850f4e6b33df9c35 Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 30 Aug 2023 20:28:23 -0400 Subject: [PATCH 04/10] Update to MainActivity --- .../wolfssljni_ndk_gradle/MainActivity.java | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java index febda2c29..cb8705ca3 100644 --- a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java +++ b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java @@ -18,9 +18,11 @@ import java.security.Security; import java.util.concurrent.Executors; +import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; public class MainActivity extends AppCompatActivity { @@ -81,6 +83,7 @@ private void appendDisplayText(String s) }); }; + private final View.OnClickListener sslSocketConnectListener = v -> { setDisplayText("Making simple SSL/TLS connection to:\n" + host + ":" + port + "\n" + @@ -112,17 +115,39 @@ private void appendDisplayText(String s) if (((connectCount % 2) == 0) && (devId != WolfSSL.INVALID_DEVID)) { appendDisplayText("B. Using hardware offload\n"); + ccbVaultIc cv = new ccbVaultIc(); + + // MANU + // cv.UpdateDefaultAuth_Manu("PASSWORD".getBytes()); + + // APP + //cv.UpdateDefaultAuth_App("KEY".getBytes, "LABEL".getBytes()); + wolfProv.registerDevId(devId); wolfProv.setDevId(devId); - ccbVaultIc cv = new ccbVaultIc(); - ByteBuffer text = ByteBuffer.allocateDirect(1024); - long[] text_len = {1024}; - int rc = cv.GetInfoText(devId, text, text_len); - - byte[] data = new byte[1024]; - text.get(data,0,(int)(text_len[0])); - appendDisplayText("GetInfoText rc=" + rc +", text_len=" + text_len[0]+", text=" + new String(data)); + // MANU + //cv.ProvisionAction_App(devId, TRUE, + // "KEY".getBytes(), "LABEL".getBytes(), + // "key.pem", "KEYPEM".getBytes(), + // "crt.pem", "CRTPEM".getBytes(), + // "ca.pem", "CAPEM".getBytes()); + // done; + + // APP: + //byte[] keyFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; + //byte[] crtFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; + //byte[] caFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; + //cv.LoadAction(devId, + // "key.pem", keyFile, + // "crt.pem", crtFile, + // "ca.pem", caFile); + //KeyManager km = cv.GenerateKM(keyFile, crtFile); + //TrustManager tm = cv.GenerateTM(caFile); + + byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; + int rc = cv.GetInfoText(devId,data); + appendDisplayText("GetInfoText rc=" + rc +"\n" + new String(data)); } else { appendDisplayText("B. Using software crypto.\n"); wolfProv.setDevId(WolfSSL.INVALID_DEVID); @@ -135,9 +160,9 @@ private void appendDisplayText(String s) * CA certs from the Android system KeyStore by default. */ SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); - //WolfSSLKeyX509 key = new WolfSSLKeyX509(new KeyStore()); ctx.init(null, null, null); + //ctx.init(km, tm, null); SSLSocketFactory sf = ctx.getSocketFactory(); SSLSocket sock = (SSLSocket) sf.createSocket(host, port); From b6ab88f1ea9f23682063bbe2be96abf368d2a7ca Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Tue, 5 Sep 2023 15:58:59 -0400 Subject: [PATCH 05/10] Updates to finish loading and most of provisioning. App is broken. --- .../wolfssljni_ndk_gradle/MainActivity.java | 152 +++++--- ccb_vaultic/ccb_vaultic.c | 224 ++++++------ ccb_vaultic/ccb_vaultic.h | 9 +- .../com_wolfssl_ccbvaultic_ccbVaultIc.c | 332 ++++++++++++++++-- .../com/wolfssl/ccbvaultic/ccbVaultIc.java | 254 ++++++++++++-- 5 files changed, 741 insertions(+), 230 deletions(-) diff --git a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java index cb8705ca3..bb99f5ab8 100644 --- a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java +++ b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java @@ -83,7 +83,11 @@ private void appendDisplayText(String s) }); }; - + String[] filenames = {"/key.pem","/crt.pem",null}; //"/ca.pem" + byte[] debugMac = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; + byte[] debugEnc = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}; + + private final View.OnClickListener sslSocketConnectListener = v -> { setDisplayText("Making simple SSL/TLS connection to:\n" + host + ":" + port + "\n" + @@ -113,56 +117,95 @@ private void appendDisplayText(String s) ts[1] = System.currentTimeMillis(); connectCount++; - if (((connectCount % 2) == 0) && (devId != WolfSSL.INVALID_DEVID)) { - appendDisplayText("B. Using hardware offload\n"); - ccbVaultIc cv = new ccbVaultIc(); - - // MANU - // cv.UpdateDefaultAuth_Manu("PASSWORD".getBytes()); - - // APP - //cv.UpdateDefaultAuth_App("KEY".getBytes, "LABEL".getBytes()); - - wolfProv.registerDevId(devId); - wolfProv.setDevId(devId); - - // MANU - //cv.ProvisionAction_App(devId, TRUE, - // "KEY".getBytes(), "LABEL".getBytes(), - // "key.pem", "KEYPEM".getBytes(), - // "crt.pem", "CRTPEM".getBytes(), - // "ca.pem", "CAPEM".getBytes()); - // done; - - // APP: - //byte[] keyFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; - //byte[] crtFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; - //byte[] caFile = new byte[ccbVaultIc.CCBVAULTIC_FILE_DATA_LEN_MAX]; - //cv.LoadAction(devId, - // "key.pem", keyFile, - // "crt.pem", crtFile, - // "ca.pem", caFile); - //KeyManager km = cv.GenerateKM(keyFile, crtFile); - //TrustManager tm = cv.GenerateTM(caFile); - - byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; - int rc = cv.GetInfoText(devId,data); - appendDisplayText("GetInfoText rc=" + rc +"\n" + new String(data)); - } else { - appendDisplayText("B. Using software crypto.\n"); + KeyManager[] km = null; + TrustManager[] tm = null; + + ccbVaultIc cv = new ccbVaultIc(); + + if(devId != WolfSSL.INVALID_DEVID) { + switch(connectCount % 3) { + case 1: //SW + { + appendDisplayText("B. Using software crypto.\n"); + wolfProv.setDevId(WolfSSL.INVALID_DEVID); + };break; + case 2: //HW Manu + { + appendDisplayText("B. Using hardware offload - MANU\n"); + + // MANU + cv.UpdateDefaultAuth_Manu(medPin); + + wolfProv.registerDevId(devId); + wolfProv.setDevId(devId); + + // MANU + cv.ProvisionAction_App( + devId, Boolean.TRUE, + medKey, medLabel, + filenames[0], medKeyFile.getBytes(), + filenames[1], medCrtFile.getBytes(), + null, null); + + byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; + int rc = cv.GetInfoText(devId, data); + appendDisplayText("GetInfoText rc=" + rc + "\n" + new String(data)); + + rc = cv.PerformSelfTest(devId); + appendDisplayText("SelfTest rc=" + rc + "\n"); + + // done; + };break; + case 0: //HW App + { + appendDisplayText("B. Using hardware offload - APP\n"); + + cv.UpdateDefaultAuth_Debug(debugMac, debugEnc); + //cv.UpdateDefaultAuth_App("KEY".getBytes, "LABEL".getBytes()); + + wolfProv.registerDevId(devId); + wolfProv.setDevId(devId); + + //Load static data + //km = cv.GenerateKM(medKeyFile.getBytes(), medCrtFile.getBytes()); + + //Load data from VaultIC + ccbVaultIc.LoadFiles loadFiles = cv.LoadAction(devId, + filenames[0], filenames[1],filenames[2]); + if (loadFiles.rc == 0) { + int[] sizes = new int[3]; + if (loadFiles.file1 != null) sizes[0] = loadFiles.file1.length; + if (loadFiles.file2 != null) sizes[1] = loadFiles.file2.length; + if (loadFiles.file3 != null) sizes[2] = loadFiles.file3.length; + appendDisplayText("Loaded File sizes: " + + " 1:" + sizes[0] + + " 2:" + sizes[1] + + " 3:" + sizes[2] + + "\n"); + km = cv.GenerateKM(loadFiles.file1, loadFiles.file2); + tm = cv.GenerateTM(loadFiles.file3); + } + + byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; + int rc = cv.GetInfoText(devId, data); + //appendDisplayText("GetInfoText rc=" + rc + "\n" + new String(data)); + };break; + } + } + else { + appendDisplayText("B. Using internal crypto.\n"); wolfProv.setDevId(WolfSSL.INVALID_DEVID); } ts[2] = System.currentTimeMillis(); appendDisplayText("C. Setting up context and socket\n"); + + SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); /* not setting up KeyStore or TrustStore, wolfJSSE will load * CA certs from the Android system KeyStore by default. */ - SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); - - - ctx.init(null, null, null); - //ctx.init(km, tm, null); + //ctx.init(null, null, null); + ctx.init(km, tm, null); SSLSocketFactory sf = ctx.getSocketFactory(); SSLSocket sock = (SSLSocket) sf.createSocket(host, port); @@ -205,12 +248,25 @@ private void appendDisplayText(String s) sock.close(); ts[7] = System.currentTimeMillis(); - if (((connectCount % 2) == 0) && (devId != WolfSSL.INVALID_DEVID)) { - appendDisplayText("H. Disabling hardware offload\n"); - wolfProv.setDevId(WolfSSL.INVALID_DEVID); - wolfProv.unRegisterDevId(devId); + + if(devId != WolfSSL.INVALID_DEVID) { + switch(connectCount % 3) { + case 1: //SW + { + appendDisplayText("H. Software crypto still enabled\n"); + } + ; + break; + case 0: //HW -App + case 2: //HW - Manu + { + appendDisplayText("H. Disabling hardware offload\n"); + wolfProv.setDevId(WolfSSL.INVALID_DEVID); + wolfProv.unRegisterDevId(devId); + };break; + } } else { - appendDisplayText("H. Software crypto still enabled\n"); + appendDisplayText("H. Internal crypto still enabled\n"); } ts[8] = System.currentTimeMillis(); diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index 8cb08db7d..daf475fc8 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -69,7 +69,7 @@ #include "ccb_vaultic.h" /* Provide default config struct if needed */ -static ccbVaultIc_Config gDefaultConfig = CCBVAULTIC_CONFIG_DEFAULT; +ccbVaultIc_Config gDefaultConfig = CCBVAULTIC_CONFIG_DEFAULT; /* Debug defines */ #ifdef CCBVAULTIC_DEBUG_ALL @@ -628,6 +628,17 @@ void ccbVaultIc_Cleanup(ccbVaultIc_Context *c) c->vlt_rc = vlt_tls_close(); } +int ccbVaultIc_SelfTest( ccbVaultIc_Context *c) +{ + int rc = _CheckInitializedContext(c); + if (rc == 0) { + //XXX SKIP FOR NOW. Failure will set TERMINATED + //c->vlt_rc = VltSelfTest(); + c->vlt_rc = VLT_OK; + rc = _TranslateError(c->vlt_rc); + } + return rc; +} /* Helper. Missing XSTRNLEN */ static int ccbVaultIc_Strnlen(const char *s, int n) { @@ -826,54 +837,52 @@ int ccbVaultIc_ReadFile( ccbVaultIc_Context *c, return rc; } - -static int _SetState(ccbVaultIc_Context *c, VLT_STATE state) +static int _DeleteUser(ccbVaultIc_Context *c, ccbVaultIc_Auth *a) { int rc = _CheckInitializedContext(c); if (rc == 0) { - VLT_TARGET_INFO chipInfo; - rc = _GetInfo(c, &chipInfo); - if (rc == 0) { - if (chipInfo.enState != state) { - c->vlt_rc = VltSetStatus(state); - rc = _TranslateError(c->vlt_rc); - } + if (a == NULL) { + rc = BAD_FUNC_ARG; + } + if(rc == 0) { + VLT_MANAGE_AUTH_DATA authData; + authData.enOperationID = VLT_DELETE_USER; + authData.enUserID = _AuthId2VltUserId(a->id); + + c->vlt_rc = VltManageAuthenticationData(&authData); + rc = _TranslateError(c->vlt_rc); } } return rc; } -static int _SetCreationState(ccbVaultIc_Context *c) -{ - return _SetState(c, VLT_STATE_CREATION); -} -static int _SetActivatedState(ccbVaultIc_Context *c) -{ - return _SetState(c, VLT_STATE_ACTIVATED); -} - -#if 0 -static int _CreatePinUser(ccbVaultIc_Context *c, - int user, int role, - int pin_len, const char* pin) -{ - -} - -static int _CreateScp03User(ccbVaultIc_Context *c, - int user, int role, - int ,a_len, const char* pin) -{ - -} - -static int _CreateKdfUser(ccbVaultIc_Context *c, - int user, int role, - int pin_len, const char* pin) +static int _CreateUser_SCP03(ccbVaultIc_Context *c, int id, int role, + int mac_len, char* mac, + int enc_len, char* enc) { - + int rc = 0; + VLT_MANAGE_AUTH_DATA authData; + authData.enOperationID = VLT_CREATE_USER; + authData.enUserID = _AuthId2VltUserId(id); + authData.u8TryCount = 5; /* From VLT example */ + authData.enSecurityOption = VLT_NO_DELETE_ON_LOCK; + authData.enRoleID = _AuthRole2VltRoleId(role); + authData.enMethod = VLT_AUTH_SCP03; + authData.enChannelLevel = VLT_CMAC_CENC; + authData.data.secret.u8NumberOfKeys = 2; + authData.data.secret.aKeys[0].enKeyID = VLT_KEY_AES_128; + authData.data.secret.aKeys[0].u8Mask = 0xBE; + authData.data.secret.aKeys[0].u16KeyLength = mac_len; + authData.data.secret.aKeys[0].pu8Key = mac; + authData.data.secret.aKeys[1].enKeyID = VLT_KEY_AES_128; + authData.data.secret.aKeys[1].u8Mask = 0xEF; + authData.data.secret.aKeys[1].u16KeyLength = enc_len; + authData.data.secret.aKeys[1].pu8Key = enc; + + c->vlt_rc = VltManageAuthenticationData(&authData); + rc = _TranslateError(c->vlt_rc); + return rc; } - -static int _CreateUser( ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +static int _CreateUser(ccbVaultIc_Context *c, ccbVaultIc_Auth *a) { int rc = _CheckInitializedContext(c); if (rc == 0) { @@ -881,78 +890,68 @@ static int _CreateUser( ccbVaultIc_Context *c, ccbVaultIc_Auth *a) rc = BAD_FUNC_ARG; } if(rc == 0) { - + char mac[CCBVAULTIC_AUTH_MAC_LEN]; + char enc[CCBVAULTIC_AUTH_ENC_LEN]; + + XMEMSET (mac, 0, sizeof(mac)); + XMEMSET (enc, 0, sizeof(enc)); + switch (a->kind) { + case CCBVAULTIC_AUTH_KIND_SCP03: + { + XMEMCPY(mac, a->auth.scp03.mac, a->auth.scp03.mac_len); + XMEMCPY(enc, a->auth.scp03.enc, a->auth.scp03.enc_len); + rc = _CreateUser_SCP03(c, a->id, a->role, + a->auth.scp03.mac_len, mac, + a->auth.scp03.enc_len, enc); + };break; + case CCBVAULTIC_AUTH_KIND_KDF: + { + int rc = _PerformKdf( a->auth.kdf.key_len, a->auth.kdf.key, + a->auth.kdf.label_len, a->auth.kdf.label, + CCBVAULTIC_SERIAL_LEN, c->vlt_serial, + CCBVAULTIC_VERSION_LEN, c->vlt_version, + sizeof(mac), mac, + sizeof(enc), enc); + if (rc == 0) { + rc = _CreateUser_SCP03( c, a->id, a->role, + sizeof(mac), mac, + sizeof(enc), enc); + } + };break; + case CCBVAULTIC_AUTH_KIND_NONE: + case CCBVAULTIC_AUTH_KIND_PIN: + default: + rc = BAD_FUNC_ARG; + break; + } } } - - VLT_MANAGE_AUTH_DATA structAuthSetup; - structAuthSetup.enOperationID = VLT_DELETE_USER; - structAuthSetup.enUserID = VLT_USER0; - for ( VLT_USER_ID i = VLT_USER0; i <= VLT_USER6; i++) { - structAuthSetup.enUserID = i; - VltManageAuthenticationData(&structAuthSetup); - } - - // Create TLS user - //--------------------------------------------------------------------- - structAuthSetup.enOperationID = VLT_CREATE_USER; - structAuthSetup.u8TryCount = 5; - structAuthSetup.enSecurityOption = VLT_NO_DELETE_ON_LOCK; - structAuthSetup.enUserID = TLS_USER_ID; - structAuthSetup.enRoleID = VLT_NON_APPROVED_USER; - -#ifdef USE_SEC_CHANNEL - // SCP03 auth method - //--------------------------------------------------------------------- - VLT_U8 au8S_MacStaticKey[] = SMAC_KEY; - VLT_U8 au8S_EncStaticKey[] = SENC_KEY; - structAuthSetup.enMethod = VLT_AUTH_SCP03; - structAuthSetup.enChannelLevel = VLT_CMAC_CENC; - structAuthSetup.data.secret.u8NumberOfKeys = 2; - structAuthSetup.data.secret.aKeys[0].enKeyID = VLT_KEY_AES_128; - structAuthSetup.data.secret.aKeys[0].u8Mask = 0xBE; - structAuthSetup.data.secret.aKeys[0].u16KeyLength = sizeof(au8S_MacStaticKey); - structAuthSetup.data.secret.aKeys[0].pu8Key = au8S_MacStaticKey; - structAuthSetup.data.secret.aKeys[1].enKeyID = VLT_KEY_AES_128; - structAuthSetup.data.secret.aKeys[1].u8Mask = 0xEF; - structAuthSetup.data.secret.aKeys[1].u16KeyLength = sizeof(au8S_EncStaticKey); - structAuthSetup.data.secret.aKeys[1].pu8Key = au8S_EncStaticKey; - printf("Encrypted channel enabled, TLS_USER = USER%d (SCP03)\n",TLS_USER_ID); -#else - // Create user 00 with password auth method - //--------------------------------------------------------------------- - structAuthSetup.enMethod = VLT_AUTH_PASSWORD; - structAuthSetup.enChannelLevel = VLT_NO_CHANNEL; - structAuthSetup.data.password.u8PasswordLength = TLS_USER_PIN_LEN; - memset(structAuthSetup.data.password.u8Password, 0x00, sizeof (structAuthSetup.data.password.u8Password)); - memcpy(structAuthSetup.data.password.u8Password, (VLT_PU8) TLS_USER_PIN, TLS_USER_PIN_LEN); - printf("Encrypted channel disabled, TLS_USER = USER%d (PIN)\n",TLS_USER_ID); -#endif - - CHECK_STATUS("VltManageAuthenticationData Create Tls User" , VltManageAuthenticationData(&structAuthSetup),TRUE); - - + return rc; } -static int _DeleteUser( ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +static int _SetState(ccbVaultIc_Context *c, VLT_STATE state) { int rc = _CheckInitializedContext(c); if (rc == 0) { - if (a == NULL) { - rc = BAD_FUNC_ARG; - } - if(rc == 0) { - VLT_MANAGE_AUTH_DATA authSetup; - XMEMSET(authSetup, 0, sizeof(authSetup)); - authSetup.enOperationID = VLT_DELETE_USER; - authSetup.enUserID = _AuthId2VltUserId(a->id); - c->vlt_rc = VltManageAuthenticationData(&authSetup); - rc = _TranslateError(c->vlt_rc); + VLT_TARGET_INFO chipInfo; + rc = _GetInfo(c, &chipInfo); + if (rc == 0) { + if (chipInfo.enState != state) { + c->vlt_rc = VltSetStatus(state); + rc = _TranslateError(c->vlt_rc); + } } } return rc; } -#endif +static int _SetCreationState(ccbVaultIc_Context *c) +{ + return _SetState(c, VLT_STATE_CREATION); +} +static int _SetActivatedState(ccbVaultIc_Context *c) +{ + return _SetState(c, VLT_STATE_ACTIVATED); +} /* Perform the load action as the currently authed user */ int ccbVaultIc_LoadAction( ccbVaultIc_Context *c, @@ -967,8 +966,14 @@ int ccbVaultIc_LoadAction( ccbVaultIc_Context *c, if (rc == 0) { int counter = 0; for(counter = 0; counter < l->file_count; counter++) { - rc = ccbVaultIc_ReadFile(c, &l->file[counter]); - if (rc != 0) break; + /* Ok to skip empty files */ + if( (l->file[counter].name != NULL) && + (l->file[counter].name_len > 0) && + (l->file[counter].data != NULL) && + (l->file[counter].data_len > 0)) { + rc = ccbVaultIc_ReadFile(c, &l->file[counter]); + if (rc != 0) break; + } } } } @@ -987,7 +992,7 @@ int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, if (rc == 0) { /* Setting creation mode should delete all users and their files */ - // rc = _SetCreationState(c); + //rc = _SetCreationState(c); } if (rc == 0) { @@ -998,9 +1003,8 @@ int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, /* Add User */ if (rc == 0) { /* Create the requested user */ - //ccbVaultIc_DeleteUser(c, &p->create); - // rc = ccbVaultIc_CreateUser(c, &p->create); - + _DeleteUser(c, &p->create); + rc = _CreateUser(c, &p->create); } /* Create and write file data from the provision structure */ @@ -1222,9 +1226,11 @@ static int HandleCmdCallback(int devId, wc_CryptoInfo* info, rc = ccbVaultIc_ProvisionAction(c, info->cmd.ctx); }; break; - case CCBVAULTIC_CMD_NVMREAD: + case CCBVAULTIC_CMD_SELFTEST: { - + if(_CheckInitializedContext(c) != 0) + break; + rc = ccbVaultIc_SelfTest(c); }; break; default: diff --git a/ccb_vaultic/ccb_vaultic.h b/ccb_vaultic/ccb_vaultic.h index 43ddf091a..0db8ad869 100644 --- a/ccb_vaultic/ccb_vaultic.h +++ b/ccb_vaultic/ccb_vaultic.h @@ -44,8 +44,7 @@ enum { CCBVAULTIC_CMD_INFO = 0x8000, CCBVAULTIC_CMD_LOADACTION = 0x8001, CCBVAULTIC_CMD_PROVISIONACTION = 0x8002, - - CCBVAULTIC_CMD_NVMREAD = 0x8100, + CCBVAULTIC_CMD_SELFTEST = 0x8003, CCBVAULTIC_INFO_LEN = 128, }; @@ -120,6 +119,9 @@ typedef struct { ccbVaultIc_Auth auth; } ccbVaultIc_Config; +/* Storage for default auth config. Declared in ccb_vaultic.c */ +extern ccbVaultIc_Config gDefaultConfig; + typedef struct { int initialized; const ccbVaultIc_Config* config; @@ -242,6 +244,9 @@ int ccbVaultIc_LoadAction( ccbVaultIc_Context *c, int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, const ccbVaultIc_Provision *p); +/* Perform selftest. Chip will timeout on failure */ +int ccbVaultIc_SelfTest( ccbVaultIc_Context *c); + #ifdef WOLF_CRYPTO_CB #include "wolfssl/wolfcrypt/cryptocb.h" /* For wc_CryptInfo */ diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c index 3a281572b..11ce81d60 100644 --- a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c +++ b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c @@ -12,10 +12,17 @@ #include "ccb_vaultic.h" +#ifdef HAVE_CCBVAULTIC +static char defaultAuthStorage1[CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX]; +static char defaultAuthStorage2[CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX]; +static char fileNames[3][CCBVAULTIC_FILE_NAME_LEN_MAX]; +#endif + /* Prototypes are in ccbVaultIc.java */ -JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText - (JNIEnv* jenv, jobject jcl, jint devId, jobject out, jlongArray outSz) +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText ( + JNIEnv* jenv, jobject jcl, + jint devId, jobject out, jlongArray outSz) { #ifndef HAVE_CCBVAULTIC (void)jenv; (void)jcl; (void)devId; (void)out; (void)outSz; @@ -24,8 +31,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText (void)jcl; int rc = 0; jlong jSize = 0; - ccbVaultIc_Info info; + XMEMSET(&info, 0, sizeof(info)); /* Ok if this buffer is NULL */ @@ -47,54 +54,301 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_GetInfoText } -JNIEXPORT jint JNICALL -Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth(JNIEnv *env, jobject thiz, jint id, - jint role, jint kind, jobject in1, - jlongArray in1_sz, jobject in2, - jlongArray in2_sz) { - // TODO: implement UpdateDefaultAuth() +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth( + JNIEnv *jenv, jobject jcl, + jint id, jint role, jint kind, + jobject in1, jlongArray in1_sz, + jobject in2, jlongArray in2_sz) +{ +#ifndef HAVE_CCBVAULTIC + (void)jenv; (void)jcl; (void)id; (void)role; (void)kind; + (void)in1; (void)in1_sz; (void)in2; (void)in2_sz; return (jint)CRYPTOCB_UNAVAILABLE; +#else + int rc = 0; + + char *in1p = NULL; + char *in2p = NULL; + jlong in1Len = 0; + jlong in2Len = 0; + + if (in1 != NULL) in1p = (*jenv)->GetDirectBufferAddress(jenv, in1); + if (in2 != NULL) in2p = (*jenv)->GetDirectBufferAddress(jenv, in2); + + /* Ok if this length is 0 for now */ + if (in1_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &in1Len); + if (in2_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &in2Len); + + switch((int)kind) { + case CCBVAULTIC_AUTH_KIND_NONE: + { + gDefaultConfig.auth.id = (int)id; + gDefaultConfig.auth.role = (int)role; + gDefaultConfig.auth.kind = CCBVAULTIC_AUTH_KIND_NONE; + rc = 0; + }; break; + case CCBVAULTIC_AUTH_KIND_PIN: { + if((in1p == NULL) || (in1Len < CCBVAULTIC_AUTH_PIN_LEN_MIN) || + (in1Len > CCBVAULTIC_AUTH_PIN_LEN_MAX)) { + rc = BAD_FUNC_ARG; + break; + } + /* Save updated info */ + XMEMCPY(defaultAuthStorage1, in1p, in1Len); + + gDefaultConfig.auth.id = (int)id; + gDefaultConfig.auth.role = (int)role; + gDefaultConfig.auth.kind = CCBVAULTIC_AUTH_KIND_PIN; + gDefaultConfig.auth.auth.pin.pin = defaultAuthStorage1; + gDefaultConfig.auth.auth.pin.pin_len = in1Len; + rc = 0; + };break; + case CCBVAULTIC_AUTH_KIND_SCP03: { + if((in1p == NULL) || (in1Len != CCBVAULTIC_AUTH_MAC_LEN) || + (in2p == NULL) || (in2Len != CCBVAULTIC_AUTH_ENC_LEN)) { + rc = BAD_FUNC_ARG; + break; + } + /* Save updated info */ + XMEMCPY(defaultAuthStorage1, in1p, CCBVAULTIC_AUTH_MAC_LEN); + XMEMCPY(defaultAuthStorage2, in2p, CCBVAULTIC_AUTH_ENC_LEN); + + gDefaultConfig.auth.id = (int)id; + gDefaultConfig.auth.role = (int)role; + gDefaultConfig.auth.kind = CCBVAULTIC_AUTH_KIND_SCP03; + gDefaultConfig.auth.auth.scp03.mac = defaultAuthStorage1; + gDefaultConfig.auth.auth.scp03.mac_len = in1Len; + gDefaultConfig.auth.auth.scp03.enc = defaultAuthStorage2; + gDefaultConfig.auth.auth.scp03.enc_len = in2Len; + rc = 0; + };break; + case CCBVAULTIC_AUTH_KIND_KDF: { + if((in1p == NULL) || (in1Len < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || + (in1Len > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX) || + (in2p == NULL) || (in2Len != CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || + (in2Len > CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX)) { + rc = BAD_FUNC_ARG; + break; + } + /* Save updated info */ + XMEMCPY(defaultAuthStorage1, in1p, in1Len); + XMEMCPY(defaultAuthStorage2, in2p, in2Len); + + gDefaultConfig.auth.id = (int)id; + gDefaultConfig.auth.role = (int)role; + gDefaultConfig.auth.kind = CCBVAULTIC_AUTH_KIND_KDF; + gDefaultConfig.auth.auth.scp03.mac = defaultAuthStorage1; + gDefaultConfig.auth.auth.scp03.mac_len = in1Len; + gDefaultConfig.auth.auth.scp03.enc = defaultAuthStorage2; + gDefaultConfig.auth.auth.scp03.enc_len = in2Len; + rc = 0; + };break; + default: + rc = BAD_FUNC_ARG; + } + return (jint)rc; +#endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_ccbvaultic_ccbVaultIc_ProvisionAction(JNIEnv *env, jobject thiz, jint devId, - jboolean selftest, jint id, jint role, - jint kind, jstring in_name1, jobject in1, - jlongArray in1_sz, jstring in_name2, - jobject in2, jlongArray in2_sz, - jstring in_name3, jobject in3, - jlongArray in3_sz) { +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_ProvisionAction( + JNIEnv *jenv, jobject jcl, + jint devId, jboolean selftest, + jint id, jint role, jint kind, + jobject userin1, jlongArray userin1_sz, + jobject userin2, jlongArray userin2_sz, + jstring in_name1, jobject in1, jlongArray in1_sz, + jstring in_name2, jobject in2, jlongArray in2_sz, + jstring in_name3, jobject in3, jlongArray in3_sz) +{ +#ifndef HAVE_CCBVAULTIC + (void)jenv; (void)jcl; (void)devId; (void)selftest; + (void)id; (void)role; (void)kind; + + (void)in_name1; (void)in1; (void)in1_sz; + (void)in_name2; (void)in2; (void)in2_sz; + (void)in_name3; (void)in3; (void)in3_sz; + return (jint)CRYPTOCB_UNAVAILABLE; +#else // TODO: implement ProvisionAction() - //ccbVaultIc_Provision prov; - //prov.self_test= selftest; - //switch(kind) - //{ - //setup auth. - //} - //Set the file data + ccbVaultIc_Provision prov; + jlong jSize; + int rc = 0; + ccbVaultIc_Load l; + ccbVaultIc_File files[3]; + XMEMSET(&prov, 0, sizeof(prov)); + prov.self_test = (int)selftest; + prov.create.id = (int)id; + prov.create.role = (int)role; - /* Invoke the callback */ - //int rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_PROVISIONACTION, (void*) &info, NULL); + switch((int)kind) { + case CCBVAULTIC_AUTH_KIND_KDF: { + /* + prov.create.auth.kdf.key + prov.create.auth.kdf.label + */ + };break; - //return (jint)rc; - return (jint)CRYPTOCB_UNAVAILABLE; + case CCBVAULTIC_AUTH_KIND_SCP03: { + /* + prov.create.auth.scp03.mac + prov.create.auth.scp03.enc + */ + };break; + + case CCBVAULTIC_AUTH_KIND_PIN: + case CCBVAULTIC_AUTH_KIND_NONE: + default: + rc = BAD_FUNC_ARG; + } + if(rc == 0) { + //Set the file data + + XMEMSET(&l, 0, sizeof(l)); + XMEMSET(files, 0, sizeof(files)); + l.file_count = 3; + l.file = files; + + /* Setup file 1 */ + if (in_name1 != NULL) { + l.file[0].name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); + if (l.file[0].name != NULL) { + l.file[0].name_len = XSTRLEN(l.file[0].name); + l.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); + (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &jSize); + l.file[0].data_len = jSize; + } + } + + /* Setup file 2 */ + if (in_name2 != NULL) { + l.file[1].name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); + if (l.file[1].name != NULL) { + l.file[1].name_len = XSTRLEN(l.file[1].name); + l.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); + (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &jSize); + l.file[1].data_len = jSize; + } + } + + /* Setup file 3 */ + if (in_name3 != NULL) { + l.file[2].name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); + if (l.file[2].name != NULL) { + l.file[2].name_len = XSTRLEN(l.file[2].name); + l.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); + (*jenv)->GetLongArrayRegion(jenv, in3_sz, 0, 1, &jSize); + l.file[2].data_len = jSize; + } + } + /* Invoke the callback */ + rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_PROVISIONACTION, (void*) &prov, NULL); + } + //Cleanup strings + /* + * + */ + return (jint)rc; +#endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_ccbvaultic_ccbVaultIc_LoadAction(JNIEnv *env, jobject thiz, jint devId, - jstring in_name1, jobject in1, jlongArray in1_sz, - jstring in_name2, jobject in2, jlongArray in2_sz, - jstring in_name3, jobject in3, - jlongArray in3_sz) { - // TODO: implement LoadAction() - //Handle null or emtpy strings +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_LoadAction( + JNIEnv *jenv, jobject jcl, + jint devId, + jstring in_name1, jobject in1, jlongArray in1_sz, + jstring in_name2, jobject in2, jlongArray in2_sz, + jstring in_name3, jobject in3, jlongArray in3_sz) +{ +#ifndef HAVE_CCBVAULTIC + (void)jenv; (void)jcl; (void)devId; + (void)in_name1; (void)in1; (void)in1_sz; + (void)in_name2; (void)in2; (void)in2_sz; + (void)in_name3; (void)in3; (void)in3_sz; return (jint)CRYPTOCB_UNAVAILABLE; +#else + jlong jSize; + int rc = 0; + ccbVaultIc_Load l; + ccbVaultIc_File files[3]; + + XMEMSET(&l, 0, sizeof(l)); + XMEMSET(files, 0, sizeof(files)); + l.file_count = 3; + l.file = files; + + /* Setup file 1 */ + if(in_name1 != NULL) { + l.file[0].name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); + if (l.file[0].name != NULL) { + l.file[0].name_len = XSTRLEN(l.file[0].name); + l.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); + (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &jSize); + l.file[0].data_len = jSize; + } + } + + /* Setup file 2 */ + if(in_name2 != NULL) { + l.file[1].name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); + if (l.file[1].name != NULL) { + l.file[1].name_len = XSTRLEN(l.file[1].name); + l.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); + (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &jSize); + l.file[1].data_len = jSize; + } + } + + /* Setup file 3 */ + if(in_name3 != NULL) { + l.file[2].name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); + if (l.file[2].name != NULL) { + l.file[2].name_len = XSTRLEN(l.file[2].name); + l.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); + (*jenv)->GetLongArrayRegion(jenv, in3_sz, 0, 1, &jSize); + l.file[2].data_len = jSize; + } + } + + rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_LOADACTION, (void*) &l, NULL); + if(rc == 0) { + /* Update the output lengths */ + jSize = l.file[0].data_len; + (*jenv)->SetLongArrayRegion(jenv, in1_sz, 0, 1, (jlong*)&jSize); + jSize = l.file[1].data_len; + (*jenv)->SetLongArrayRegion(jenv, in2_sz, 0, 1, (jlong*)&jSize); + jSize = l.file[2].data_len; + (*jenv)->SetLongArrayRegion(jenv, in3_sz, 0, 1, (jlong*)&jSize); + } + + if ((in_name1 != NULL) && (l.file[0].name != NULL)) { + (*jenv)->ReleaseStringUTFChars(jenv, in_name1, l.file[0].name); + } + if ((in_name2 != NULL) && (l.file[1].name != NULL)) { + (*jenv)->ReleaseStringUTFChars(jenv, in_name2, l.file[1].name); + } + if ((in_name3 != NULL) && (l.file[2].name != NULL)) { + (*jenv)->ReleaseStringUTFChars(jenv, in_name3, l.file[2].name); + } + return rc; +#endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_ccbvaultic_ccbVaultIc_PerformSelfTest(JNIEnv *env, jobject thiz, jint devId) { - // TODO: implement PerformSelfTest() +JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_PerformSelfTest( + JNIEnv *jenv, jobject jcl, + jint devId) +{ +#ifndef HAVE_CCBVAULTIC + (void)jenv; (void)jcl; (void)devId; return (jint)CRYPTOCB_UNAVAILABLE; +#else + (void)jcl; + int rc = 0; + + + /* Invoke the callback */ + rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_SELFTEST, NULL, NULL); + return (jint)rc; + +#endif } \ No newline at end of file diff --git a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java index ad6fa6aaf..1a79bfda3 100644 --- a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java +++ b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java @@ -1,8 +1,23 @@ package com.wolfssl.ccbvaultic; +import android.util.Base64; + +import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; +import java.security.BasicPermission; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.EncodedKeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Arrays; +import java.util.Collection; import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManager; public class ccbVaultIc { @@ -61,6 +76,30 @@ public class ccbVaultIc { public static final int CCBVAULTIC_AUTH_ID_DEBUG = 1; + public void SetByteBufferWithLen(ByteBuffer byteBuffer, long[] len, byte[] inData) + { + if ((byteBuffer == null) || (len == null)) { + return; + } + if((inData == null) || (inData.length == 0)) { + len[0] = 0; + return; + } + int minLen = Math.min(byteBuffer.limit(), inData.length); + byteBuffer.put(inData, 0 , minLen); + len[0] = minLen; + } + + public byte[] GetByteBufferWithLen(ByteBuffer byteBuffer, long[] len) + { + if ((byteBuffer == null) || (len == null) || (len[0] <= 0)) { + return null; + } + byte[] out = new byte[(int)len[0]]; + byteBuffer.get(out, 0, (int)len[0]); + return out; + } + /* Buffer should be at least CCBVAULTIC_INFO_LEN bytes */ public native int GetInfoText(int devId, ByteBuffer out, long[] outSz); @@ -71,7 +110,8 @@ public int GetInfoText(int devId, byte[] out) int rc = GetInfoText(devId, text, text_len); if (rc == 0) { - text.get(out, 0, (int)text_len[0]); + int minLen = Math.min((int)text_len[0], out.length); + text.get(out, 0, minLen); } return rc; } @@ -83,8 +123,8 @@ public native int UpdateDefaultAuth(int id, int role, int kind, public int UpdateDefaultAuth_Pin(int id, int role, byte[] pin) { ByteBuffer pinBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_PIN_LEN_MAX); - pinBytes.put(pin, 0, pin.length); - long[] pinLen = {(long)pin.length}; + long[] pinLen = {0}; + SetByteBufferWithLen(pinBytes, pinLen, pin); return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_PIN, pinBytes, pinLen, @@ -95,12 +135,13 @@ public int UpdateDefaultAuth_Pin(int id, int role, byte[] pin) public int UpdateDefaultAuth_SCP03(int id, int role, byte[] mac, byte[] enc) { ByteBuffer macBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_MAC_LEN); - macBytes.put(mac, 0, mac.length); - long[] macLen = {(long)mac.length}; + long[] macLen = {0}; ByteBuffer encBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_ENC_LEN); - encBytes.put(enc, 0, enc.length); - long[] encLen = {(long)enc.length}; + long[] encLen = {0}; + + SetByteBufferWithLen(macBytes, macLen, mac); + SetByteBufferWithLen(encBytes, encLen, enc); return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_SCP03, macBytes, macLen, @@ -111,12 +152,13 @@ public int UpdateDefaultAuth_SCP03(int id, int role, byte[] mac, byte[] enc) public int UpdateDefaultAuth_KDF(int id, int role, byte[] key, byte[] label) { ByteBuffer keyBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX); - keyBytes.put(key, 0, key.length); - long[] keyLen = {(long)key.length}; + long[] keyLen = {0}; ByteBuffer labelBytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX); - labelBytes.put(label, 0, label.length); - long[] labelLen = {(long)label.length}; + long[] labelLen = {0}; + + SetByteBufferWithLen(keyBytes, keyLen, key); + SetByteBufferWithLen(labelBytes, labelLen, label); return UpdateDefaultAuth(id, role, CCBVAULTIC_AUTH_KIND_KDF, keyBytes, keyLen, @@ -141,7 +183,7 @@ public int UpdateDefaultAuth_App(byte[] key, byte[] label) key, label); } - /* Debug */ + /* Debug login*/ public int UpdateDefaultAuth_Debug(byte[] mac, byte[] enc) { return UpdateDefaultAuth_SCP03( @@ -159,6 +201,39 @@ public native int ProvisionAction(int devId, String inName1, ByteBuffer in1, long[] in1Sz, String inName2, ByteBuffer in2, long[] in2Sz, String inName3, ByteBuffer in3, long[] in3Sz); + public int ProvisionAction( int devId, + boolean poweron_selftest, + int id, int role, int kind, + byte[] userin1, byte[] userin2, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3 + ) + { + ByteBuffer userin1Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX); + long[] userin1Len = {0}; + ByteBuffer userin2Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX); + long[] userin2Len = {0}; + ByteBuffer in1Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] in1Len = {0}; + ByteBuffer in2Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] in2Len = {0}; + ByteBuffer in3Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] in3Len = {0}; + + SetByteBufferWithLen(userin1Bytes, userin1Len, userin1); + SetByteBufferWithLen(userin2Bytes, userin2Len, userin2); + SetByteBufferWithLen(in1Bytes, in1Len, in1); + SetByteBufferWithLen(in2Bytes, in2Len, in2); + SetByteBufferWithLen(in3Bytes, in3Len, in3); + + return ProvisionAction(devId, poweron_selftest, + id, role, + kind, userin1Bytes, userin1Len, userin2Bytes, userin2Len, + inName1, in1Bytes, in1Len, + inName2, in2Bytes, in2Len, + inName3, in3Bytes, in3Len); + } public int ProvisionAction_KDF(int devId, boolean poweron_selftest, int id, int role, //create user data @@ -167,12 +242,20 @@ public int ProvisionAction_KDF(int devId, String inName2, byte[] in2, String inName3, byte[] in3) { - //return ProvisionAction(devId, poweron_selftest, id, role, CCBVAULTIC_AUTH_KIND_KDF, - // keyBytes, keyLen, labelBytes, labelLen, - // inName1, in1Bytes, in1Len, - // inName1, in2Bytes, in2Len, - // inName1, in3Bytes, in3Len,) - return -1; + if((key == null) || (key.length < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || + (key.length > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX)) { + return -1; + } + if((label == null) || (label.length < CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || + (label.length > CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX)) { + return -1; + } + return ProvisionAction(devId, poweron_selftest, + id, role, + CCBVAULTIC_AUTH_KIND_KDF, key, label, + inName1, in1, + inName2, in2, + inName3, in3); } public int ProvisionAction_App(int devId, boolean poweron_selftest, byte[] key, byte[] label, @@ -181,31 +264,138 @@ public int ProvisionAction_App(int devId, boolean poweron_selftest, String inName3, byte[] in3) { return ProvisionAction_KDF(devId, poweron_selftest, - CCBVAULTIC_AUTH_ID_APP,CCBVAULTIC_AUTH_ROLE_APP, + CCBVAULTIC_AUTH_ID_APP, CCBVAULTIC_AUTH_ROLE_APP, key, label,inName1, in1, inName2, in2, inName3, in3); } + + /* Invoke the load action using the provided devId */ public native int LoadAction(int devId, - String inName1, ByteBuffer in1, long[] in1Sz, - String inName2, ByteBuffer in2, long[] in2Sz, - String inName3, ByteBuffer in3, long[] in3Sz); + String inName1, ByteBuffer out1Bytes, long[] out1Len, + String inName2, ByteBuffer out2Bytes, long[] out2Len, + String inName3, ByteBuffer out3Bytes, long[] out3Len); + + public class LoadFiles { + public int rc; + public byte[] file1; + public byte[] file2; + public byte[] file3; + } + public LoadFiles LoadAction(int devId, + String inName1, + String inName2, + String inName3) + { + ByteBuffer out1Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] out1Len = {CCBVAULTIC_FILE_DATA_LEN_MAX}; + ByteBuffer out2Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] out2Len = {CCBVAULTIC_FILE_DATA_LEN_MAX}; + ByteBuffer out3Bytes = ByteBuffer.allocateDirect(CCBVAULTIC_FILE_DATA_LEN_MAX); + long[] out3Len = {CCBVAULTIC_FILE_DATA_LEN_MAX}; + + LoadFiles out = new LoadFiles(); + out.rc= LoadAction(devId, + inName1, out1Bytes, out1Len, + inName2, out2Bytes, out2Len, + inName3, out3Bytes, out3Len); + if (out.rc == 0) { + out.file1 = GetByteBufferWithLen(out1Bytes,out1Len); + out.file2 = GetByteBufferWithLen(out2Bytes,out2Len); + out.file3 = GetByteBufferWithLen(out3Bytes,out3Len); + } + return out; + } + - public int LoadAction(int devId, - String inName1, byte[] in1, - String inName2, byte[] in2, - String inName3, byte[] in3) + /* Copy data that is not a PEM header. Note this does not handle non-base64 text prior to the + * first header. */ + private byte[] StripPemHeaders(byte[] data) { - //return LoadAction(devId, inName1, in1Bytes, in1Len, - // inName2, in2Bytes, in2Len, - // inName3, in3Bytes, in3Len); - return -1; + if (data == null) return null; + /* Don't copy sections "-----xxxx-----" + * ^head + * ^desc + * ^foot + */ + int outSize = 0; + byte[] outData = new byte[data.length]; + boolean inHead = false; + boolean inDesc = false; + boolean inFoot = false; + for (byte datum : data) { + if (datum == '-') { + if (!inHead) { + inHead = true; + } else { + if (inDesc) { + inFoot = true; + } + } + // Always remove -'s + } else { + // Not a - + if (inFoot) { + //End of footer + inFoot = false; + inDesc = false; + inHead = false; + } else { + if (inHead) { + inDesc = true; + } + } + if (!inDesc) { + //Keep this byte + outData[outSize++] = datum; + } + } + } + //Truncate the output + return Arrays.copyOfRange(outData, 0, outSize); } - public KeyManager GenerateKM(byte[] keyFile, byte[] crtFile) + public KeyManager[] GenerateKM(byte[] keyPem, byte[] crtPem) { + /* Check for empty or missing files */ + if( (keyPem == null) || (keyPem.length == 0) || + (crtPem == null) || (crtPem.length == 0)) { + return null; + } + try { + byte[] keyFile = Base64.decode(StripPemHeaders(keyPem),Base64.DEFAULT); + byte[] crtFile = Base64.decode(StripPemHeaders(crtPem),Base64.DEFAULT); + + /* Parse the provided keyFile into a PrivateKey */ + KeyFactory kF = KeyFactory.getInstance("RSA"); + PrivateKey pK = kF.generatePrivate(new PKCS8EncodedKeySpec(keyFile)); + + /* Parse the provided crtFile into a X509Certificate[] CertChain */ + CertificateFactory cF = CertificateFactory.getInstance("X.509"); + Collection certs = + cF.generateCertificates(new ByteArrayInputStream(crtFile)); + X509Certificate[] certChain = new X509Certificate[certs.size()]; + int i=0; + for (Certificate cert:certs) { + certChain[i++] = (X509Certificate) cert; + } + + /* Create a PKCS12 KeyStore and put the PrivateKey and CertChain in */ + KeyStore kS = KeyStore.getInstance("PKCS12"); + kS.load(null, null); + kS.setKeyEntry("alias", pK, null, certChain); + + /* Create a KeyManagerFactory and Init it using the KeyStore */ + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(kS, null); + return kmf.getKeyManagers(); + } + catch (Exception e){ + /* Do something?*/ + } return null; } - public TrustManager GenerateTM(byte[] cafile) + public TrustManager[] GenerateTM(byte[] cafile) { + return null; } From 0928209c90a3706b56f17e2700dd51d2e9b4b58a Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 6 Sep 2023 01:15:58 -0400 Subject: [PATCH 06/10] Updates with working provisioning and kdf users. --- .../wolfssljni_ndk_gradle/MainActivity.java | 165 ++++++++------ ccb_vaultic/ccb_vaultic.c | 47 ++-- ccb_vaultic/ccb_vaultic.h | 2 +- .../com_wolfssl_ccbvaultic_ccbVaultIc.c | 201 ++++++++++-------- 4 files changed, 234 insertions(+), 181 deletions(-) diff --git a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java index bb99f5ab8..a37517f5b 100644 --- a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java +++ b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java @@ -84,15 +84,33 @@ private void appendDisplayText(String s) }; String[] filenames = {"/key.pem","/crt.pem",null}; //"/ca.pem" - byte[] debugMac = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; - byte[] debugEnc = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}; + byte[] debugPin = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}; + + byte[] debugMac = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; + byte[] debugEnc = { 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}; + + + byte[] debugKey = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}; + byte[] debugLabel = "Debug Label".getBytes(); + + byte[] debugFile1 = "FILE1".getBytes(); + byte[] debugFile2 = "FILE2".getBytes(); + + + public String getCmd = "GET / HTTP/1.1\r\n" + + "Host: www.wolfssl.com\r\n" + + "Accept: */*\r\n\r\n"; private final View.OnClickListener sslSocketConnectListener = v -> { - setDisplayText("Making simple SSL/TLS connection to:\n" + + setDisplayText("Making simple SSL/TLS connection to:" + host + ":" + port + "\n" + - "See logcat output for details (adb logcat).\n" + - "...\n"); + "See logcat output for details (adb logcat).\n"); Executors.newSingleThreadExecutor().execute(() -> { try { /* Enable wolfJSSE debug messages */ @@ -107,6 +125,10 @@ private void appendDisplayText(String s) boolean limitCipherProtocol = true; //boolean limitCipherProtocol = false; + /* Select if using Debug or KDF user for HW provisioning and connection */ + boolean useKdfUser = true; + //boolean useKdfUser = false; + long[] ts = new long[10]; ts[0] = System.currentTimeMillis(); @@ -119,7 +141,7 @@ private void appendDisplayText(String s) KeyManager[] km = null; TrustManager[] tm = null; - + long totalRead = 0; ccbVaultIc cv = new ccbVaultIc(); if(devId != WolfSSL.INVALID_DEVID) { @@ -134,34 +156,45 @@ private void appendDisplayText(String s) appendDisplayText("B. Using hardware offload - MANU\n"); // MANU - cv.UpdateDefaultAuth_Manu(medPin); + cv.UpdateDefaultAuth_Manu(debugPin); wolfProv.registerDevId(devId); wolfProv.setDevId(devId); - // MANU - cv.ProvisionAction_App( - devId, Boolean.TRUE, - medKey, medLabel, - filenames[0], medKeyFile.getBytes(), - filenames[1], medCrtFile.getBytes(), - null, null); - + int rc = 0; + if(useKdfUser) { + rc = cv.ProvisionAction_App( + devId, Boolean.TRUE, + debugKey, debugLabel + filenames[0], debugFile1, + filenames[1], debugFile2, + null, null); + } else { + rc = cv.ProvisionAction_Debug( + devId, Boolean.TRUE, + debugMac, debugEnc, + filenames[0], debugFile1, + filenames[1], debugFile2, + null, null); + } + appendDisplayText("Provision rc=" + rc + "\n" ); byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; - int rc = cv.GetInfoText(devId, data); + rc = cv.GetInfoText(devId, data); appendDisplayText("GetInfoText rc=" + rc + "\n" + new String(data)); rc = cv.PerformSelfTest(devId); appendDisplayText("SelfTest rc=" + rc + "\n"); - - // done; + // Skip the connection tests };break; case 0: //HW App { appendDisplayText("B. Using hardware offload - APP\n"); - cv.UpdateDefaultAuth_Debug(debugMac, debugEnc); - //cv.UpdateDefaultAuth_App("KEY".getBytes, "LABEL".getBytes()); + if(useKdfUser) { + cv.UpdateDefaultAuth_App(debugKey, debugLabel); + } else { + cv.UpdateDefaultAuth_Debug(debugMac, debugEnc); + } wolfProv.registerDevId(devId); wolfProv.setDevId(devId); @@ -188,7 +221,7 @@ private void appendDisplayText(String s) byte[] data = new byte[ccbVaultIc.CCBVAULTIC_INFO_LEN]; int rc = cv.GetInfoText(devId, data); - //appendDisplayText("GetInfoText rc=" + rc + "\n" + new String(data)); + appendDisplayText("GetInfoText rc=" + rc + "\n" + new String(data)); };break; } } @@ -198,65 +231,61 @@ private void appendDisplayText(String s) } ts[2] = System.currentTimeMillis(); - appendDisplayText("C. Setting up context and socket\n"); - - SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); - /* not setting up KeyStore or TrustStore, wolfJSSE will load - * CA certs from the Android system KeyStore by default. */ - //ctx.init(null, null, null); - ctx.init(km, tm, null); + // Skip the connection if we are doing HW MANU + if((devId == WolfSSL.INVALID_DEVID)||((connectCount % 3) != 2)) { + appendDisplayText("C. Setting up context and socket\n"); - SSLSocketFactory sf = ctx.getSocketFactory(); - SSLSocket sock = (SSLSocket) sf.createSocket(host, port); + SSLContext ctx = SSLContext.getInstance("TLS", wolfProv.getName()); + /* not setting up KeyStore or TrustStore, wolfJSSE will load + * CA certs from the Android system KeyStore by default. */ + ctx.init(km, tm, null); - if (limitCipherProtocol) { - /* Limit cipherSuites and protocol */ - String[] cipherSuites = new String[]{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}; - sock.setEnabledCipherSuites(cipherSuites); - String[] protocols = new String[]{"TLSv1.2"}; - sock.setEnabledProtocols(protocols); - } + SSLSocketFactory sf = ctx.getSocketFactory(); + SSLSocket sock = (SSLSocket) sf.createSocket(host, port); - ts[3] = System.currentTimeMillis(); - appendDisplayText("D. Starting Handshake\n"); - sock.startHandshake(); - - ts[4] = System.currentTimeMillis(); - appendDisplayText("E. Sending GET Request\n"); - String getCmd = "GET / HTTP/1.1\r\n" + - "Host: www.wolfssl.com\r\n" + - "Accept: */*\r\n\r\n"; - sock.getOutputStream().write(getCmd.getBytes()); - - ts[5] = System.currentTimeMillis(); - long sizeLimit = 10 * 1024; - appendDisplayText("F. Receiving at least " + sizeLimit + " bytes\n"); - byte[] data = new byte[4 * 1024]; - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - long totalRead = 0; - /* Read the first 10kB */ - while (totalRead < sizeLimit) { - int nRead = sock.getInputStream().read(data, 0, data.length); - if (nRead < 0) break; - buffer.write(data, 0, nRead); - totalRead = totalRead + nRead; - } + if (limitCipherProtocol) { + /* Limit cipherSuites and protocol */ + String[] cipherSuites = new String[]{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}; + sock.setEnabledCipherSuites(cipherSuites); + String[] protocols = new String[]{"TLSv1.2"}; + sock.setEnabledProtocols(protocols); + } - ts[6] = System.currentTimeMillis(); - appendDisplayText("G. Closing socket\n"); - sock.close(); + ts[3] = System.currentTimeMillis(); + appendDisplayText("D. Starting Handshake\n"); + sock.startHandshake(); + + ts[4] = System.currentTimeMillis(); + appendDisplayText("E. Sending GET Request\n"); + sock.getOutputStream().write(getCmd.getBytes()); + + ts[5] = System.currentTimeMillis(); + long sizeLimit = 10 * 1024; + appendDisplayText("F. Receiving at least " + sizeLimit + " bytes\n"); + byte[] data = new byte[4 * 1024]; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + /* Read the first 10kB */ + while (totalRead < sizeLimit) { + int nRead = sock.getInputStream().read(data, 0, data.length); + if (nRead < 0) break; + buffer.write(data, 0, nRead); + totalRead = totalRead + nRead; + } - ts[7] = System.currentTimeMillis(); + ts[6] = System.currentTimeMillis(); + appendDisplayText("G. Closing socket\n"); + sock.close(); + ts[7] = System.currentTimeMillis(); + } if(devId != WolfSSL.INVALID_DEVID) { switch(connectCount % 3) { case 1: //SW { appendDisplayText("H. Software crypto still enabled\n"); - } - ; - break; + };break; case 0: //HW -App case 2: //HW - Manu { diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index daf475fc8..1522d2488 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -743,7 +743,7 @@ int ccbVaultIc_CreateUserFile( ccbVaultIc_Context *c, entryParams.u8EntryType = VLT_FILE_ENTRY; c->vlt_rc = VltFsCreate( - (VLT_U16)f->name_len, + (VLT_U16)f->name_len+1, (VLT_PU8)f->name, &entryParams, (VLT_USER_ID) userId); /* Owner */ @@ -837,7 +837,7 @@ int ccbVaultIc_ReadFile( ccbVaultIc_Context *c, return rc; } -static int _DeleteUser(ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +static int _DeleteUser(ccbVaultIc_Context *c, const ccbVaultIc_Auth *a) { int rc = _CheckInitializedContext(c); if (rc == 0) { @@ -846,6 +846,7 @@ static int _DeleteUser(ccbVaultIc_Context *c, ccbVaultIc_Auth *a) } if(rc == 0) { VLT_MANAGE_AUTH_DATA authData; + XMEMSET(&authData, 0, sizeof(authData)); authData.enOperationID = VLT_DELETE_USER; authData.enUserID = _AuthId2VltUserId(a->id); @@ -861,6 +862,8 @@ static int _CreateUser_SCP03(ccbVaultIc_Context *c, int id, int role, { int rc = 0; VLT_MANAGE_AUTH_DATA authData; + XMEMSET(&authData, 0, sizeof(authData)); + authData.enOperationID = VLT_CREATE_USER; authData.enUserID = _AuthId2VltUserId(id); authData.u8TryCount = 5; /* From VLT example */ @@ -872,17 +875,17 @@ static int _CreateUser_SCP03(ccbVaultIc_Context *c, int id, int role, authData.data.secret.aKeys[0].enKeyID = VLT_KEY_AES_128; authData.data.secret.aKeys[0].u8Mask = 0xBE; authData.data.secret.aKeys[0].u16KeyLength = mac_len; - authData.data.secret.aKeys[0].pu8Key = mac; + authData.data.secret.aKeys[0].pu8Key = (VLT_PU8) mac; authData.data.secret.aKeys[1].enKeyID = VLT_KEY_AES_128; authData.data.secret.aKeys[1].u8Mask = 0xEF; authData.data.secret.aKeys[1].u16KeyLength = enc_len; - authData.data.secret.aKeys[1].pu8Key = enc; + authData.data.secret.aKeys[1].pu8Key = (VLT_PU8) enc; c->vlt_rc = VltManageAuthenticationData(&authData); rc = _TranslateError(c->vlt_rc); return rc; } -static int _CreateUser(ccbVaultIc_Context *c, ccbVaultIc_Auth *a) +static int _CreateUser(ccbVaultIc_Context *c,const ccbVaultIc_Auth *a) { int rc = _CheckInitializedContext(c); if (rc == 0) { @@ -992,7 +995,7 @@ int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, if (rc == 0) { /* Setting creation mode should delete all users and their files */ - //rc = _SetCreationState(c); + rc = _SetCreationState(c); } if (rc == 0) { @@ -1011,25 +1014,33 @@ int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, if (rc == 0) { int counter = 0; int userId = p->create.id; - int adminId = c->config->auth.id; + int adminId = 0; + ccbVaultIc_Config *config = c->config; + if(config == NULL) { + ccbVaultIc_GetDefaultConfig(&config); + } + adminId = config->auth.id; for(counter = 0; counter < p->file_count; counter++) { - /* Delete any existing file. Ignore errors */ - ccbVaultIc_DeleteFile(c, &p->file[counter]); - - /* Create the file */ - rc = ccbVaultIc_CreateUserFile(c, &p->file[counter], - userId, adminId); - if (rc == 0) { - /* Write the file */ - rc = ccbVaultIc_WriteFile(c, &p->file[counter]); + if( (p->file[counter].name != NULL) && + (p->file[counter].name_len > 0)) { + /* Delete any existing file. Ignore errors */ + ccbVaultIc_DeleteFile(c, &p->file[counter]); + + /* Create the file */ + rc = ccbVaultIc_CreateUserFile(c, &p->file[counter], + userId, adminId); + if (rc == 0) { + /* Write the file */ + rc = ccbVaultIc_WriteFile(c, &p->file[counter]); + } + if (rc != 0) break; } - if (rc != 0) break; } } if (rc == 0) { /* Set Activated State */ - // rc = _SetActivatedState(c); + rc = _SetActivatedState(c); } } return rc; diff --git a/ccb_vaultic/ccb_vaultic.h b/ccb_vaultic/ccb_vaultic.h index 0db8ad869..19e5f69f1 100644 --- a/ccb_vaultic/ccb_vaultic.h +++ b/ccb_vaultic/ccb_vaultic.h @@ -180,7 +180,7 @@ typedef struct { int self_test; ccbVaultIc_Auth create; int file_count; - const ccbVaultIc_File *file; + ccbVaultIc_File *file; } ccbVaultIc_Provision; /* Data provided to Load action */ diff --git a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c index 11ce81d60..867e6ce51 100644 --- a/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c +++ b/ccb_vaultic/com_wolfssl_ccbvaultic_ccbVaultIc.c @@ -74,8 +74,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth( if (in1 != NULL) in1p = (*jenv)->GetDirectBufferAddress(jenv, in1); if (in2 != NULL) in2p = (*jenv)->GetDirectBufferAddress(jenv, in2); - - /* Ok if this length is 0 for now */ if (in1_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &in1Len); if (in2_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &in2Len); @@ -125,7 +123,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth( case CCBVAULTIC_AUTH_KIND_KDF: { if((in1p == NULL) || (in1Len < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || (in1Len > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX) || - (in2p == NULL) || (in2Len != CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || + (in2p == NULL) || (in2Len < CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || (in2Len > CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX)) { rc = BAD_FUNC_ARG; break; @@ -137,10 +135,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_UpdateDefaultAuth( gDefaultConfig.auth.id = (int)id; gDefaultConfig.auth.role = (int)role; gDefaultConfig.auth.kind = CCBVAULTIC_AUTH_KIND_KDF; - gDefaultConfig.auth.auth.scp03.mac = defaultAuthStorage1; - gDefaultConfig.auth.auth.scp03.mac_len = in1Len; - gDefaultConfig.auth.auth.scp03.enc = defaultAuthStorage2; - gDefaultConfig.auth.auth.scp03.enc_len = in2Len; + gDefaultConfig.auth.auth.kdf.key = defaultAuthStorage1; + gDefaultConfig.auth.auth.kdf.key_len = in1Len; + gDefaultConfig.auth.auth.kdf.label = defaultAuthStorage2; + gDefaultConfig.auth.auth.kdf.label_len = in2Len; rc = 0; };break; default: @@ -163,38 +161,66 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_ProvisionAction( #ifndef HAVE_CCBVAULTIC (void)jenv; (void)jcl; (void)devId; (void)selftest; (void)id; (void)role; (void)kind; - + (void)userin1; (void)userin1_sz; + (void)userin2; (void)userin2_sz; (void)in_name1; (void)in1; (void)in1_sz; (void)in_name2; (void)in2; (void)in2_sz; (void)in_name3; (void)in3; (void)in3_sz; return (jint)CRYPTOCB_UNAVAILABLE; #else - // TODO: implement ProvisionAction() - - ccbVaultIc_Provision prov; - jlong jSize; int rc = 0; - ccbVaultIc_Load l; + jlong jSize; + const char *name; + ccbVaultIc_Provision p; ccbVaultIc_File files[3]; + char filenames[3][CCBVAULTIC_FILE_NAME_LEN_MAX]; - XMEMSET(&prov, 0, sizeof(prov)); - prov.self_test = (int)selftest; - prov.create.id = (int)id; - prov.create.role = (int)role; + char *userin1p = NULL; + char *userin2p = NULL; + jlong userin1Len = 0; + jlong userin2Len = 0; - switch((int)kind) { + if (in1 != NULL) userin1p = (*jenv)->GetDirectBufferAddress(jenv, userin1); + if (in2 != NULL) userin2p = (*jenv)->GetDirectBufferAddress(jenv, userin2); + if (in1_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, userin1_sz, 0, 1, &userin1Len); + if (in2_sz != NULL) (*jenv)->GetLongArrayRegion(jenv, userin2_sz, 0, 1, &userin2Len); + + XMEMSET(&p, 0, sizeof(p)); + XMEMSET(files, 0, sizeof(files)); + XMEMSET(filenames, 0, sizeof(filenames)); + + p.self_test = (int)selftest; + p.create.id = (int)id; + p.create.role = (int)role; + p.create.kind = (int)kind; + p.file_count = 3; + p.file = files; + + switch(p.create.kind) { case CCBVAULTIC_AUTH_KIND_KDF: { - /* - prov.create.auth.kdf.key - prov.create.auth.kdf.label - */ + if((userin1p == NULL) || (userin1Len < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || + (userin1Len > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX) || + (userin2p == NULL) || (userin2Len < CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || + (userin2Len > CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX)) { + rc = BAD_FUNC_ARG; + break; + } + p.create.auth.kdf.key = userin1p; + p.create.auth.kdf.key_len = userin1Len; + p.create.auth.kdf.label = userin2p; + p.create.auth.kdf.label_len = userin2Len; };break; case CCBVAULTIC_AUTH_KIND_SCP03: { - /* - prov.create.auth.scp03.mac - prov.create.auth.scp03.enc - */ + if((userin1p == NULL) || (userin1Len != CCBVAULTIC_AUTH_MAC_LEN) || + (userin2p == NULL) || (userin2Len != CCBVAULTIC_AUTH_ENC_LEN)) { + rc = BAD_FUNC_ARG; + break; + } + p.create.auth.scp03.mac = userin1p; + p.create.auth.scp03.mac_len = userin1Len; + p.create.auth.scp03.enc = userin2p; + p.create.auth.scp03.enc_len = userin2Len; };break; case CCBVAULTIC_AUTH_KIND_PIN: @@ -204,51 +230,42 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_ProvisionAction( } if(rc == 0) { //Set the file data - - XMEMSET(&l, 0, sizeof(l)); - XMEMSET(files, 0, sizeof(files)); - l.file_count = 3; - l.file = files; - - /* Setup file 1 */ - if (in_name1 != NULL) { - l.file[0].name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); - if (l.file[0].name != NULL) { - l.file[0].name_len = XSTRLEN(l.file[0].name); - l.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); + if ((in_name1 != NULL) && (in1 != NULL) && (in1_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); + if (name != NULL) { + p.file[0].name_len = XSTRLEN(name); + p.file[0].name = XMEMCPY(filenames[0], name, p.file[0].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name1, name); (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &jSize); - l.file[0].data_len = jSize; + p.file[0].data_len = jSize; + p.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); } } - - /* Setup file 2 */ - if (in_name2 != NULL) { - l.file[1].name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); - if (l.file[1].name != NULL) { - l.file[1].name_len = XSTRLEN(l.file[1].name); - l.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); + if ((in_name2 != NULL) && (in2 != NULL) && (in2_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); + if (name != NULL) { + p.file[1].name_len = XSTRLEN(name); + p.file[1].name = XMEMCPY(filenames[1], name, p.file[1].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name2, name); (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &jSize); - l.file[1].data_len = jSize; + p.file[1].data_len = jSize; + p.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); } } - - /* Setup file 3 */ - if (in_name3 != NULL) { - l.file[2].name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); - if (l.file[2].name != NULL) { - l.file[2].name_len = XSTRLEN(l.file[2].name); - l.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); + if ((in_name3 != NULL) && (in3 != NULL) && (in3_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); + if (name != NULL) { + p.file[2].name_len = XSTRLEN(name); + p.file[2].name = XMEMCPY(filenames[2], name, p.file[2].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name3, name); (*jenv)->GetLongArrayRegion(jenv, in3_sz, 0, 1, &jSize); - l.file[2].data_len = jSize; + p.file[2].data_len = jSize; + p.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); } } /* Invoke the callback */ - rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_PROVISIONACTION, (void*) &prov, NULL); + rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_PROVISIONACTION, (void*) &p, NULL); } - //Cleanup strings - /* - * - */ return (jint)rc; #endif } @@ -267,46 +284,52 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_LoadAction( (void)in_name3; (void)in3; (void)in3_sz; return (jint)CRYPTOCB_UNAVAILABLE; #else - jlong jSize; int rc = 0; + jlong jSize; + const char* name; ccbVaultIc_Load l; ccbVaultIc_File files[3]; + char filenames[3][CCBVAULTIC_FILE_NAME_LEN_MAX]; XMEMSET(&l, 0, sizeof(l)); XMEMSET(files, 0, sizeof(files)); + XMEMSET(filenames, 0, sizeof(filenames)); + l.file_count = 3; l.file = files; - /* Setup file 1 */ - if(in_name1 != NULL) { - l.file[0].name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); - if (l.file[0].name != NULL) { - l.file[0].name_len = XSTRLEN(l.file[0].name); - l.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); + //Set the file data + if ((in_name1 != NULL) && (in1 != NULL) && (in1_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name1, NULL); + if (name != NULL) { + l.file[0].name_len = XSTRLEN(name); + l.file[0].name = XMEMCPY(filenames[0], name, l.file[0].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name1, name); (*jenv)->GetLongArrayRegion(jenv, in1_sz, 0, 1, &jSize); l.file[0].data_len = jSize; + l.file[0].data = (*jenv)->GetDirectBufferAddress(jenv, in1); } } - - /* Setup file 2 */ - if(in_name2 != NULL) { - l.file[1].name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); - if (l.file[1].name != NULL) { - l.file[1].name_len = XSTRLEN(l.file[1].name); - l.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); + if ((in_name2 != NULL) && (in2 != NULL) && (in2_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name2, NULL); + if (name != NULL) { + l.file[1].name_len = XSTRLEN(name); + l.file[1].name = XMEMCPY(filenames[1], name, l.file[1].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name2, name); (*jenv)->GetLongArrayRegion(jenv, in2_sz, 0, 1, &jSize); l.file[1].data_len = jSize; + l.file[1].data = (*jenv)->GetDirectBufferAddress(jenv, in2); } } - - /* Setup file 3 */ - if(in_name3 != NULL) { - l.file[2].name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); - if (l.file[2].name != NULL) { - l.file[2].name_len = XSTRLEN(l.file[2].name); - l.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); + if ((in_name3 != NULL) && (in3 != NULL) && (in3_sz != NULL)) { + name = (*jenv)->GetStringUTFChars(jenv, in_name3, NULL); + if (name != NULL) { + l.file[2].name_len = XSTRLEN(name); + l.file[2].name = XMEMCPY(filenames[2], name, l.file[2].name_len); + (*jenv)->ReleaseStringUTFChars(jenv, in_name3, name); (*jenv)->GetLongArrayRegion(jenv, in3_sz, 0, 1, &jSize); l.file[2].data_len = jSize; + l.file[2].data = (*jenv)->GetDirectBufferAddress(jenv, in3); } } @@ -314,22 +337,13 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_LoadAction( if(rc == 0) { /* Update the output lengths */ jSize = l.file[0].data_len; - (*jenv)->SetLongArrayRegion(jenv, in1_sz, 0, 1, (jlong*)&jSize); + if(in1_sz != NULL) (*jenv)->SetLongArrayRegion(jenv, in1_sz, 0, 1, (jlong*)&jSize); jSize = l.file[1].data_len; - (*jenv)->SetLongArrayRegion(jenv, in2_sz, 0, 1, (jlong*)&jSize); + if(in2_sz != NULL) (*jenv)->SetLongArrayRegion(jenv, in2_sz, 0, 1, (jlong*)&jSize); jSize = l.file[2].data_len; - (*jenv)->SetLongArrayRegion(jenv, in3_sz, 0, 1, (jlong*)&jSize); + if(in3_sz != NULL) (*jenv)->SetLongArrayRegion(jenv, in3_sz, 0, 1, (jlong*)&jSize); } - if ((in_name1 != NULL) && (l.file[0].name != NULL)) { - (*jenv)->ReleaseStringUTFChars(jenv, in_name1, l.file[0].name); - } - if ((in_name2 != NULL) && (l.file[1].name != NULL)) { - (*jenv)->ReleaseStringUTFChars(jenv, in_name2, l.file[1].name); - } - if ((in_name3 != NULL) && (l.file[2].name != NULL)) { - (*jenv)->ReleaseStringUTFChars(jenv, in_name3, l.file[2].name); - } return rc; #endif } @@ -345,7 +359,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_ccbvaultic_ccbVaultIc_PerformSelfTest( (void)jcl; int rc = 0; - /* Invoke the callback */ rc = wc_CryptoCb_Command((int)devId, CCBVAULTIC_CMD_SELFTEST, NULL, NULL); return (jint)rc; From 3cdf6f5efcab808b1d687840cc1fc6ee5d97ca3b Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 6 Sep 2023 09:06:49 -0400 Subject: [PATCH 07/10] Added missing file. --- .../com/wolfssl/ccbvaultic/ccbVaultIc.java | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java index 1a79bfda3..043fbd4fe 100644 --- a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java +++ b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java @@ -32,8 +32,7 @@ public class ccbVaultIc { public static final int CCBVAULTIC_CMD_INFO = 0x8000; public static final int CCBVAULTIC_CMD_LOADACTION = 0x8001; public static final int CCBVAULTIC_CMD_PROVISIONACTION = 0x8002; - - public static final int CCBVAULTIC_CMD_NVMREAD = 0x8100; + public static final int CCBVAULTIC_CMD_SELFTEST = 0x8003; public static final int CCBVAULTIC_INFO_LEN = 128; public static final int CCBVAULTIC_FAST_START_MS = 700; @@ -68,7 +67,7 @@ public class ccbVaultIc { public static final int CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX = 0x40; public static final int CCBVAULTIC_AUTH_ROLE_MANU = CCBVAULTIC_AUTH_ROLE_MANUFACTURER; - public static final int CCBVAULTIC_AUTH_ROLE_APP = CCBVAULTIC_AUTH_ROLE_APPROVED; + public static final int CCBVAULTIC_AUTH_ROLE_APP = CCBVAULTIC_AUTH_ROLE_UNAPPROVED; public static final int CCBVAULTIC_AUTH_ROLE_DEBUG = CCBVAULTIC_AUTH_ROLE_UNAPPROVED; public static final int CCBVAULTIC_AUTH_ID_MANU = 7; @@ -234,19 +233,39 @@ public int ProvisionAction( int devId, inName2, in2Bytes, in2Len, inName3, in3Bytes, in3Len); } - public int ProvisionAction_KDF(int devId, + + public int ProvisionAction_SCP03(int devId, boolean poweron_selftest, int id, int role, //create user data - byte[] key, byte[] label, + byte[] mac, byte[] enc, String inName1, byte[] in1, String inName2, byte[] in2, String inName3, byte[] in3) { - if((key == null) || (key.length < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || - (key.length > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX)) { + if( (mac == null) || (mac.length != CCBVAULTIC_AUTH_MAC_LEN) || + (enc == null) || (enc.length != CCBVAULTIC_AUTH_ENC_LEN)) { return -1; } - if((label == null) || (label.length < CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || + return ProvisionAction(devId, poweron_selftest, + id, role, + CCBVAULTIC_AUTH_KIND_SCP03, mac, enc, + inName1, in1, + inName2, in2, + inName3, in3); + } + public int ProvisionAction_KDF(int devId, + boolean poweron_selftest, + int id, int role, //create user data + byte[] key, byte[] label, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3) + { + if( (key == null) || + (key.length < CCBVAULTIC_AUTH_KDF_KEY_LEN_MIN) || + (key.length > CCBVAULTIC_AUTH_KDF_KEY_LEN_MAX) || + (label == null) || + (label.length < CCBVAULTIC_AUTH_KDF_LABEL_LEN_MIN) || (label.length > CCBVAULTIC_AUTH_KDF_LABEL_LEN_MAX)) { return -1; } @@ -267,6 +286,17 @@ public int ProvisionAction_App(int devId, boolean poweron_selftest, CCBVAULTIC_AUTH_ID_APP, CCBVAULTIC_AUTH_ROLE_APP, key, label,inName1, in1, inName2, in2, inName3, in3); } + public int ProvisionAction_Debug(int devId, boolean poweron_selftest, + byte[] mac, byte[] enc, + String inName1, byte[] in1, + String inName2, byte[] in2, + String inName3, byte[] in3) + { + return ProvisionAction_SCP03(devId, poweron_selftest, + CCBVAULTIC_AUTH_ID_DEBUG, CCBVAULTIC_AUTH_ROLE_DEBUG, + mac, enc, inName1, in1, inName2, in2, inName3, in3); + } + /* Invoke the load action using the provided devId */ public native int LoadAction(int devId, @@ -395,7 +425,7 @@ public KeyManager[] GenerateKM(byte[] keyPem, byte[] crtPem) public TrustManager[] GenerateTM(byte[] cafile) { - + //TODO Process ca PEM file into a valid trust manager, similar to the KM above return null; } From 516e46b18c1129f28fb9d47565a6dddc2131199a Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 6 Sep 2023 13:02:08 -0400 Subject: [PATCH 08/10] Fix missing comma. --- .../java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java index a37517f5b..640928f02 100644 --- a/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java +++ b/android/wolfssljni-ndk-gradle/app/src/main/java/com/wolfssl/wolfssljni_ndk_gradle/MainActivity.java @@ -165,7 +165,7 @@ private void appendDisplayText(String s) if(useKdfUser) { rc = cv.ProvisionAction_App( devId, Boolean.TRUE, - debugKey, debugLabel + debugKey, debugLabel, filenames[0], debugFile1, filenames[1], debugFile2, null, null); From ce7318a51c36fb6489cb1cd65ca17ad1e248f763 Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Wed, 6 Sep 2023 13:45:01 -0400 Subject: [PATCH 09/10] Correct const pointer warning. --- ccb_vaultic/ccb_vaultic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccb_vaultic/ccb_vaultic.c b/ccb_vaultic/ccb_vaultic.c index 1522d2488..e590b82d5 100644 --- a/ccb_vaultic/ccb_vaultic.c +++ b/ccb_vaultic/ccb_vaultic.c @@ -1015,7 +1015,7 @@ int ccbVaultIc_ProvisionAction( ccbVaultIc_Context *c, int counter = 0; int userId = p->create.id; int adminId = 0; - ccbVaultIc_Config *config = c->config; + const ccbVaultIc_Config *config = c->config; if(config == NULL) { ccbVaultIc_GetDefaultConfig(&config); } From 1e955c94ca1de4ff67c252b07e8abb4e8879296f Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Tue, 24 Oct 2023 11:10:59 -0400 Subject: [PATCH 10/10] Minor updates to improve compatibility with servers and certs. --- android/wolfssljni-ndk-gradle/app/CMakeLists.txt | 6 +++++- .../java/com/wolfssl/ccbvaultic/ccbVaultIc.java | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt index 95bb55cdc..5f80a4338 100644 --- a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt +++ b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt @@ -59,10 +59,14 @@ if ("${WOLFSSL_PKG_TYPE}" MATCHES "normal") -DWOLFSSL_AKID_NAME -DHAVE_CTS -DNO_DES3 -DGCM_TABLE_4BIT -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DHAVE_AESGCM -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 + + -DHAVE_SECURE_RENEGOTIATION + #-DHAVE_SERVER_RENEGOTIATION_INFO + -DWOLFSSL_ALT_CERT_CHAINS # Defines added for debugging. These can be removed if debug logging is not needed # and will increase performance and reduce library footprint size if removed. - -DEBUG_WOLFSSL + -DEBUG_WOLFSSL -DWOLFSSL_ANDROID_DEBUG # Defines added for wolfCrypt test and benchmark only, may not be needed for your # own application. diff --git a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java index 043fbd4fe..5bf9e432c 100644 --- a/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java +++ b/ccb_vaultic/java/com/wolfssl/ccbvaultic/ccbVaultIc.java @@ -351,7 +351,20 @@ private byte[] StripPemHeaders(byte[] data) boolean inHead = false; boolean inDesc = false; boolean inFoot = false; - for (byte datum : data) { + + int dataoffset = 0; + // Search for "-----" and drop all data before then + for(dataoffset = 0; dataoffset < (data.length - 5); dataoffset ++) { + if( (data[dataoffset] == '-') && + (data[dataoffset + 1] == '-') && + (data[dataoffset + 2] == '-') && + (data[dataoffset + 3] == '-') && + (data[dataoffset + 4] == '-')) + break; + } + //Continue on removing comments + for (; dataoffset < data.length; dataoffset ++) { + byte datum = data[dataoffset]; if (datum == '-') { if (!inHead) { inHead = true;