blob: be155c7d6d466e969cd3de0ebe5527c7cf652d87 [file] [log] [blame]
/*
*
* Copyright 2019,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef SE05X_TLV_H_INC
#define SE05X_TLV_H_INC
#include <sm_types.h>
#include <se05x_enums.h>
#include "nxLog.h"
#include "nxScp03_Types.h"
//#include <smCom.h>
// #define VERBOSE_APDU_LOGS 1
#define kSE05x_CLA 0x80
typedef enum
{
SM_NOT_OK = 0xFFFF,
SM_OK = 0x9000,
SM_ERR_CONDITIONS_OF_USE_NOT_SATISFIED = 0x6985,
SM_ERR_ACCESS_DENIED_BASED_ON_POLICY = 0x6986,
} smStatus_t;
typedef enum
{
CRED_DEFAULT = 0x00,
CRED_EC = 0x01,
CRED_RSA = 0x02,
CRED_AES = 0x03,
CRED_DES = 0x04,
CRED_BINARY = 0x05,
CRED_PIN = 0x06,
CRED_COUNTER = 0x07,
CRED_PCR = 0x08,
CRED_OBJECT = 0x09,
CRED_PUB_EC,
CRED_PUB_RSA
} eSE05xType_t;
typedef struct
{
uint8_t *se05xTxBuf;
size_t se05xTxBufLen;
size_t ws_LC; // With Session LC
size_t ws_LCW; // With Session LC Width 1 or 3 bytes
uint8_t *wsSe05x_cmd; // WithSession SE05X command
size_t wsSe05x_cmdLen; // WithSession SE05X command Length
size_t wsSe05x_tag1Len; // WithSession SE05X Tag1 len
size_t wsSe05x_tag1W; // WithSession SE05X Tag1 Width
uint8_t *wsSe05x_tag1Cmd; // WithSession SE05X Tag1 Command Data
size_t wsSe05x_tag1CmdLen; // WithSession SE05X Tag1 Command Data Len
const tlvHeader_t *se05xCmd_hdr; // SE05x Command Header
size_t se05xCmdLC; // SE05x Command LC
size_t se05xCmdLCW; // SE05x Command LC width
uint8_t *se05xCmd; // SE05x Command
size_t se05xCmdLen; // SE05x Command Length
uint8_t *dataToMac;
size_t dataToMacLen;
} Se05xApdu_t;
struct Se05xSession;
struct _sss_se05x_tunnel_context;
typedef struct Se05xSession
{
uint8_t value[8];
uint8_t hasSession : 1;
SE_AuthType_t authType;
/** Meta Funciton
*
* Internall first calls fp_Transform
* Then calls fp_RawTXn
* Then calls fp_DeCrypt
*/
smStatus_t(*fp_TXn)(struct Se05xSession * pSession,
const tlvHeader_t *hdr, uint8_t *cmdBuf, size_t cmdBufLen, uint8_t *rsp, size_t *rspLen, uint8_t hasle);
/** API called by fp_TXn. Helps handle UserID/Applet/ECKey to transform buffer.
*
* But this API never sends any data out over any communication link. */
smStatus_t(*fp_Transform)(struct Se05xSession * pSession,
/** IN */
const tlvHeader_t *inHdr,
/** IN */
uint8_t *inCmdBuf,
/** IN */
size_t inCmdBufLen,
/** OUT:
* For Session less,
* For Platform SCP this will be copy of, inHDR, with outHdr[0] = outHdr[0] | 0x04
* For Plain Session: Same as inHDR
*
* For With Session:
* This will be with TLV Header for Wrapped Session Command
*/
tlvHeader_t *outHdr,
/** OUT: For Session less, this will be copy of inCmdBuf
*
* For session based impelementation, this will have
* TAG=Session, L=8,V=Session,TAG=TAG1,L=inCmdBufLen,inCmdBuf */
uint8_t * pTxBuf,
/** IN,OUT: */
size_t * pTxBufLen,
/** IN */
uint8_t hasle);
/* API called by fp_TXn. Helps handle Applet/Fast SCP to decrypt buffer.
*
* But this API never reads any data */
smStatus_t(*fp_DeCrypt)(struct Se05xSession * pSession,
size_t prevCmdBufLen,
uint8_t *pInRxBuf,
size_t *pInRxBufLen,
uint8_t hasle);
#if SSS_HAVE_APPLET_SE05X_IOT
/* It's either a minimal/single implemntation that calls smCom_TransceiveRaw()
*
* if pTunnelCtx is Null, directly call smCom_TransceiveRaw()
*
* Or an API part of tunnel ctx that can do PlatformSCP */
smStatus_t (*fp_RawTXn)(void *conn_ctx,
struct _sss_se05x_tunnel_context *pChannelCtx,
SE_AuthType_t currAuth,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rsp,
size_t *rspLen,
uint8_t hasle);
struct _sss_se05x_tunnel_context * pChannelCtx;
#endif
#if SSS_HAVE_SE
smStatus_t(*fp_Transmit)(
SE_AuthType_t currAuth,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rsp,
size_t *rspLen,
uint8_t hasle);
#endif
NXSCP03_DynCtx_t *pdynScp03Ctx;
/**Connection data context */
void *conn_ctx;
} Se05xSession_t;
typedef struct
{
uint8_t *value;
size_t value_len;
} Se05xPolicy_t;
typedef struct
{
uint8_t ts[12];
} SE05x_TimeStamp_t;
typedef struct
{
uint8_t features[30];
} SE05x_ExtendedFeatures_t;
typedef struct
{
SE05x_Variant_t variant;
SE05x_ExtendedFeatures_t *extended_features;
} Se05x_AppletFeatures_t;
typedef Se05x_AppletFeatures_t *pSe05xAppletFeatures_t;
typedef Se05xSession_t *pSe05xSession_t;
typedef Se05xPolicy_t *pSe05xPolicy_t;
#if VERBOSE_APDU_LOGS
#define DO_LOG_V(TAG, DESCRIPTION, VALUE) nLog("APDU", NX_LEVEL_DEBUG, #TAG " [" DESCRIPTION "] = 0x%X", VALUE);
#define DO_LOG_A(TAG, DESCRIPTION, ARRAY, ARRAY_LEN) \
nLog_au8("APDU", NX_LEVEL_DEBUG, #TAG " [" DESCRIPTION "]", ARRAY, ARRAY_LEN);
#else
#define DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define DO_LOG_A(TAG, DESCRIPTION, ARRAY, ARRAY_LEN)
#endif
#define TLVSET_Se05xSession(DESCRIPTION, PBUF, PBUFLEN, TAG, SESSIONID) \
TLVSET_u8buf(DESCRIPTION, PBUF, PBUFLEN, TAG, SESSIONID->value, sizeof(SESSIONID->value))
#define TLVSET_Se05xPolicy(DESCRIPTION, PBUF, PBUFLEN, TAG, POLICY) \
tlvSet_Se05xPolicy(DESCRIPTION, PBUF, PBUFLEN, TAG, POLICY)
#define TLVSET_U8(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_U8(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_U16(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_U16(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_U16Optional(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_U16Optional(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_U32(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_U32(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_U64_SIZE(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE,SIZE) \
tlvSet_U64_size(PBUF, PBUFLEN, TAG, VALUE,SIZE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_KeyID(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_KeyID(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_MaxAttemps(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_MaxAttemps(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_AttestationAlgo TLVSET_U8
#define TLVSET_CipherMode TLVSET_U8
#define TLVSET_ECCurve(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
tlvSet_ECCurve(PBUF, PBUFLEN, TAG, VALUE); \
DO_LOG_V(TAG, DESCRIPTION, VALUE)
#define TLVSET_ECCurveParam TLVSET_U8
#define TLVSET_ECDAASignatureAlgo TLVSET_U8
#define TLVSET_ECSignatureAlgo TLVSET_U8
#define TLVSET_EDSignatureAlgo TLVSET_U8
#define TLVSET_MacOperation TLVSET_U8
#define TLVSET_RSAEncryptionAlgo TLVSET_U8
#define TLVSET_RSAKeyComponent TLVSET_U8
#define TLVSET_RSASignatureAlgo TLVSET_U8
#define TLVSET_DigestMode TLVSET_U8
#define TLVSET_Variant tlvSet_u8buf_features
#define TLVSET_RSAPubKeyComp TLVSET_U8
#define TLVSET_PlatformSCPRequest TLVSET_U8
#define TLVSET_MemoryType TLVSET_U8
#define TLVSET_CryptoContext TLVSET_U8
#define TLVSET_CryptoModeSubType(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) \
TLVSET_U8(DESCRIPTION, PBUF, PBUFLEN, TAG, ((VALUE).union_8bit))
#define TLVSET_CryptoObjectID TLVSET_U16
// #define TLVSET_pVoid(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) (0)
// #define tlvGet_pVoid(DESCRIPTION, PBUF, PBUFLEN, TAG, VALUE) (0)
#define TLVSET_u8buf(DESCRIPTION, PBUF, PBUFLEN, TAG, CMD, CMDLEN) \
tlvSet_u8buf(PBUF, PBUFLEN, TAG, CMD, CMDLEN); \
DO_LOG_A(TAG, DESCRIPTION, CMD, CMDLEN)
#define TLVSET_u8bufOptional(DESCRIPTION, PBUF, PBUFLEN, TAG, CMD, CMDLEN) \
tlvSet_u8bufOptional(PBUF, PBUFLEN, TAG, CMD, CMDLEN); \
DO_LOG_A(TAG, DESCRIPTION, CMD, CMDLEN)
#define TLVSET_u8bufOptional_ByteShift(DESCRIPTION, PBUF, PBUFLEN, TAG, CMD, CMDLEN) \
tlvSet_u8bufOptional_ByteShift(PBUF, PBUFLEN, TAG, CMD, CMDLEN); \
DO_LOG_A(TAG, DESCRIPTION, CMD, CMDLEN)
#define TLVSET_u8buf_I2CM(DESCRIPTION, PBUF, PBUFLEN, TAG, CMD, CMDLEN) \
tlvSet_u8buf_I2CM(PBUF, PBUFLEN, TAG, CMD, CMDLEN); \
DO_LOG_A(TAG, DESCRIPTION, CMD, CMDLEN)
int tlvSet_U8(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint8_t value);
int tlvSet_U16(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint16_t value);
int tlvSet_U16Optional(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint16_t value);
int tlvSet_U32(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint32_t value);
int tlvSet_U64_size(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint64_t value,uint16_t size);
int tlvSet_u8buf(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, const uint8_t *cmd, size_t cmdLen);
int tlvSet_u8bufOptional(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, const uint8_t *cmd, size_t cmdLen);
/* Same as tlvSet_u8bufOptional, but some time, Most Significant Byte needs to be shifted and Plus by 1 */
int tlvSet_u8bufOptional_ByteShift(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, const uint8_t *cmd, size_t cmdLen);
int tlvSet_Se05xPolicy(const char *description, uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, Se05xPolicy_t *policy);
int tlvSet_KeyID(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint32_t keyID);
int tlvSet_MaxAttemps(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint16_t maxAttemps);
int tlvSet_ECCurve(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, SE05x_ECCurve_t value);
int tlvSet_u8buf_features(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, pSe05xAppletFeatures_t appletVariant);
int tlvGet_U8(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint8_t *pRsp);
int tlvGet_U16(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint16_t *pRsp);
int tlvGet_U32(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint32_t *pRsp);
int tlvGet_u8buf(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint8_t *rsp, size_t *pRspLen);
int tlvGet_Se05xSession(
uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, pSe05xSession_t *pSessionId);
int tlvGet_TimeStamp(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, SE05x_TimeStamp_t *pTs);
int tlvSet_u8buf_I2CM(uint8_t **buf, size_t *bufLen, SE05x_I2CM_TAG_t tag, const uint8_t *cmd, size_t cmdLen);
int tlvGet_SecureObjectType(uint8_t *buf, size_t *pBufIndex, size_t bufLen, SE05x_TAG_t tag, SE05x_SecObjTyp_t *pType);
int tlvGet_Result(uint8_t *buf, size_t *pBufIndex, size_t bufLen, SE05x_TAG_t tag, SE05x_Result_t *presult);
smStatus_t se05x_Transform(struct Se05xSession *pSession,
const tlvHeader_t *hdr,
uint8_t *cmdApduBuf,
const size_t cmdApduBufLen,
tlvHeader_t *out_hdr,
uint8_t *txBuf,
size_t *ptxBufLen,
uint8_t hasle);
smStatus_t se05x_Transform_scp(struct Se05xSession *pSession,
const tlvHeader_t *hdr,
uint8_t *cmdApduBuf,
const size_t cmdApduBufLen,
tlvHeader_t *outhdr,
uint8_t *txBuf,
size_t *ptxBufLen,
uint8_t hasle);
smStatus_t se05x_DeCrypt(struct Se05xSession *pSessionCtx,
size_t cmd_cmacLen,
uint8_t *rsp,
size_t *rspLength,
uint8_t hasle);
smStatus_t DoAPDUTxRx_s_Case2(Se05xSession_t *pSessionCtx,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rspBuf,
size_t *pRspBufLen);
smStatus_t DoAPDUTx_s_Case3(Se05xSession_t *pSessionCtx,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen);
smStatus_t DoAPDUTxRx_s_Case4(Se05xSession_t *pSessionCtx,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rspBuf,
size_t *pRspBufLen);
smStatus_t DoAPDUTxRx_s_Case4_ext(Se05xSession_t *pSessionCtx,
const tlvHeader_t *hdr,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rspBuf,
size_t *pRspBufLen);
smStatus_t DoAPDUTxRx(Se05xSession_t *pSessionCtx,
uint8_t *cmdBuf,
size_t cmdBufLen,
uint8_t *rspBuf,
size_t *pRspBufLen);
#if SSS_HAVE_APPLET_SE05X_IOT
smStatus_t Se05x_API_I2CM_Send(
pSe05xSession_t sessionId, const uint8_t *buffer, size_t bufferLen, uint8_t *result, size_t *presultLen);
#endif
#endif // !SE05X_TLV_H_INC