blob: 7e89b6c0bba474456887374226a23e9013a52870 [file] [log] [blame]
/* Copyright 2019,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
/** @file */
#if defined(FLOW_VERBOSE)
#define NX_LOG_ENABLE_SCP_DEBUG 1
#endif
#include <fsl_sss_se05x_apis.h>
#if SSS_HAVE_APPLET_SE05X_IOT
#if SSS_HAVE_SCP_SCP03_SSS && SSSFTR_SE05X_AuthECKey
#include <fsl_sss_se05x_scp03.h>
#include <nxEnsure.h>
#include <nxLog_scp.h>
#include <nxScp03_Apis.h>
#include <se05x_tlv.h>
#include <smCom.h>
#include <sm_const.h>
#include <string.h>
#if SSS_HAVE_MBEDTLS
#include "fsl_sss_mbedtls_types.h"
#elif SSS_HAVE_OPENSSL
#include "fsl_sss_openssl_types.h"
#endif
/* ************************************************************************** */
/* Functions : Private function declaration */
/* ************************************************************************** */
static sss_status_t nxECKey_InternalAuthenticate(pSe05xSession_t se05xSession,
SE05x_AuthCtx_ECKey_t *pAuthFScp,
uint8_t *hostEckaPubKey,
size_t hostEckaPubKeyLen,
uint8_t *rndData,
size_t *rndDataLen,
uint8_t *receipt,
size_t *receiptLen);
static sss_status_t nxECKey_calculate_master_secret(
SE05x_AuthCtx_ECKey_t *pAuthFScp, uint8_t *rnd, size_t rndLen, uint8_t *sharedSecret, size_t sharedSecretLen);
static sss_status_t nxECKey_HostLocal_CalculateSessionKeys(SE05x_AuthCtx_ECKey_t *pAuthFScp);
static sss_status_t nxECKey_Calculate_Initial_Mac_Chaining_Value(SE05x_AuthCtx_ECKey_t *pAuthFScp);
static sss_status_t nxECKey_Calculate_Shared_secret(
SE05x_AuthCtx_ECKey_t *pAuthFScp, uint8_t *sharedSecret, size_t *sharedSecretLen);
#define TAG_PK_SE_ECKA 0x7F49
#define TAG_SIG_SE_ECKA 0x5F37
static sss_status_t nxECKey_GetVerify_SE_Ecka_Public(
pSe05xSession_t se05xSession, uint8_t *pSePubEcka, size_t *pSePubEckaLen);
static void set_secp256r1nist_header(uint8_t *pbKey, size_t *pbKeyByteLen);
int get_u8buf_2bTag(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, uint16_t tag, uint8_t *rsp, size_t *pRspLen);
/* ************************************************************************** */
/* Functions : Function definition */
/* ************************************************************************** */
sss_status_t nxECKey_AuthenticateChannel(pSe05xSession_t se05xSession, SE05x_AuthCtx_ECKey_t *pAuthFScp)
{
sss_status_t status = kStatus_SSS_Fail;
// Host public key to send to the SE for internal authenticate
uint8_t hostEckaPub[100];
size_t hostEckaPubLen = sizeof(hostEckaPub);
size_t hostEckabitLen;
// Random bytes to retrive from SE in internal authenticate
uint8_t drSE[20];
size_t drSELen = sizeof(drSE);
uint8_t receipt[16];
size_t receiptLen = sizeof(receipt);
uint8_t shsSecret[32];
size_t shsSecretLen = sizeof(shsSecret);
int offset = 0;
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
NXSCP03_DynCtx_t *pDyn_ctx = pAuthFScp->pDyn_ctx;
uint8_t sePubkey[150] = {
0,
}; // SE ECKA Public Key
size_t sePubkeyLen = sizeof(sePubkey);
uint8_t *pkSeEcka;
/* clang-format off */
const uint8_t commandCounter[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
/* clang-format on */
/* Get the Host ephemeral key */
uint8_t hostPubkey[100];
status = sss_host_key_store_get_key(
pStatic_ctx->HostEcKeypair.keyStore, &pStatic_ctx->HostEcKeypair, hostPubkey, &hostEckaPubLen, &hostEckabitLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/* Get Ecc public key in the plain form required for Security Storage
* according to GPCS Ammendment E For ECC Nist 256 key
*/
hostEckaPub[offset++] = GPCS_KEY_TYPE_ECC_NIST256; //Tag EC public key
hostEckaPub[offset++] = 0x41; // public key len
memcpy(
hostEckaPub + offset, hostPubkey + ASN_ECC_NIST_256_HEADER_LEN, hostEckaPubLen - ASN_ECC_NIST_256_HEADER_LEN);
offset += hostEckaPubLen - ASN_ECC_NIST_256_HEADER_LEN;
hostEckaPub[offset++] = KEY_PARAMETER_REFERENCE_TAG;
hostEckaPub[offset++] = KEY_PARAMETER_REFERENCE_VALUE_LEN;
hostEckaPub[offset++] = KEY_PARAMETER_REFERENCE_VALUE;
hostEckaPubLen = offset;
/* Get SE ECKA Public Key*/
status = nxECKey_GetVerify_SE_Ecka_Public(se05xSession, sePubkey, &sePubkeyLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/* Create the Key in ASN1 Der format */
pkSeEcka = &sePubkey[2]; // Exclude first two bytes Tag and len
sePubkeyLen = sePubkeyLen - 2;
set_secp256r1nist_header(pkSeEcka, &sePubkeyLen);
sePubkeyLen = sePubkeyLen - 2; // Exclude last three bytes Key parameter tag len and value
/*Set the key in Fast scp Host context*/
status = sss_host_key_store_set_key(
pStatic_ctx->SeEcPubKey.keyStore, &pStatic_ctx->SeEcPubKey, pkSeEcka, sePubkeyLen, 256, NULL, 0);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = nxECKey_InternalAuthenticate(
se05xSession, pAuthFScp, hostEckaPub, hostEckaPubLen, drSE, &drSELen, receipt, &receiptLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/*Calculate the Shared Secret */
status = nxECKey_Calculate_Shared_secret(pAuthFScp, shsSecret, &shsSecretLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/*Erase the host key pair as it is no longer needed*/
memset(hostEckaPub, 0, sizeof(hostEckaPub));
memset(hostPubkey, 0, sizeof(hostPubkey));
sss_key_object_free(&pStatic_ctx->HostEcKeypair);
status = nxECKey_calculate_master_secret(pAuthFScp, drSE, drSELen, shsSecret, shsSecretLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = nxECKey_HostLocal_CalculateSessionKeys(pAuthFScp);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/* Increment the command Encreption counter to 1*/
memcpy(pDyn_ctx->cCounter, commandCounter, AES_KEY_LEN_nBYTE);
/* compute the initial MAC chaining value */
status = nxECKey_Calculate_Initial_Mac_Chaining_Value(pAuthFScp);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
pDyn_ctx->SecurityLevel = (uint8_t)SECURITY_LEVEL;
exit:
return status;
}
static sss_status_t nxECKey_Calculate_Initial_Mac_Chaining_Value(SE05x_AuthCtx_ECKey_t *pAuthFScp)
{
sss_status_t status = kStatus_SSS_Fail;
uint8_t ddA[128];
uint16_t ddALen = sizeof(ddA);
uint8_t iniMacChaining[AES_KEY_LEN_nBYTE];
uint32_t signatureLen = AES_KEY_LEN_nBYTE;
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
NXSCP03_DynCtx_t *pDyn_ctx = pAuthFScp->pDyn_ctx;
// Set the Derviation data
nxScp03_setDerivationData(
ddA, &ddALen, DATA_DERIVATION_INITIAL_MCV, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, NULL, 0);
// Calculate the Initial MCV value
status = nxScp03_Generate_SessionKey(&pStatic_ctx->masterSec, ddA, ddALen, iniMacChaining, &signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
LOG_MAU8_D("Initial MCV", iniMacChaining, AES_KEY_LEN_nBYTE);
// Set the Initial MCV value
memcpy(pDyn_ctx->MCV, iniMacChaining, AES_KEY_LEN_nBYTE);
exit:
return status;
}
static sss_status_t nxECKey_HostLocal_CalculateSessionKeys(SE05x_AuthCtx_ECKey_t *pAuthFScp)
{
sss_status_t status = kStatus_SSS_Fail;
uint8_t ddA[128];
uint16_t ddALen = sizeof(ddA);
uint8_t sessionEncKey[AES_KEY_LEN_nBYTE];
uint8_t sessionMacKey[AES_KEY_LEN_nBYTE];
uint8_t sessionRmacKey[AES_KEY_LEN_nBYTE];
uint32_t signatureLen = AES_KEY_LEN_nBYTE;
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
NXSCP03_DynCtx_t *pDyn_ctx = pAuthFScp->pDyn_ctx;
/* Generation and Creation of Session ENC SSS Key Object */
// Set the Derviation data
nxScp03_setDerivationData(
ddA, &ddALen, DATA_DERIVATION_SENC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, NULL, 0);
// Calculate the Session-ENC key
status = nxScp03_Generate_SessionKey(&pStatic_ctx->masterSec, ddA, ddALen, sessionEncKey, &signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
LOG_MAU8_D("sessionEncKey", sessionEncKey, AES_KEY_LEN_nBYTE);
// Set the Session-ENC key
status = sss_host_key_store_set_key(pDyn_ctx->Enc.keyStore, &pDyn_ctx->Enc, sessionEncKey, 16, (16) * 8, NULL, 0);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/* Generation and Creation of Session MAC SSS Key Object */
// Set the Derviation data
nxScp03_setDerivationData(
ddA, &ddALen, DATA_DERIVATION_SMAC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, NULL, 0);
// Calculate the Session-MAC key
status = nxScp03_Generate_SessionKey(&pStatic_ctx->masterSec, ddA, ddALen, sessionMacKey, &signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
LOG_MAU8_D("sessionMacKey", sessionMacKey, AES_KEY_LEN_nBYTE);
// Set the Session-MAC key
status = sss_host_key_store_set_key(pDyn_ctx->Mac.keyStore, &pDyn_ctx->Mac, sessionMacKey, 16, (16) * 8, NULL, 0);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/* Generation and Creation of Session RMAC SSS Key Object */
// Set the Derviation data
nxScp03_setDerivationData(
ddA, &ddALen, DATA_DERIVATION_SRMAC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, NULL, 0);
// Calculate the Session-RMAC key
status = nxScp03_Generate_SessionKey(&pStatic_ctx->masterSec, ddA, ddALen, sessionRmacKey, &signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
LOG_MAU8_D("sessionRmacKey", sessionRmacKey, AES_KEY_LEN_nBYTE);
// Set the Session-RMAC key
status =
sss_host_key_store_set_key(pDyn_ctx->Rmac.keyStore, &pDyn_ctx->Rmac, sessionRmacKey, 16, (16) * 8, NULL, 0);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
exit:
return status;
}
static sss_status_t nxECKey_calculate_master_secret(
SE05x_AuthCtx_ECKey_t *pAuthFScp, uint8_t *rnd, size_t rndLen, uint8_t *sharedSecret, size_t sharedSecretLen)
{
sss_status_t status = kStatus_SSS_Fail;
sss_digest_t md;
uint8_t derivationInput[100] = {0};
uint8_t masterSk[32];
size_t masterSkLen = sizeof(masterSk);
size_t derivationInputLen = 0;
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
if (pAuthFScp->pDyn_ctx->authType == kSSS_AuthType_INT_ECKey_Counter) {
const uint8_t kdf_counter[] = {0x00, 0x00, 0x00, 0x01};
memcpy(&derivationInput[derivationInputLen], kdf_counter, sizeof(kdf_counter));
derivationInputLen += sizeof(kdf_counter);
}
memcpy(&derivationInput[derivationInputLen], sharedSecret, sharedSecretLen);
derivationInputLen += sharedSecretLen;
memcpy(&derivationInput[derivationInputLen], rnd, rndLen);
derivationInputLen += rndLen;
derivationInput[derivationInputLen++] = SCP_CONFIG;
derivationInput[derivationInputLen++] = SECURITY_LEVEL;
derivationInput[derivationInputLen++] = GPCS_KEY_TYPE_AES;
derivationInput[derivationInputLen++] = GPCS_KEY_LEN_AES;
status = sss_host_digest_context_init(
&md, pStatic_ctx->HostEcdsaObj.keyStore->session, kAlgorithm_SSS_SHA256, kMode_SSS_Digest);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_digest_one_go(&md, derivationInput, derivationInputLen, masterSk, &masterSkLen);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
sss_host_digest_context_free(&md);
masterSkLen = 16;
LOG_MAU8_D("Master Secret", masterSk, masterSkLen);
/*Set the Master secret as AES Key*/
status = sss_host_key_store_set_key(
pStatic_ctx->masterSec.keyStore, &pStatic_ctx->masterSec, masterSk, masterSkLen, masterSkLen * 8, NULL, 0);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
cleanup:
return status;
}
static void set_secp256r1nist_header(uint8_t *pbKey, size_t *pbKeyByteLen)
{
unsigned int i = 0;
/* clang-format off */
char temp[112] = { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01,
0x07, 0x03, 0x42, 0x00 };
/* clang-format on */
for (i = 0; i < *pbKeyByteLen; i++) {
temp[26 + i] = pbKey[i];
}
*pbKeyByteLen = *pbKeyByteLen + 26;
memcpy(pbKey, temp, *pbKeyByteLen);
}
sss_status_t nxECKey_InternalAuthenticate(pSe05xSession_t se05xSession,
SE05x_AuthCtx_ECKey_t *pAuthFScp,
uint8_t *hostEckaPubKey,
size_t hostEckaPubKeyLen,
uint8_t *rndData,
size_t *rndDataLen,
uint8_t *receipt,
size_t *receiptLen)
{
sss_status_t status = kStatus_SSS_Fail;
smStatus_t retStatus = SM_NOT_OK;
int tlvRet = 0;
uint8_t cmdbuf[256];
size_t cmdbufLen = 0;
uint8_t *pCmdbuf = NULL;
uint8_t rspbuf[256];
uint8_t *pRspbuf = &rspbuf[0];
size_t rspbufLen = ARRAY_SIZE(rspbuf);
sss_digest_t md;
uint8_t md_host5F37[32];
size_t md_host5F37Len = sizeof(md_host5F37);
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
const uint8_t tagEpkSeEcka[] = {0x7F, 0x49};
const uint8_t tagSigSeEcka[] = {0x5F, 0x37};
const tlvHeader_t hdr = {{CLA_GP_7816 | CLA_GP_SECURITY_BIT, INS_GP_INTERNAL_AUTHENTICATE, 00, 00}};
uint8_t scpParms[3] = {0xAB, SCP_CONFIG, SECURITY_LEVEL};
uint8_t appletName[APPLET_NAME_LEN] = APPLET_NAME;
sss_asymmetric_t asym;
uint8_t sig_host5F37[100];
size_t sig_host5F37Len = sizeof(sig_host5F37);
size_t cntrlRefTemp_Len = 0 + 1 + 1 + APPLET_NAME_LEN /*TLV AID */ + 1 + 1 + sizeof(scpParms) /* TLV SCP Params */ +
1 + 1 + 1 /* TLV Keytype */ + 1 + 1 + 1 /* TLV KeyLEN */;
#if NX_LOG_ENABLE_SCP_DEBUG
nLog("APDU", NX_LEVEL_DEBUG, "ECKey Internal authenticate []");
#endif /* VERBOSE_APDU_LOGS */
cmdbuf[0] = kSE05x_TAG_GP_CONTRL_REF_PARM; // Tag Control reference template
cmdbuf[1] = (uint8_t)cntrlRefTemp_Len;
cmdbufLen = 2;
pCmdbuf = &cmdbuf[2];
tlvRet = TLVSET_u8buf("SE05x AID", &pCmdbuf, &cmdbufLen, kSE05x_GP_TAG_AID, appletName, APPLET_NAME_LEN);
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
tlvRet = TLVSET_u8buf("SCP parameters", &pCmdbuf, &cmdbufLen, kSE05x_GP_TAG_SCP_PARMS, scpParms, sizeof(scpParms));
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
tlvRet = TLVSET_U8("Key Type", &pCmdbuf, &cmdbufLen, kSE05x_GP_TAG_KEY_TYPE, GPCS_KEY_TYPE_AES);
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
tlvRet = TLVSET_U8("Key length", &pCmdbuf, &cmdbufLen, kSE05x_GP_TAG_KEY_LEN, GPCS_KEY_LEN_AES);
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
/*Put the ephemral host ECKA pub key */
*pCmdbuf++ = tagEpkSeEcka[0]; //Tag is 2 byte */
cmdbufLen++;
*pCmdbuf++ = tagEpkSeEcka[1];
cmdbufLen++;
*pCmdbuf++ = (uint8_t)hostEckaPubKeyLen;
cmdbufLen++;
memcpy(pCmdbuf, hostEckaPubKey, hostEckaPubKeyLen);
cmdbufLen += hostEckaPubKeyLen;
/* Get the sha256 hash of Control_refernce_template + host ECKA Pub key */
status = sss_host_digest_context_init(
&md, pStatic_ctx->HostEcdsaObj.keyStore->session, kAlgorithm_SSS_SHA256, kMode_SSS_Digest);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_digest_one_go(&md, cmdbuf, cmdbufLen, md_host5F37, &md_host5F37Len);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
sss_host_digest_context_free(&md);
/* Get the signiture over hash*/
status = sss_host_asymmetric_context_init(&asym,
pStatic_ctx->HostEcdsaObj.keyStore->session,
&pStatic_ctx->HostEcdsaObj,
kAlgorithm_SSS_SHA256,
kMode_SSS_Sign);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_asymmetric_sign_digest(&asym, md_host5F37, md_host5F37Len, sig_host5F37, &sig_host5F37Len);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
sss_host_asymmetric_context_free(&asym);
/* Put the Control refernce template Value signiture*/
pCmdbuf = &cmdbuf[cmdbufLen];
*pCmdbuf++ = tagSigSeEcka[0];
cmdbufLen++;
*pCmdbuf++ = tagSigSeEcka[1];
cmdbufLen++;
*pCmdbuf++ = (uint8_t)sig_host5F37Len;
cmdbufLen++;
memcpy(pCmdbuf, sig_host5F37, sig_host5F37Len);
cmdbufLen += sig_host5F37Len;
status = kStatus_SSS_Fail;
retStatus = DoAPDUTxRx_s_Case4(se05xSession, &hdr, cmdbuf, cmdbufLen, rspbuf, &rspbufLen);
if (retStatus == SM_OK) {
size_t rspIndex = 0;
tlvRet = tlvGet_u8buf(
pRspbuf, &rspIndex, rspbufLen, kSE05x_GP_TAG_DR_SE, rndData, rndDataLen); /* Get the Random No */
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
tlvRet = tlvGet_u8buf(
pRspbuf, &rspIndex, rspbufLen, kSE05x_GP_TAG_RECEIPT, receipt, receiptLen); /* Get the Receipt */
ENSURE_OR_GO_CLEANUP(tlvRet == 0);
ENSURE_OR_GO_CLEANUP((rspIndex + 2) == rspbufLen);
retStatus = (pRspbuf[rspIndex] << 8) | (pRspbuf[rspIndex + 1]);
ENSURE_OR_GO_CLEANUP(retStatus == SM_OK);
status = kStatus_SSS_Success;
}
cleanup:
return status;
}
sss_status_t nxECKey_GetVerify_SE_Ecka_Public(pSe05xSession_t se05xSession, uint8_t *pSePubEcka, size_t *pSePubEckaLen)
{
smStatus_t retStatus = SM_NOT_OK;
sss_status_t status = kStatus_SSS_Fail;
int tlvRet = 0;
uint8_t cmdbuf[100];
uint8_t rspbuf[512];
uint8_t *pRspbuf = &rspbuf[0];
size_t rspbufLen = ARRAY_SIZE(rspbuf);
uint8_t sigSePubkey[100];
size_t sigSePubkeyLen = sizeof(sigSePubkey);
size_t i = 0;
const tlvHeader_t hdr = {{CLA_GP_7816, INS_GP_GET_DATA, P1_GP_GET_DATA, P2_GP_GET_DATA}};
size_t cntrlRefTemp_Len = 0 + 1 + 1 + 2; /*TLV Key */
cmdbuf[i++] = kSE05x_TAG_GP_CONTRL_REF_PARM; // Tag Control reference template
cmdbuf[i++] = (uint8_t)cntrlRefTemp_Len;
cmdbuf[i++] = kSE05x_GP_TAG_GET_DATA;
cmdbuf[i++] = 0x02;
cmdbuf[i++] = 0x00; //Key Identifier
cmdbuf[i++] = 0x00; //Key Version Number
retStatus = DoAPDUTxRx_s_Case4(se05xSession, &hdr, cmdbuf, i, rspbuf, &rspbufLen);
ENSURE_OR_GO_CLEANUP(retStatus == SM_OK);
i = 0;
/* Get the Public Key*/
tlvRet = get_u8buf_2bTag(pRspbuf, &i, rspbufLen, (uint16_t)TAG_PK_SE_ECKA, pSePubEcka, pSePubEckaLen);
if (0 != tlvRet) {
goto cleanup;
}
/* Get the signiture */
tlvRet = get_u8buf_2bTag(pRspbuf, &i, rspbufLen, (uint16_t)TAG_SIG_SE_ECKA, sigSePubkey, &sigSePubkeyLen);
if (0 != tlvRet) {
goto cleanup;
}
ENSURE_OR_GO_CLEANUP((i + 2) == rspbufLen)
retStatus = (pRspbuf[i] << 8) | (pRspbuf[i + 1]);
ENSURE_OR_GO_CLEANUP(retStatus == SM_OK);
status = kStatus_SSS_Success;
cleanup:
return status;
}
int get_u8buf_2bTag(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, uint16_t tag, uint8_t *rsp, size_t *pRspLen)
{
int retVal = 1;
uint8_t *pBuf = buf + (*pBufIndex);
uint16_t got_tag;
got_tag = ((*pBuf++) << 8) & 0xFFFF;
got_tag |= ((*pBuf++)) & 0xFFFF;
size_t extendedLen;
size_t rspLen;
//size_t len;
if (got_tag != tag)
goto cleanup;
rspLen = *pBuf++;
if (rspLen <= 0x7FU) {
extendedLen = rspLen;
*pBufIndex += (2 + 1);
}
else if (rspLen == 0x81) {
extendedLen = *pBuf++;
*pBufIndex += (2 + 1 + 1);
}
else if (rspLen == 0x82) {
extendedLen = *pBuf++;
extendedLen = (extendedLen << 8) | *pBuf++;
*pBufIndex += (2 + 1 + 2);
}
else {
goto cleanup;
}
if (extendedLen > *pRspLen)
goto cleanup;
if (extendedLen > bufLen)
goto cleanup;
*pRspLen = extendedLen;
*pBufIndex += extendedLen;
while (extendedLen-- > 0) {
*rsp++ = *pBuf++;
}
retVal = 0;
cleanup:
return retVal;
}
sss_status_t nxECKey_Calculate_Shared_secret(
SE05x_AuthCtx_ECKey_t *pAuthFScp, uint8_t *sharedSecret, size_t *sharedSecretLen)
{
sss_status_t status = kStatus_SSS_Fail;
sss_derive_key_t dervCtx;
sss_object_t shsSecret;
NXECKey03_StaticCtx_t *pStatic_ctx = pAuthFScp->pStatic_ctx;
size_t sharedSecBitLen = 0;
status = sss_host_key_object_init(&shsSecret, pStatic_ctx->SeEcPubKey.keyStore);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_key_object_allocate_handle(
&shsSecret, __LINE__, kSSS_KeyPart_Default, kSSS_CipherType_AES, 32, kKeyObject_Mode_Transient);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_derive_key_context_init(&dervCtx,
pStatic_ctx->HostEcKeypair.keyStore->session,
&pStatic_ctx->HostEcKeypair,
kAlgorithm_SSS_ECDH,
kMode_SSS_ComputeSharedSecret);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_host_derive_key_dh(&dervCtx, &pStatic_ctx->SeEcPubKey, &shsSecret);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status =
sss_host_key_store_get_key(&shsSecret.keyStore, &shsSecret, sharedSecret, sharedSecretLen, &sharedSecBitLen);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
LOG_MAU8_D("Shared Secret", sharedSecret, *sharedSecretLen);
cleanup:
sss_host_derive_key_context_free(&dervCtx);
sss_host_key_object_free(&shsSecret);
return status;
}
#endif /* defined SSS_HAVE_SCP_SCP03_SSS */
#endif /* SSS_HAVE_APPLET_SE05X_IOT */