/* * Copyright 2018-2020 NXP * SPDX-License-Identifier: Apache-2.0 */ #include #if SSS_HAVE_A71CL || SSS_HAVE_SE050_L #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include "HostCryptoAPI.h" #include "ax_api.h" #include "nxLog_sss.h" /* ************************************************************************** */ /* Includes */ /* ************************************************************************** */ /* ************************************************************************** */ /* Local Defines */ /* ************************************************************************** */ /* Key store N Count */ #define CONVERT_BYTE(x) (x) / 8 #define CONVERT_BIT(x) (x) * 8 #define MAX_RSA_COMPONENT_SIZE (256 + 4 + 256) // rsaModulus + public_exponent + private_exponent #define MAX_KEY_HEADER_SIZE (12 + 1 + 1 + 1) //Key header contains 12 bytes cl_id + id_len + keytype + keyid #define MAX_KEY_ELEMENT_SIZE (3 + 6) // (key_tag + key_len) * 3 components #define MAX_TLV_BUF_SIZE (MAX_RSA_COMPONENT_SIZE + MAX_KEY_HEADER_SIZE + MAX_KEY_ELEMENT_SIZE) /* ************************************************************************** */ /* Structures and Typedefs */ /* ************************************************************************** */ /* ************************************************************************** */ /* Global Variables */ /* ************************************************************************** */ static bool gapplet_mode_default = TRUE; SE_Connect_Ctx_t pA71Auth_init = {0}; /* clang-format off */ static U8 KEK[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; U8 *grsaPubKey = NULL; U16 grsaPubKeyLen = 0; /* clang-format on */ keyStoreTable_t gkeystore_shadow_cl; keyIdAndTypeIndexLookup_t gLookupEntires_cl[KS_N_ENTIRES_CL]; /* ************************************************************************** */ /* Static function declarations */ /* ************************************************************************** */ static HLSE_RET_CODE a71cl_GenerateKey( keyStoreTable_t *keystore_shadow, uint8_t keyType, uint8_t cipherType, uint32_t KeyID, uint16_t keylen); static sss_status_t swToSSSResult(uint16_t checkSW); static HLSE_RET_CODE a71cl_AllocateKeyStore(sss_a71cl_key_store_t *keyStore, uint32_t keyStoreID); static HLSE_RET_CODE a71cl_loadKeyStore(sss_a71cl_key_store_t *keyStore); static HLSE_RET_CODE a71cl_saveKeyStore(sss_a71cl_key_store_t *keyStore); static HLSE_RET_CODE a71cl_AllocateKeyObject(sss_a71cl_key_store_t *keyStore, uint32_t extKeyID, sss_key_part_t keyPart, sss_cipher_type_t cipherType, size_t keyByteLenMax, uint32_t options); static U16 a71cl_setKey(keyStoreTable_t *keystore_shadow, sss_key_part_t key_part, sss_cipher_type_t cipher_type, uint32_t extId, uint8_t *key, size_t keyLen); static U16 a71cl_rsaSign(keyStoreTable_t *keystore_shadow, uint8_t extKeyID, uint8_t *pHash, uint16_t hashLen, uint8_t *pSignature, uint16_t *pSignatureLen); static U16 a71cl_rsaVerify(keyStoreTable_t *keystore_shadow, uint8_t extKeyID, uint8_t *pHash, uint16_t hashLen, uint8_t *pSignature, uint16_t SignatureLen); /* ************************************************************************** */ /* Public Functions */ /* ************************************************************************** */ static U16 a71cl_Scp02Authenticate() { U16 err = SW_OK; #ifdef USE_SCP02 /* clang-format off */ U8 keyEnc[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F }; U8 keyMac[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F }; U8 keyDek[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F }; /* clang-format on */ U8 sCounter[3]; U16 sCounterLen = sizeof(sCounter); #endif if (CL_IsAppletInAuthenticationMode()) { gapplet_mode_default = FALSE; } else { gapplet_mode_default = TRUE; #ifdef USE_SCP02 err = SCP02_Authenticate(keyEnc, keyMac, keyDek, SCP_KEY_SIZE, sCounter, &sCounterLen); #endif } return err; } static U16 a71cl_GetCryptType(sss_algorithm_t algo, sss_mode_t mode) { U16 cryptType = (U16)(-1); switch (algo) { case kAlgorithm_SSS_AES_ECB: if (mode == kMode_SSS_Encrypt || mode == kMode_SSS_Decrypt) cryptType = eAES_ECB_NOPADDING; else if (mode == kMode_SSS_Sign || mode == kMode_SSS_Verify) { LOG_E("AES_ECB is not supported for sign and verify"); cryptType = (U16)(-1); } break; case kAlgorithm_SSS_AES_CBC: if (mode == kMode_SSS_Encrypt || mode == kMode_SSS_Decrypt) cryptType = eAES_CBC_NOPADDING; else if (mode == kMode_SSS_Sign || mode == kMode_SSS_Verify) cryptType = eAES_CBC_ISO9797_M1; break; case kAlgorithm_SSS_DES3_ECB: if (mode == kMode_SSS_Encrypt || mode == kMode_SSS_Decrypt) cryptType = eDES_ECB_NOPADDING; else if (mode == kMode_SSS_Sign || mode == kMode_SSS_Verify) { LOG_E("DES_ECB is not supported for sign and verify"); cryptType = (U16)(-1); } break; case kAlgorithm_SSS_DES3_CBC: if (mode == kMode_SSS_Encrypt || mode == kMode_SSS_Decrypt) cryptType = eDES_CBC_NOPADDING; else if (mode == kMode_SSS_Sign || mode == kMode_SSS_Verify) cryptType = eDES_CBC_ISO9797_M1; break; default: LOG_E("Algorithem is not supported by A71CL"); cryptType = (U16)(-1); } return cryptType; } static U16 a71cl_Get_key(sss_cipher_type_t cipherType, U8 *key, size_t KeyByteLen) { U16 err = ERR_API_ERROR; if (cipherType == kSSS_CipherType_RSA) { if (grsaPubKey) { memcpy(key, grsaPubKey + 2, grsaPubKeyLen); KeyByteLen = CONVERT_BIT(grsaPubKeyLen); err = SW_OK; } else { LOG_E("RSA Key Pair not generated"); } } else LOG_E("Can not get other than RSA Public key."); return err; } static U16 a71cl_symmCrypt( U8 *indata, U16 indataLen, sss_mode_t mode, sss_algorithm_t alg, U8 *iv, U16 ivLen, U8 *outData, size_t *outDataLen) { eCLSymCryptMode CryptMode; eCLSymCryptType CryptType = (eCLSymCryptType)a71cl_GetCryptType(alg, mode); if (CryptType == (CryptType)-1) return ERR_API_ERROR; U16 blockSize = (alg == kAlgorithm_SSS_DES3_CBC || alg == kAlgorithm_SSS_DES3_ECB) ? 8 : 16; U8 *input = NULL; U16 inputLen = indataLen; U16 outLen = 256; U16 err; U16 offset = 0; switch (mode) { case kMode_SSS_Encrypt: CryptMode = eEncrypt; inputLen = indataLen + blockSize - (indataLen % blockSize); break; case kMode_SSS_Decrypt: CryptMode = eDecrypt; break; default: return ERR_API_ERROR; ; } if (alg == kAlgorithm_SSS_DES3_CBC || alg == kAlgorithm_SSS_AES_CBC) { inputLen += ivLen; input = SSS_MALLOC(inputLen); memset(input, 0, inputLen); memcpy(input, iv, ivLen); offset = ivLen; } else { input = SSS_MALLOC(inputLen); memset(input, 0, inputLen); } memcpy(input + offset, indata, indataLen); err = CL_SymmetricCrypt(input, inputLen, CryptMode, CryptType, 0, outData, &outLen); *outDataLen = outLen; SSS_FREE(input); return err; } static U16 a71cl_rsaSign(keyStoreTable_t *keystore_shadow, uint8_t extKeyID, uint8_t *pHash, uint16_t hashLen, uint8_t *pSignature, uint16_t *pSignatureLen) { U16 ret = SW_OK; eCLAsymCryptMode mode = eAsymSign; eCLAsymCryptType type = eRSA_SHA256_PKCS1; ret = CL_AsymmetricCrypt(pHash, hashLen, mode, type, 0, pSignature, pSignatureLen); return ret; } static U16 a71cl_rsaVerify(keyStoreTable_t *keystore_shadow, uint8_t extKeyID, uint8_t *digest, uint16_t digestlen, uint8_t *pSignature, uint16_t SignatureLen) { U16 ret = SW_OK; U8 allData[512]; U16 retDatalen = sizeof(allData); eCLAsymCryptMode mode = eAsymVerifySign; eCLAsymCryptType type = eRSA_SHA256_PKCS1; ret = CL_AsymmetricCrypt(pSignature, SignatureLen, mode, type, 0, allData, &retDatalen); return ret; } static U16 a71cl_rsaEncrypt(keyStoreTable_t *keystore_shadow, uint8_t KeyID, uint8_t *inputData, uint16_t inputDataLen, uint8_t *encryptedData, uint16_t *encryptedDataLen) { U16 ret = SW_OK; eCLAsymCryptMode mode = eAsymEncrypt; eCLAsymCryptType type = eRSA_SHA1_PKCS1; ret = CL_AsymmetricCrypt(inputData, inputDataLen, mode, type, 0, encryptedData, encryptedDataLen); return ret; } static U16 a71cl_rsaDecrypt(keyStoreTable_t *keystore_shadow, uint8_t KeyID, uint8_t *encryptedData, uint16_t encryptedDataLen, uint8_t *rawData, uint16_t rawDataLen) { U16 ret = SW_OK; eCLAsymCryptMode mode = eAsymDecrypt; eCLAsymCryptType type = eRSA_SHA1_PKCS1; ret = CL_AsymmetricCrypt(encryptedData, encryptedDataLen, mode, type, 0, rawData, &rawDataLen); return ret; } sss_status_t sscp_a71cl_openSession(const void *connectionData) { HLSE_CONNECTION_PARAMS params = {0}; HLSE_COMMUNICATION_STATE commState = {0}; HLSE_RET_CODE ret_code; uint32_t ret = kStatus_SSS_Fail; SE_Connect_Ctx_t *pEncrCtxt = (SE_Connect_Ctx_t *)connectionData; commState.atrLen = MAX_APDU_BUF_LENGTH; if (pEncrCtxt == NULL) { LOG_I("pEncrCtxt is NULL"); pEncrCtxt = &pA71Auth_init; // initialize pA71Auth parameters } else { params.pParameter = (void *)pEncrCtxt->portName; params.connType = pEncrCtxt->connType; } if (pEncrCtxt == NULL || pEncrCtxt->portName == NULL) params.ulParameterLen = 0; else params.ulParameterLen = (U16)strlen(pEncrCtxt->portName); ret_code = HLSE_Connect(¶ms, &commState); if (ret_code == HLSE_SW_OK) ret = kStatus_SSS_Success; return (sss_status_t)ret; } void sscp_a71cl_closeSession(void) { HLSE_CloseConnection(HLSE_CLOSE_CONNECTION_NO_RESET); } sss_status_t sscp_a71cl_init(sscp_a71cl_context_t *context, sss_a71cl_key_store_t *keyStore) { sss_status_t status = kStatus_SSS_Fail; U16 err; if (context == NULL) { goto cleanup; } /* assign a71cl implementation of ::sscp_invoke_command() */ context->keyStore = keyStore; context->invoke = &sscp_a71cl_invoke_command; keyStore->session->sscp_context = (sscp_context_t *)context; err = a71cl_Scp02Authenticate(); if (err == SW_OK) status = kStatus_SSS_Success; cleanup: return status; } void sscp_a71cl_free(sscp_a71cl_context_t *context) { if (context != NULL) { memset(context, 0, sizeof(*context)); } if (grsaPubKey) { SSS_FREE(grsaPubKey); grsaPubKey = NULL; } } void getA7CLKeyStore(sss_a71cl_key_store_t **ks, sscp_context_reference_t *ref) { switch (ref->type) { case kSSCP_ParamContextType_SSS_Symmetric: { sss_sscp_symmetric_t *ctx = (sss_sscp_symmetric_t *)ref->ptr; *ks = (sss_a71cl_key_store_t *)ctx->keyObject->keyStore; } break; case kSSCP_ParamContextType_SSS_Asymmetric: { sss_asymmetric_t *ctx = (sss_asymmetric_t *)ref->ptr; *ks = (sss_a71cl_key_store_t *)ctx->keyObject->keyStore; break; } case kSSCP_ParamContextType_SSS_Object: { sss_object_t *pobj = (sss_object_t *)ref->ptr; *ks = (sss_a71cl_key_store_t *)pobj->keyStore; break; } case kSSCP_ParamContextType_SSS_KeyStore: { *ks = (sss_a71cl_key_store_t *)ref->ptr; break; } default: break; } } sscp_status_t sscp_a71cl_invoke_command( sscp_context_t *a71clContext, uint32_t commandID, sscp_operation_t *op, uint32_t *returnOrigin) { uint16_t resSW = SMCOM_SND_FAILED; sscp_status_t retSSCP = kStatus_SSCP_Success; uint8_t keyId; sss_a71cl_key_store_t *a71cl_keystore = NULL; sscp_a71cl_context_t *context = (sscp_a71cl_context_t *)a71clContext; if (kSSCP_ParamType_ContextReference == SSCP_OP_GET_PARAM(0, op->paramTypes)) { getA7CLKeyStore(&a71cl_keystore, &op->params[0].context); } switch (commandID) { case kSSCP_CMD_GENERATE_KEY: resSW = a71cl_GenerateKey(a71cl_keystore->keystore_shadow, op->params[1].value.a, op->params[2].value.b, op->params[1].value.b, op->params[2].value.a); break; case kSSCP_CMD_GET_KEY: { resSW = a71cl_Get_key(op->params[3].value.b, op->params[2].memref.buffer, (op->params[3].value.a)); } break; case kSSCP_CMD_ALLOCATE_KEYSTORE: resSW = a71cl_AllocateKeyStore(a71cl_keystore, op->params[1].value.a); resSW = SMCOM_OK; break; case kSSCP_CMD_LOAD_KEYSTORE: resSW = a71cl_loadKeyStore(a71cl_keystore); resSW = SMCOM_OK; break; case kSSCP_CMD_SAVE_KEYSTORE: resSW = a71cl_saveKeyStore(a71cl_keystore); resSW = SMCOM_OK; break; case kSSCP_CMD_SET_KEY: resSW = a71cl_setKey(a71cl_keystore->keystore_shadow, op->params[1].value.a, op->params[3].value.b, op->params[1].value.b, op->params[2].memref.buffer, op->params[2].memref.size); break; case kSSCP_KEYOBJ_CMD_ALLOCATE_HANDLE: resSW = a71cl_AllocateKeyObject(a71cl_keystore, op->params[1].value.a, op->params[1].value.b, op->params[3].value.a, op->params[2].value.a, op->params[2].value.b); resSW = SMCOM_OK; break; case kSSCP_KEYOBJ_CMD_GET_HANDLE: resSW = SMCOM_OK; break; case kSSCP_ASYMMETRIC_CTX_INIT: op->params[3].value.a = (0xFFFFFFFFu ^ op->params[2].value.a); resSW = SMCOM_OK; break; case kSSCP_ASYMMETRIC_CMD_ENCRYPT: keyId = (0xFFFFFFFFu ^ op->params[1].value.a); resSW = a71cl_rsaEncrypt(a71cl_keystore->keystore_shadow, keyId, op->params[2].memref.buffer, (uint16_t)op->params[2].memref.size, op->params[3].memref.buffer, (uint16_t *)&op->params[3].memref.size); break; case kSSCP_ASYMMETRIC_CMD_DECRYPT: keyId = (0xFFFFFFFFu ^ op->params[1].value.a); resSW = a71cl_rsaDecrypt(a71cl_keystore->keystore_shadow, keyId, op->params[2].memref.buffer, (uint16_t)op->params[2].memref.size, op->params[3].memref.buffer, (uint16_t)op->params[3].memref.size); break; case kSSCP_ASYMMETRIC_CMD_SIGN_DIGEST: keyId = (0xFFFFFFFFu ^ op->params[1].value.a); resSW = a71cl_rsaSign(a71cl_keystore->keystore_shadow, keyId, op->params[2].memref.buffer, (uint16_t)op->params[2].memref.size, op->params[3].memref.buffer, (uint16_t *)&op->params[3].memref.size); break; case kSSCP_ASYMMETRIC_CMD_VERIFY_DIGEST: keyId = (0xFFFFFFFFu ^ op->params[1].value.a); resSW = a71cl_rsaVerify(context->keyStore->keystore_shadow, keyId, op->params[2].memref.buffer, (uint16_t)op->params[2].memref.size, op->params[3].memref.buffer, (uint16_t)op->params[3].memref.size); break; case kSSCP_SYMM_CIPHER_ONE_GO: { sss_algorithm_t algorithm = ((sss_sscp_symmetric_t *)op->params[0].context.ptr)->algorithm; sss_mode_t mode = ((sss_sscp_symmetric_t *)op->params[0].context.ptr)->mode; resSW = a71cl_symmCrypt(op->params[3].memref.buffer, (U16)op->params[3].memref.size, mode, algorithm, op->params[2].memref.buffer, (U16)op->params[2].memref.size, op->params[4].memref.buffer, &(op->params[4].memref.size)); break; } case kSSCP_SYMM_CIPHER_CTX_INIT: op->params[2].value.a = (0xFFFFFFFFu ^ op->params[1].value.a); resSW = SMCOM_OK; break; case kSSCP_DERIVE_CTX_INIT: op->params[3].value.a = (0xFFFFFFFFu ^ op->params[2].value.a); resSW = SMCOM_OK; break; default: retSSCP = kStatus_SSCP_Fail; LOG_E("Not a SSCP command"); } *returnOrigin = (uint32_t)swToSSSResult(resSW); return (retSSCP); } /* ************************************************************************** */ /* Private Functions */ /* ************************************************************************** */ static U16 a71cl_GenerateKey( keyStoreTable_t *keystore_shadow, uint8_t keyType, uint8_t cipherType, uint32_t KeyID, uint16_t keybytelen) { U16 ret = ERR_API_ERROR; U8 *Key = NULL; if (keyType == kSSS_KeyPart_Pair && cipherType == kSSS_CipherType_RSA) { if ((keybytelen % 8) && keybytelen > 256) { LOG_E( "Keylen must be integer multiple of 8 and should be less than " "256 Bytes"); } if (grsaPubKey) { SSS_FREE(grsaPubKey); grsaPubKey = NULL; } grsaPubKey = SSS_MALLOC(keybytelen + 8); if (grsaPubKey == NULL) { LOG_E("malloc failed"); ret = ERR_MEMORY; goto cleanup; ; } memset(grsaPubKey, 0, keybytelen + 8); if (gapplet_mode_default) { ret = CL_GenerateKeyPair(grsaPubKey, keybytelen, eRSA, 0); } else { ret = CL_GenerateKeyPairWithKEK(grsaPubKey, keybytelen, eRSA, 0, KEK, sizeof(KEK)); } if (ret != SW_OK) { LOG_E("CL_GenerateKeyPair failed"); goto cleanup; } grsaPubKeyLen = keybytelen; } else if (keyType == kSSS_KeyPart_Default && (cipherType == kSSS_CipherType_DES || cipherType == kSSS_CipherType_AES)) { Key = SSS_MALLOC(keybytelen); ret = CL_GetChallenge(Key, keybytelen); if (ret != SW_OK) { LOG_E("Get Random failed with status 0x%X", ret); goto cleanup; } ret = a71cl_setKey(keystore_shadow, keyType, cipherType, 0, Key, keybytelen); if (ret != SW_OK) { LOG_E("a71cl_setKey failed with status 0x%X", ret); goto cleanup; } } else { LOG_E("Key Type Not Supported"); goto cleanup; } cleanup: if (Key) { SSS_FREE(Key); } return ret; } static sss_status_t swToSSSResult(uint16_t checkSW) { switch (checkSW) { case SMCOM_OK: return kStatus_SSS_Success; default: return kStatus_SSS_Fail; } } static HLSE_RET_CODE a71cl_AllocateKeyStore(sss_a71cl_key_store_t *keyStore, uint32_t keyStoreID) { HLSE_RET_CODE hlseret = SW_OK; if (gapplet_mode_default == FALSE) { hlseret = HLSE_ERR_API_ERROR; HLSE_OBJECT_HANDLE Handles[5]; U16 HandlesNum = sizeof(Handles) / sizeof(HLSE_OBJECT_HANDLE); U16 HandlesNum_copy; U8 i = 0; HLSE_OBJECT_INDEX index = 0; /* Search for our data table @ index */ if (keyStore->shadow_handle == 0) { hlseret = HLSE_EnumerateObjects(HLSE_DATA, Handles, &HandlesNum); if (hlseret == HLSE_SW_OK) { HandlesNum_copy = HandlesNum; while (HandlesNum_copy) { if (HLSE_GET_OBJECT_INDEX(Handles[i]) == index) { keyStore->shadow_handle = Handles[i]; break; } i++; HandlesNum_copy--; } } } /* If it was never there, create it @ index */ if (keyStore->shadow_handle == 0) { /* Could not find it yet*/ HLSE_KEK_WRAPPED_OBJECT_PARAMS kekparm; memcpy(kekparm.KEK, KEK, sizeof(KEK)); kekparm.KEKLen = sizeof(KEK); kekparm.value = (U8 *)&gkeystore_shadow_cl; kekparm.valueLen = sizeof(gkeystore_shadow_cl); HLSE_OBJECT_TYPE objType = HLSE_DATA; U16 templateSize = 3; HLSE_ATTRIBUTE attr[3]; ks_common_init_fat(&gkeystore_shadow_cl, gLookupEntires_cl, ARRAY_SIZE(gLookupEntires_cl)); keyStore->keystore_shadow = &gkeystore_shadow_cl; attr[0].type = HLSE_ATTR_OBJECT_TYPE; attr[0].value = &objType; attr[0].valueLen = sizeof(objType); attr[1].type = HLSE_ATTR_OBJECT_INDEX; attr[1].value = &index; attr[1].valueLen = sizeof(index); attr[2].type = HLSE_ATTR_WRAPPED_OBJECT_VALUE; attr[2].value = &kekparm; attr[2].valueLen = sizeof(HLSE_KEK_WRAPPED_OBJECT_PARAMS); hlseret = HLSE_CreateObject(attr, templateSize, &keyStore->shadow_handle); } /* Either we created it. Or it was already existing, read it. */ if (keyStore->shadow_handle != 0) { hlseret = a71cl_loadKeyStore(keyStore); } } return hlseret; } static HLSE_RET_CODE a71cl_loadKeyStore(sss_a71cl_key_store_t *keyStore) { HLSE_RET_CODE hlseret = SW_OK; if (gapplet_mode_default == FALSE) { hlseret = HLSE_ERR_API_ERROR; HLSE_ATTRIBUTE attr; attr.type = HLSE_ATTR_OBJECT_VALUE; attr.value = &gkeystore_shadow_cl; attr.valueLen = sizeof(gkeystore_shadow_cl); /* Read from Key Store and load it here in gkeystore_shadow */ hlseret = HLSE_GetObjectAttribute(keyStore->shadow_handle, &attr); keyStore->keystore_shadow = &gkeystore_shadow_cl; } return hlseret; } static HLSE_RET_CODE a71cl_saveKeyStore(sss_a71cl_key_store_t *keyStore) { HLSE_RET_CODE hlseret; if (keyStore->shadow_handle == 0) { hlseret = HLSE_ERR_API_ERROR; } else { HLSE_ATTRIBUTE attr; HLSE_KEK_WRAPPED_OBJECT_PARAMS kekparm; memcpy(kekparm.KEK, KEK, sizeof(KEK)); kekparm.KEKLen = sizeof(KEK); kekparm.value = (U8 *)keyStore->keystore_shadow; kekparm.valueLen = sizeof(*keyStore->keystore_shadow); attr.type = HLSE_ATTR_WRAPPED_OBJECT_VALUE; attr.value = &kekparm; attr.valueLen = sizeof(kekparm); /* write gkeystore_shadow */ hlseret = HLSE_SetObjectAttribute(keyStore->shadow_handle, &attr); } return hlseret; } static U16 a71cl_AllocateKeyObject(sss_a71cl_key_store_t *keyStore, uint32_t extKeyID, sss_key_part_t key_part, sss_cipher_type_t cipherType, size_t keyByteLenMax, uint32_t options) { HLSE_RET_CODE hlseret = HLSE_SW_OK; uint16_t intIndex = 0; sss_status_t ks_status; ks_status = ks_common_check_available_int_index( keyStore->keystore_shadow, (uint8_t)key_part, cipherType, &intIndex, (uint16_t)keyByteLenMax); if (ks_status != kStatus_SSS_Success) { hlseret = HLSE_ERR_MEMORY; } if (hlseret == HLSE_SW_OK) { ks_status = ks_common_update_fat(keyStore->keystore_shadow, extKeyID, (uint8_t)key_part, (uint8_t)cipherType, (uint8_t)intIndex, 0, (uint16_t)keyByteLenMax); } if (ks_status != kStatus_SSS_Success) { hlseret = HLSE_ERR_MEMORY; } if (hlseret == HLSE_SW_OK) { /* Persist to EEPROM */ hlseret = a71cl_saveKeyStore(keyStore); } else { /* Reset the structure based on EEPROM */ a71cl_loadKeyStore(keyStore); } return hlseret; } static U16 a71cl_setKey(keyStoreTable_t *keystore_shadow, sss_key_part_t key_part, sss_cipher_type_t cipher_type, uint32_t extId, uint8_t *key, size_t keyByteLen) { U16 ret = 0; U8 keyBuffer[MAX_TLV_BUF_SIZE]; /* clang-format off */ U8 CL[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44,}; /* clang-format on */ U16 offset = 0; keyBuffer[offset++] = sizeof(CL); memcpy(keyBuffer + offset, CL, sizeof(CL)); offset += sizeof(CL); keyBuffer[offset++] = ((cipher_type == kSSS_CipherType_DES) ? e3DES : (cipher_type == kSSS_CipherType_AES) ? eAES : eRSA); keyBuffer[offset++] = 0; // Key ID is always 0 if (cipher_type == kSSS_CipherType_AES || cipher_type == kSSS_CipherType_DES) { keyBuffer[offset++] = ((cipher_type == kSSS_CipherType_DES) ? etag3ES : etagAES); keyBuffer[offset++] = (U8)(keyByteLen >> 8); keyBuffer[offset++] = keyByteLen & 0xFF; memcpy(keyBuffer + offset, key, keyByteLen); offset += (U16)keyByteLen; } else if (key_part == kSSS_KeyPart_Public && cipher_type == kSSS_CipherType_RSA) { U8 *rsaN, *rsaE; size_t rsaNlen, rsaElen; ret = sss_util_asn1_rsa_parse_public(key, keyByteLen, &rsaN, &rsaNlen, &rsaE, &rsaElen); if (ret == 0) { keyBuffer[offset++] = etagRSA_N; keyBuffer[offset++] = (U8)(rsaNlen >> 8); keyBuffer[offset++] = rsaNlen & 0xFF; memcpy(keyBuffer + offset, rsaN, rsaNlen); offset += (U16)rsaNlen; keyBuffer[offset++] = etagRSA_E; keyBuffer[offset++] = (U8)(rsaElen >> 8); keyBuffer[offset++] = rsaElen & 0xFF; memcpy(keyBuffer + offset, rsaE, rsaElen); offset += (U16)rsaElen; } } else if ((key_part == kSSS_KeyPart_Private || key_part == kSSS_KeyPart_Pair) && cipher_type == kSSS_CipherType_RSA) { U8 *rsaN, *rsaE, *rsaD; size_t rsaNlen, rsaElen, rsaDlen; ret = sss_util_asn1_rsa_parse_private(key, keyByteLen, cipher_type, &rsaN, &rsaNlen, &rsaE, &rsaElen, &rsaD, &rsaDlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (ret == 0) { keyBuffer[offset++] = etagRSA_N; keyBuffer[offset++] = (U8)(rsaNlen >> 8); keyBuffer[offset++] = rsaNlen & 0xFF; memcpy(keyBuffer + offset, rsaN, rsaNlen); offset += (U16)rsaNlen; keyBuffer[offset++] = etagRSA_E; keyBuffer[offset++] = (U8)(rsaElen >> 8); keyBuffer[offset++] = rsaElen & 0xFF; memcpy(keyBuffer + offset, rsaE, rsaElen); offset += (U16)rsaElen; keyBuffer[offset++] = etagRSA_D; keyBuffer[offset++] = (U8)(rsaDlen >> 8); keyBuffer[offset++] = rsaDlen & 0xFF; memcpy(keyBuffer + offset, rsaD, rsaDlen); offset += (U16)rsaDlen; } } else { LOG_E("Key Type is not Supported"); return ERR_API_ERROR; } if (ret == 0) { if (gapplet_mode_default) { ret = CL_SecurityStorage(keyBuffer, offset); } else { ret = CL_SecurityStorageWithKEK(keyBuffer, offset, KEK, sizeof(KEK)); } if (ret != SW_OK) { LOG_E("Security Storage failed with status 0x%X", ret); return ret; } } return ret; } #endif /* SSS_HAVE_a71cl */