/** * @file rjct_com.c * @author NXP Semiconductors * @version 1.0 * @par License * * Copyright 2016,2020 NXP * SPDX-License-Identifier: Apache-2.0 * * @par Description * This file implements basic communication functionality between Host and * Secure element. * @par History * 1.0 26-march-2014 : Initial version * *****************************************************************************/ #include <string.h> #include <stdint.h> #include <stdio.h> #include "rjct.h" // #ifdef __gnu_linux__ #ifdef TDA8029_UART #include "smComAlpar.h" #include "smUart.h" #endif #if defined(SCI2C) #include "smComSCI2C.h" #endif #if defined(SPI) #include "smComSCSPI.h" #endif #if defined(PCSC) #include "smComPCSC.h" #endif #if defined(SMCOM_JRCP_V2) #include "smComJRCP.h" #endif #if defined(RJCT_VCOM) #include "smComSerial.h" #endif #if defined(T1oI2C) #include "smComT1oI2C.h" #endif #if defined(SMCOM_PN7150) #include "smComPN7150.h" #endif #if defined(SMCOM_THREAD) #include "smComThread.h" #endif #include "global_platf.h" #ifndef FLOW_VERBOSE #define FLOW_VERBOSE #endif #ifdef FLOW_VERBOSE #define FPRINTF(...) printf (__VA_ARGS__) #else #define FPRINTF(...) #endif /** * SM_ConnectRjct * @param[in] commState * @param[out] atr * @param[in,out] atrLen * @return ::ERR_CONNECT_LINK_FAILED No communication with TDA chip (and/or) Secure Module * @return ::SMCOM_COM_FAILED Cannot open communication channel on the Host * @return ::SMCOM_PROTOCOL_FAILED No communication with Secure Module * @return 0x9000 OK */ U16 SM_ConnectRjct(SmCommStateRjct_t *commState, U8 *atr, U16 *atrLen) { U16 sw = SW_OK; U16 uartBR = 0; U16 t1BR = 0; #ifdef TDA8029_UART U32 status = 0; #elif defined(SCI2C) || defined(T1oI2C) U8 dummyAtr[64]; U16 dummyAtrLen = sizeof(dummyAtr); U8 precookedI2cATR[] = { 0x3B, 0xFB, 0x18, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x45, 0x50, 0x4C, 0x41, 0x43, 0x45, 0x48, 0x4F, 0x4C, 0x44, 0x45, 0x52, 0xAB}; #endif #ifndef A71_IGNORE_PARAM_CHECK if ((commState == NULL) || (atr == NULL) || (atrLen == 0)) { return ERR_API_ERROR; } #endif #ifdef TDA8029_UART if ((*atrLen) <= 33) return ERR_API_ERROR; smComAlpar_Init(); status = smComAlpar_AtrT1Configure(ALPAR_T1_BAUDRATE_MAX, atr, atrLen, &uartBR, &t1BR); if (status != SMCOM_ALPAR_OK ) { commState->param1 = 0; commState->param2 = 0; FPRINTF("smComAlpar_AtrT1Configure failed: 0x%08X\n", status); return ERR_CONNECT_LINK_FAILED; } #elif defined SMCOM_PN7150 sw = smComPN7150_Open(0, 0x00, atr, atrLen); #elif defined(SCI2C) // The smComSCI2C_Open function returns an SCI2C compliant ATR value. // This value can not be used as is as ATR parameter to the SM_Connect function because it is // not ISO7816-3 compliant. Instead a pre-cooked value is used. // In case no SCI2C ATR can be retrieved by smComSCI2C_Open, no Secure Element is attached. sw = smComSCI2C_Open(NULL, ESTABLISH_SCI2C, 0x00, dummyAtr, &dummyAtrLen); #elif defined(PCSC) sw = smComPCSC_Open(0, atr, atrLen); #elif defined(T1oI2C) // sw = smComT1oI2C_Open(NULL, ESE_MODE_NORMAL, 0x00, atr, atrLen); sw = smComT1oI2C_Open(NULL, ESE_MODE_NORMAL, 0x00, dummyAtr, &dummyAtrLen); #elif defined(SMCOM_JRCP_V2) if (atrLen != NULL) *atrLen = 0; AX_UNUSED_ARG(atr); AX_UNUSED_ARG(atrLen); #endif commState->param1 = t1BR; commState->param2 = uartBR; #if defined(SCI2C) if (sw == SW_OK) { if (dummyAtrLen == 0) { FPRINTF("smComSCI2C_Open failed. No secure module attached"); *atrLen = 0; return ERR_CONNECT_LINK_FAILED; } else { int i = 0; FPRINTF("SCI2C_ATR=0x"); for (i=0; i<dummyAtrLen; i++) FPRINTF("%02X.", dummyAtr[i]); FPRINTF("\n"); } memcpy(atr, precookedI2cATR, sizeof(precookedI2cATR)); *atrLen = sizeof(precookedI2cATR); } #endif #if defined(T1oI2C) if (sw == SW_OK) { if (dummyAtrLen == 0) { FPRINTF("smComT1oI2C_Open failed. No secure module attached"); *atrLen = 0; return ERR_CONNECT_LINK_FAILED; } else { int i = 0; FPRINTF("T1oI2C_ATR=0x"); for (i=0; i<dummyAtrLen; i++) FPRINTF("%02X.", dummyAtr[i]); FPRINTF("\n"); } FPRINTF("Replacing T1oI2C_ATR by default ATR.\n"); memcpy(atr, precookedI2cATR, sizeof(precookedI2cATR)); *atrLen = sizeof(precookedI2cATR); } #endif return sw; } U16 SM_SendAPDURjct(U8 *cmd, U16 cmdLen, U8 *resp, U16 *respLen) { U32 status = 0; U32 respLenLocal = *respLen; status = smCom_TransceiveRaw(NULL, cmd, cmdLen, resp, &respLenLocal); *respLen = (U16)respLenLocal; return (U16) status; } U16 SM_CloseRjct(U8 mode) { U16 sw = SW_OK; #if defined(SCI2C) sw = smComSCI2C_Close(mode); #endif #if defined(SPI) sw = smComSCSPI_Close(mode); #endif #if defined(PCSC) sw = smComPCSC_Close(mode); #endif #if defined(T1oI2C) sw = smComT1oI2C_Close(NULL, mode); #endif #if defined(SMCOM_JRCP_V1) AX_UNUSED_ARG(mode); sw = smComSocket_Close(); #endif #if defined(SMCOM_JRCP_V2) AX_UNUSED_ARG(mode); sw = smComJRCP_Close(NULL, mode); #endif #if defined(RJCT_VCOM) AX_UNUSED_ARG(mode); sw = smComVCom_Close(NULL); #endif #if defined(SMCOM_THREAD) AX_UNUSED_ARG(mode); sw = smComThread_Close(); #endif smCom_DeInit(); return sw; }