diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 32b991ecdb..53f2b519d7 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5313,11 +5313,16 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) } #endif #if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) - ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir); - if (ret == 0) { + if (keylen == TA_KEY_TYPE_AES128_SIZE) { + ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir); + if (ret != 0) { + return ret; + } ret = wc_AesSetIV(aes, iv); + if (ret != 0) { + return ret; + } } - return ret; #endif XMEMCPY(aes->key, userKey, keylen); @@ -10150,11 +10155,20 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, authIn, authInSz); #endif #if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) - return wc_Microchip_AesGcmEncrypt( - aes, out, in, sz, - iv, ivSz, - authTag, authTagSz, - authIn, authInSz); +#ifndef TA_AES_GCM_MAX_DATA_SIZE + #define TA_AES_GCM_MAX_DATA_SIZE 996u +#endif + if (aes != NULL && + aes->keylen == TA_KEY_TYPE_AES128_SIZE && + ivSz == TA_AES_GCM_IV_LENGTH && + authTagSz == TA_AES_GCM_TAG_LENGTH && + (authInSz + sz) <= TA_AES_GCM_MAX_DATA_SIZE) { + return wc_Microchip_AesGcmEncrypt( + aes, out, in, sz, + iv, ivSz, + authTag, authTagSz, + authIn, authInSz); + } #endif #ifdef STM32_CRYPTO_AES_GCM return wc_AesGcmEncrypt_STM32( @@ -10885,9 +10899,18 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, #endif #if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM) - return wc_Microchip_AesGcmDecrypt( - aes, out, in, sz, iv, ivSz, - authTag, authTagSz, authIn, authInSz); +#ifndef TA_AES_GCM_MAX_DATA_SIZE + #define TA_AES_GCM_MAX_DATA_SIZE 996u +#endif + if (aes != NULL && + aes->keylen == TA_KEY_TYPE_AES128_SIZE && + ivSz == TA_AES_GCM_IV_LENGTH && + authTagSz == TA_AES_GCM_TAG_LENGTH && + (authInSz + sz) <= TA_AES_GCM_MAX_DATA_SIZE) { + return wc_Microchip_AesGcmDecrypt( + aes, out, in, sz, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + } #endif #ifdef STM32_CRYPTO_AES_GCM diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 97b064cd25..6c6f72401a 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4748,7 +4748,8 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ defined(WOLFSSL_MICROCHIP_TA100) /* For SECP256R1 use hardware */ - if (private_key->dp->id == ECC_SECP256R1) { + if (private_key->dp->id == ECC_SECP256R1 && + private_key->slot != ATECC_INVALID_SLOT) { err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out); *outlen = private_key->dp->size; } @@ -5659,6 +5660,173 @@ int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng) return err; } +static int wc_ecc_make_key_sw(WC_RNG* rng, ecc_key* key) +{ + int err = MP_OKAY; + DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); +#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \ + defined(WC_ECC_NONBLOCK_ONLY) + ecc_nb_ctx_t nb_ctx; + XMEMSET(&nb_ctx, 0, sizeof(nb_ctx)); +#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */ + + if (key == NULL || rng == NULL) { + return BAD_FUNC_ARG; + } + +/* Prefer SP ECC when available. */ +#ifdef WOLFSSL_HAVE_SP_ECC +#ifndef WOLFSSL_SP_NO_256 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { + #ifndef WC_ECC_NONBLOCK + err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap); + #else + if (key->nb_ctx) { + err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } + else { + #ifdef WC_ECC_NONBLOCK_ONLY + do { /* perform blocking call to non-blocking function */ + err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } while (err == FP_WOULDBLOCK); + #else + err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap); + #endif /* WC_ECC_NONBLOCK_ONLY */ + } + #endif /* !WC_ECC_NONBLOCK */ + + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + return err; + } + } +#endif /* !WOLFSSL_SP_NO_256 */ +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2) + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) { + err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap); + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + return err; + } + } +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + #ifndef WC_ECC_NONBLOCK + err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap); + #else + if (key->nb_ctx) { + err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } + else { + #ifdef WC_ECC_NONBLOCK_ONLY + do { /* perform blocking call to non-blocking function */ + err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } while (err == FP_WOULDBLOCK); + #else + err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap); + #endif /* WC_ECC_NONBLOCK_ONLY */ + } + #endif /* !WC_ECC_NONBLOCK */ + + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + return err; + } + } +#endif /* WOLFSSL_SP_384 */ +#ifdef WOLFSSL_SP_521 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) { + #ifndef WC_ECC_NONBLOCK + err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap); + #else + if (key->nb_ctx) { + err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } + else { + #ifdef WC_ECC_NONBLOCK_ONLY + do { /* perform blocking call to non-blocking function */ + err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k, + &key->pubkey, key->heap); + } while (err == FP_WOULDBLOCK); + #else + err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap); + #endif /* WC_ECC_NONBLOCK_ONLY */ + } + #endif /* !WC_ECC_NONBLOCK */ + + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + return err; + } + } +#endif /* WOLFSSL_SP_521 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ + + /* setup the key variables */ +#ifndef ALT_ECC_SIZE + err = mp_init(key->k); +#else + err = 0; + key->k = (mp_int*)key->ka; + alt_fp_init(key->k); +#endif + + /* load curve info */ + if (err == MP_OKAY) { + ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err); + if (err != MP_OKAY) { + WOLFSSL_MSG("ALLOC_CURVE_SPECS failed"); + } + } + + if (err == MP_OKAY) { + err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); + if (err != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_curve_load failed"); + } + } + + /* generate k */ + if (err == MP_OKAY) { + err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order); + if (err != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_gen_k failed"); + } + } + + /* generate public key from k */ + if (err == MP_OKAY) { + err = ecc_make_pub_ex(key, curve, NULL, rng); + if (err != MP_OKAY) { + WOLFSSL_MSG("ecc_make_pub_ex failed"); + } + } + + if (err == MP_OKAY + #ifdef WOLFSSL_ASYNC_CRYPT + || err == WC_NO_ERR_TRACE(WC_PENDING_E) + #endif + ) { + key->type = ECC_PRIVATEKEY; + } + else { + /* cleanup these on failure case only */ + mp_forcezero(key->k); + } + + /* cleanup allocations */ + wc_ecc_curve_free(curve); + FREE_CURVE_SPECS(); + + return err; +} + static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, int flags) @@ -5784,6 +5952,18 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, else { err = NOT_COMPILED_IN; } +#if defined(WOLFSSL_MICROCHIP_TA100) + if (key->dp->id != ECC_SECP256R1) { + /* Avoid TA100 access for unsupported curves. */ + key->slot = ATECC_INVALID_SLOT; + err = wc_ecc_make_key_sw(rng, key); + } + if (err == NOT_COMPILED_IN) { /* software key gen fallback */ + /* Ensure slot is not used for software curves. */ + key->slot = ATECC_INVALID_SLOT; + err = wc_ecc_make_key_sw(rng, key); + } +#endif /* WOLFSSL_MICROCHIP_TA100 */ #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) err = se050_ecc_create_key(key, key->dp->id, key->dp->size); key->type = ECC_PRIVATEKEY; @@ -5997,68 +6177,8 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif /* WOLFSSL_SP_521 */ #endif /* WOLFSSL_HAVE_SP_ECC */ - { /* software key gen */ -#if defined(WOLFSSL_SP_MATH) - err = WC_KEY_SIZE_E; -#else - DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); - - /* setup the key variables */ -#ifndef ALT_ECC_SIZE - err = mp_init(key->k); -#else - err = 0; - key->k = (mp_int*)key->ka; - alt_fp_init(key->k); -#endif - - /* load curve info */ - if (err == MP_OKAY) { - ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err); - if (err != MP_OKAY) { - WOLFSSL_MSG("ALLOC_CURVE_SPECS failed"); - } - } - - if (err == MP_OKAY) { - err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); - if (err != MP_OKAY) { - WOLFSSL_MSG("wc_ecc_curve_load failed"); - } - } - - /* generate k */ - if (err == MP_OKAY) { - err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order); - if (err != MP_OKAY) { - WOLFSSL_MSG("wc_ecc_gen_k failed"); - } - } - - /* generate public key from k */ - if (err == MP_OKAY) { - err = ecc_make_pub_ex(key, curve, NULL, rng); - if (err != MP_OKAY) { - WOLFSSL_MSG("ecc_make_pub_ex failed"); - } - } - - if (err == MP_OKAY - #ifdef WOLFSSL_ASYNC_CRYPT - || err == WC_NO_ERR_TRACE(WC_PENDING_E) - #endif - ) { - key->type = ECC_PRIVATEKEY; - } - else { - /* cleanup these on failure case only */ - mp_forcezero(key->k); - } - - /* cleanup allocations */ - wc_ecc_curve_free(curve); - FREE_CURVE_SPECS(); -#endif /* WOLFSSL_SP_MATH */ + { /* software key gen */ + err = wc_ecc_make_key_sw(rng, key); } #ifdef HAVE_WOLF_BIGINT @@ -6259,6 +6379,14 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ defined(WOLFSSL_MICROCHIP_TA100) key->slot = ATECC_INVALID_SLOT; + /* TA100 needs pubkey initialized to populate after genkey */ +#ifdef WOLFSSL_MICROCHIP_TA100 + ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, + NULL, NULL, NULL); + if (ret != MP_OKAY) { + return MEMORY_E; + } +#endif #else #if defined(WOLFSSL_KCAPI_ECC) key->handle = NULL; @@ -6498,8 +6626,27 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, } #endif - #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_MICROCHIP_TA100) + #if defined(WOLFSSL_MICROCHIP_TA100) + if (key->dp->id == ECC_SECP256R1 && + key->slot != ATECC_INVALID_SLOT) { + (void)inlen; + /* Sign: Result is 32-bytes of R then 32-bytes of S */ + err = atmel_ecc_sign(key->slot, in, out); + if (err != 0) { + return err; + } + err = mp_read_unsigned_bin(r, out, keysize); + if (err != MP_OKAY) { + return err; + } + err = mp_read_unsigned_bin(s, out + keysize, keysize); + if (err != MP_OKAY) { + return err; + } + return 0; + } + #endif + #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) (void)inlen; /* Sign: Result is 32-bytes of R then 32-bytes of S */ err = atmel_ecc_sign(key->slot, in, out); @@ -6507,6 +6654,14 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, if (err != 0) { return err; } + err = mp_read_unsigned_bin(r, out, keysize); + if (err != MP_OKAY) { + return err; + } + err = mp_read_unsigned_bin(s, out + keysize, keysize); + if (err != MP_OKAY) { + return err; + } #elif defined(PLUTON_CRYPTO_ECC) { /* if the input is larger than curve order, we must truncate */ @@ -6857,7 +7012,16 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \ defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \ defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL) + #if defined(WOLFSSL_MICROCHIP_TA100) + if (key->dp != NULL && key->dp->id != ECC_SECP256R1) { + err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); + } + else { + err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key); + } + #else err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key); + #endif #else err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); #endif @@ -6975,7 +7139,6 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s); } #elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_MICROCHIP_TA100) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) #ifndef WOLFSSL_SP_MATH static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, @@ -8818,7 +8981,7 @@ static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s) } #endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */ -#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP) +#if defined(HAVE_ECC_VERIFY_HELPER) || defined(WOLFSSL_MICROCHIP_TA100) static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key) { @@ -8976,7 +9139,8 @@ static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash, return NOT_COMPILED_IN; } -#if !defined(WOLFSSL_MICROCHIP) && (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)) +#if (!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)) && \ + (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)) static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve) { @@ -9400,8 +9564,26 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } #endif /* WOLFSSL_SE050 */ -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_MICROCHIP_TA100) +#if defined(WOLFSSL_MICROCHIP_TA100) + /* TA100 verify is handled in this function (not *_hw) to keep verify + * on the software/SP path for unsupported curves. */ + if (key->dp->id != ECC_SECP256R1) { + err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key); + return err; + } +#endif + +#if defined(WOLFSSL_MICROCHIP_TA100) + if (key->dp->id == ECC_SECP256R1) { + err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); + if (err != 0) { + return err; + } + (void)hashlen; + return 0; + } +#endif +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); if (err != 0) { return err; diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c index f4668dcf1c..b6de7b32a8 100644 --- a/wolfcrypt/src/port/atmel/atmel.c +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -211,6 +211,10 @@ static ATCAIfaceCfg* gCfg = &config_atmel_device[WOLFSSL_ATCA_DEVICE_NO]; #define SHARED_DATA_ADDR 0x8006 #endif #define MAP_TO_HANDLE(value) (SHARED_DATA_ADDR + (value)) + /* TA100 uses separate handle range for symmetric keys (AES/HMAC) */ + #ifndef TA100_AES_HANDLE + #define TA100_AES_HANDLE 0x8106 + #endif #else #define MAP_TO_HANDLE(value) value #endif @@ -570,9 +574,15 @@ static int atmel_init_enc_key(void) int atmel_get_rev_info(word32* revision) { int ret; - printf("Waking device...\n"); +#ifdef WOLFSSL_ATECC_DEBUG + WOLFSSL_MSG("Waking device..."); +#endif ret = atcab_wakeup(); - printf("atcab_wakeup: %d\n", ret); +#ifdef WOLFSSL_ATECC_DEBUG + if (ret != 0) { + WOLFSSL_MSG("atcab_wakeup failed"); + } +#endif ret = atcab_info((uint8_t*)revision); ret = atmel_ecc_translate_err(ret); return ret; @@ -981,7 +991,8 @@ static int atmel_createHandles(void) int i; #ifdef WOLFSSL_ATECC_DEBUG atmel_Handle_Attributes(); - printf("atmel_Handle_Attributes() finished \n\n"); + WOLFSSL_MSG("atmel_Handle_Attributes() finished"); + WOLFSSL_MSG("createHandles starting"); #endif for (i = 0; i < ATECC_MAX_SLOT; i++ ) { @@ -1008,6 +1019,9 @@ static int atmel_createHandles(void) CHECK_STATUS(status); shared_handle += 1; } +#ifdef WOLFSSL_ATECC_DEBUG + WOLFSSL_MSG("createHandles done"); +#endif return 0; } #endif /* WOLFSSL_MICROCHIP_TA100 */ @@ -1638,11 +1652,44 @@ int atcatls_set_callback_ctx(WOLFSSL* ssl, void* user_ctx) #if defined(WOLFSSL_MICROCHIP_TA100) && !defined(NO_AES) && \ defined(HAVE_AESGCM) && defined(WOLFSSL_MICROCHIP_AESGCM) + +/* AES key element attributes for TA100: class=0x62, prop=0x0600, perm=0x55 */ +static int ta100_aes_handle_created = 0; +static uint16_t ta100_aes_handle = TA100_AES_HANDLE; + +/* Optional runtime override for AES handle. */ +int wc_Microchip_SetAesGcmHandle(uint16_t handle) +{ + ta100_aes_handle = handle; + ta100_aes_handle_created = 0; + return 0; +} + +static int ta100_is_aes_handle(uint16_t handle) +{ + uint8_t info[TA_HANDLE_INFO_SIZE] = { 0 }; + ATCA_STATUS status; + uint8_t handle_class; + uint8_t key_type; + + status = talib_info_get_handle_info(atcab_get_device(), handle, info); + if (status != ATCA_SUCCESS) { + return 0; + } + + handle_class = info[0] & TA_HANDLE_INFO_CLASS_MASK; + key_type = (info[0] & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT; + + return (handle_class == TA_CLASS_SYMMETRIC_KEY && key_type == TA_KEY_TYPE_AES128); +} + int wc_Microchip_aes_set_key(Aes* aes, const byte* key, word32 keylen, const byte* iv, int dir) { ATCA_STATUS status; bool is_locked = false; + uint8_t is_handle_valid = 0; + ta_element_attributes_t attr; (void)dir; (void)iv; @@ -1650,28 +1697,57 @@ int wc_Microchip_aes_set_key(Aes* aes, const byte* key, word32 keylen, if (aes == NULL) { return BAD_FUNC_ARG; } - aes->key_id = atmel_ecc_alloc(ATMEL_SLOT_ENCKEY); - - if (aes->key_id == ATECC_INVALID_SLOT) { - return WC_HW_WAIT_E; - } + /* TA100 uses dedicated symmetric key handle, not ECC slot mapping */ + aes->key_id = ta100_aes_handle; aes->keylen = keylen; aes->rounds = keylen/4 + 6; XMEMCPY(aes->key, key, keylen); - status = talib_write_element(atcab_get_device(), MAP_TO_HANDLE(aes->key_id), + /* Create AES handle if not already created */ + if (!ta100_aes_handle_created) { + status = talib_is_handle_valid(atcab_get_device(), (uint32_t)aes->key_id, + &is_handle_valid); + if (status != ATCA_SUCCESS) { + return WC_HW_E; + } + + if (is_handle_valid == 0) { + status = talib_handle_init_symmetric_key(&attr, TA_KEY_TYPE_AES128, + TA_PROP_SYMM_KEY_USAGE_ANY); + if (status != ATCA_SUCCESS) { + return WC_HW_E; + } + (void)talib_handle_set_permissions(&attr, TA_PERM_ALWAYS, TA_PERM_ALWAYS, + TA_PERM_ALWAYS, TA_PERM_ALWAYS); + ta100_fix_property_endian(&attr); + + status = talib_create_element_with_handle(atcab_get_device(), + aes->key_id, &attr); + /* Ignore "already exists" error (0xA3), fail on other errors */ + if (!(status == ATCA_SUCCESS || status == 0xA3)) { + return WC_HW_E; + } + } else if (!ta100_is_aes_handle(aes->key_id)) { + return WC_HW_E; + } + + ta100_aes_handle_created = 1; + } + + status = talib_is_handle_locked(atcab_get_device(), aes->key_id, &is_locked); + if (status == ATCA_SUCCESS && is_locked) { + return WC_HW_E; + } + + /* Write AES key to the symmetric key handle */ + status = talib_write_element(atcab_get_device(), aes->key_id, TA_KEY_TYPE_AES128_SIZE, (const uint8_t*)key); - - /*status = talib_write_bytes_zone(atcab_get_device(), (uint8_t)ATCA_ZONE_DATA, - MAP_TO_HANDLE(aes->key_id), 0, (const uint8_t*)key, - (const size_t)keylen); - */ CHECK_STATUS(status); - status = talib_aes_gcm_keyload(atcab_get_device(), aes->key_id, keylen); + /* key_block=0 for AES-128 (single 16-byte block) */ + status = talib_aes_gcm_keyload(atcab_get_device(), aes->key_id, 0); CHECK_STATUS(status); - (void)is_locked; /* Test if data zone is locked */ status = talib_is_setup_locked(atcab_get_device(), &is_locked); @@ -1694,10 +1770,10 @@ static int wc_Microchip_AesGcmCommon(Aes* aes, byte* out, const byte* in, const byte* authIn, word32 authInSz, int dir) { ATCA_STATUS status; + byte tag_buf[TA_AES_GCM_TAG_LENGTH]; + word32 copy_sz; (void)aes; - (void)ivSz; - (void)authTagSz; if (aes == NULL) { return BAD_FUNC_ARG; @@ -1705,18 +1781,52 @@ static int wc_Microchip_AesGcmCommon(Aes* aes, byte* out, const byte* in, if (dir != AES_ENCRYPTION && dir != AES_DECRYPTION) { return BAD_FUNC_ARG; } + if (ivSz != TA_AES_GCM_IV_LENGTH) { + return BAD_FUNC_ARG; + } + if (authTag == NULL || authTagSz == 0 || authTagSz > TA_AES_GCM_TAG_LENGTH) { + return BAD_FUNC_ARG; + } if (dir == AES_ENCRYPTION) { /* Note: talib API takes non-const iv */ - status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, - authInSz, (uint8_t*)iv, in, sz, out, authTag); + if (authTagSz != TA_AES_GCM_TAG_LENGTH) { + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, tag_buf); + if (status == ATCA_SUCCESS) { + copy_sz = authTagSz; + XMEMCPY(authTag, tag_buf, copy_sz); + } + } + else { + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, authTag); + } } else { - status = talib_aes_gcm_decrypt(atcab_get_device(), authIn, - authInSz, (uint8_t*)iv, authTag, in, sz, out); + if (authTagSz != TA_AES_GCM_TAG_LENGTH) { + if (sz != 0) { + return NOT_COMPILED_IN; + } + status = talib_aes_gcm_encrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, in, sz, out, tag_buf); + if (status == ATCA_SUCCESS) { + copy_sz = authTagSz; + if (XMEMCMP(tag_buf, authTag, copy_sz) != 0) { + return AES_GCM_AUTH_E; + } + } + } + else { + status = talib_aes_gcm_decrypt(atcab_get_device(), authIn, + authInSz, (uint8_t*)iv, authTag, in, sz, out); + } } if (status != ATCA_SUCCESS) { + if (status == TA_CALCULATION && dir == AES_DECRYPTION) { + return AES_GCM_AUTH_E; + } return atmel_ecc_translate_err(status); } diff --git a/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl/wolfcrypt/port/atmel/atmel.h index 14f3461b84..aa06560e8a 100644 --- a/wolfssl/wolfcrypt/port/atmel/atmel.h +++ b/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -146,6 +146,7 @@ int atmel_ecc_verify(const byte* message, const byte* signature, defined(WOLFSSL_MICROCHIP_AESGCM) #include +WOLFSSL_API int wc_Microchip_SetAesGcmHandle(uint16_t handle); WOLFSSL_LOCAL int wc_Microchip_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz,