blob: 60a24f84ab31854390ebebefac7ffe0e75b1fbac [file] [log] [blame]
/*
* Copyright 2018-2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
#include <fsl_sss_sscp.h>
#if SSS_HAVE_A71CL || SSS_HAVE_SE050_L
#include <HLSEAPI.h>
#include <a71cl_api.h>
#include <a71cl_util.h>
#include <fsl_sscp.h>
#include <fsl_sscp_a71ch.h>
#include <fsl_sscp_a71cl.h>
#include <fsl_sscp_commands.h>
#include <fsl_sss_keyid_map.h>
#include <fsl_sss_util_asn1_der.h>
#include <nxScp03_Types.h>
#include <sm_apdu.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#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(&params, &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 */