/* * * Copyright 2019,2020 NXP * SPDX-License-Identifier: Apache-2.0 */ #ifndef SE05X_TLV_H_INC #define SE05X_TLV_H_INC #include #include #include "nxLog.h" #include "nxScp03_Types.h" //#include // #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_ValueIndex(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag); 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