From 73c2b6498b9cbc0050037e3afcac6dd83d5a5783 Mon Sep 17 00:00:00 2001 From: Christina Quast Date: Tue, 7 Apr 2015 13:49:26 +0200 Subject: [PATCH] iso7816_4.c: GetChar returns status --- .../libboard_sam3s-ek/include/iso7816_4.h | 5 +- .../libboard_sam3s-ek/source/iso7816_4.c | 92 +++++++++++++------ sam3s_example/simtrace/cciddriver.c | 16 +++- 3 files changed, 76 insertions(+), 37 deletions(-) diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/include/iso7816_4.h b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/include/iso7816_4.h index 4b3c8116..a1dbdf02 100644 --- a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/include/iso7816_4.h +++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/include/iso7816_4.h @@ -69,9 +69,10 @@ *----------------------------------------------------------------------------*/ extern void ISO7816_Init( const Pin *pPinIso7816RstMC ); extern void ISO7816_IccPowerOff(void); -extern uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, +extern uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, uint8_t *pMessage, - uint16_t wLength ); + uint16_t wLength, + uint16_t *retlen); extern void ISO7816_Escape( void ); extern void ISO7816_RestartClock(void); extern void ISO7816_StopClock( void ); diff --git a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c index fb6d6316..89465f66 100644 --- a/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c +++ b/sam3s_example/atmel_softpack_libraries/libboard_sam3s-ek/source/iso7816_4.c @@ -184,22 +184,25 @@ void ISO7816_IccPowerOff( void ) } /** - * Transfert Block TPDU T=0 - * \param pAPDU APDU buffer - * \param pMessage Message buffer - * \param wLength Block length - * \return Message index + * Transfert Block TPDU T=0 + * \param pAPDU APDU buffer + * \param pMessage Message buffer + * \param wLength Block length + * \param indexMsg Message index + * \return 0 on success, content of US_CSR otherwise */ -uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, +uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, uint8_t *pMessage, - uint16_t wLength ) + uint16_t wLength, + uint16_t *retlen ) { uint16_t NeNc; uint16_t indexApdu = 4; - uint16_t indexMessage = 0; + uint16_t indexMsg = 0; uint8_t SW1 = 0; uint8_t procByte; uint8_t cmdCase; + uint32_t status = 0; TRACE_INFO("pAPDU[0]=0x%X\n\r",pAPDU[0]); TRACE_INFO("pAPDU[1]=0x%X\n\r",pAPDU[1]); @@ -258,7 +261,10 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, /* Handle Procedure Bytes */ do { - ISO7816_GetChar(&procByte); + status = ISO7816_GetChar(&procByte); + if (status != 0) { + return status; + } TRACE_INFO("procByte: 0x%X\n\r", procByte); /* Handle NULL */ if ( procByte == ISO_NULL_VAL ) { @@ -276,8 +282,11 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, if (cmdCase == CASE2) { /* receive data from card */ do { - ISO7816_GetChar(&pMessage[indexMessage++]); - } while( 0 != --NeNc ); + status = ISO7816_GetChar(&pMessage[indexMsg++]); + } while(( 0 != --NeNc) && (status == 0) ); + if (status != 0) { + return status; + } } else { /* Send data */ @@ -292,11 +301,17 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, TRACE_INFO("HdlINS+\n\r"); if (cmdCase == CASE2) { /* receive data from card */ - ISO7816_GetChar(&pMessage[indexMessage++]); - TRACE_INFO("Rcv: 0x%X\n\r", pMessage[indexMessage-1]); + status = ISO7816_GetChar(&pMessage[indexMsg++]); + if (status != 0) { + return status; + } + TRACE_INFO("Rcv: 0x%X\n\r", pMessage[indexMsg-1]); } else { - ISO7816_SendChar(pAPDU[indexApdu++]); + status = ISO7816_SendChar(pAPDU[indexApdu++]); + if (status != 0) { + return status; + } } NeNc--; } @@ -309,16 +324,23 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, /* Status Bytes */ if (SW1 == 0) { - ISO7816_GetChar(&pMessage[indexMessage++]); /* SW1 */ + status = ISO7816_GetChar(&pMessage[indexMsg++]); /* SW1 */ + if (status != 0) { + return status; + } } else { - pMessage[indexMessage++] = procByte; + pMessage[indexMsg++] = procByte; + } + status = ISO7816_GetChar(&pMessage[indexMsg++]); /* SW2 */ + if (status != 0) { + return status; } - ISO7816_GetChar(&pMessage[indexMessage++]); /* SW2 */ - TRACE_WARNING("SW1=0x%X, SW2=0x%X\n\r", pMessage[indexMessage-2], pMessage[indexMessage-1]); + TRACE_WARNING("SW1=0x%X, SW2=0x%X\n\r", pMessage[indexMsg-2], pMessage[indexMsg-1]); - return( indexMessage ); + *retlen = indexMsg; + return status; } @@ -375,44 +397,54 @@ uint32_t ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength ) /* Read ATR TS */ // FIXME: There should always be a check for the GetChar return value..0 means timeout status = ISO7816_GetChar(&pAtr[0]); - /* if (status == 0) { + if (status != 0) { return status; - }*/ + } /* Read ATR T0 */ - ISO7816_GetChar(&pAtr[1]); + status = ISO7816_GetChar(&pAtr[1]); + if (status != 0) { + return status; + } y = pAtr[1] & 0xF0; i = 2; /* Read ATR Ti */ - while (y) { + while (y && (status == 0)) { if (y & 0x10) { /* TA[i] */ - ISO7816_GetChar(&pAtr[i++]); + status = ISO7816_GetChar(&pAtr[i++]); } if (y & 0x20) { /* TB[i] */ - ISO7816_GetChar(&pAtr[i++]); + status = ISO7816_GetChar(&pAtr[i++]); } if (y & 0x40) { /* TC[i] */ - ISO7816_GetChar(&pAtr[i++]); + status = ISO7816_GetChar(&pAtr[i++]); } if (y & 0x80) { /* TD[i] */ - ISO7816_GetChar(&pAtr[i]); + status = ISO7816_GetChar(&pAtr[i]); y = pAtr[i++] & 0xF0; } else { y = 0; } } + if (status != 0) { + return status; + } /* Historical Bytes */ y = pAtr[1] & 0x0F; - for( j=0; j < y; j++ ) { - ISO7816_GetChar(&pAtr[i++]); + for( j=0; (j < y) && (status == 0); j++ ) { + status = ISO7816_GetChar(&pAtr[i++]); + } + + if (status != 0) { + return status; } *pLength = i; - + return status; } /** diff --git a/sam3s_example/simtrace/cciddriver.c b/sam3s_example/simtrace/cciddriver.c index 0084f278..0bba1470 100644 --- a/sam3s_example/simtrace/cciddriver.c +++ b/sam3s_example/simtrace/cciddriver.c @@ -421,7 +421,8 @@ static void PCtoRDRGetSlotStatus( void ) //------------------------------------------------------------------------------ static void PCtoRDRXfrBlock( void ) { - unsigned char indexMessage = 0; + uint16_t msglen = 0; + uint32_t ret; //TRACE_DEBUG("."); @@ -447,9 +448,14 @@ static void PCtoRDRXfrBlock( void ) TRACE_INFO("APDU cmd: %x %x %x ..", ccidDriver.sCcidCommand.APDU[0], ccidDriver.sCcidCommand.APDU[1],ccidDriver.sCcidCommand.APDU[2] ); // Send commande APDU - indexMessage = ISO7816_XfrBlockTPDU_T0( ccidDriver.sCcidCommand.APDU , - ccidDriver.sCcidMessage.abData, - ccidDriver.sCcidCommand.wLength ); + ret = ISO7816_XfrBlockTPDU_T0( ccidDriver.sCcidCommand.APDU , + ccidDriver.sCcidMessage.abData, + ccidDriver.sCcidCommand.wLength, + &msglen ); + if (ret != 0) { + TRACE_ERROR("APDU could not be sent: (US_CSR = 0x%x)", ret); + return; + } } else { if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_T1) { @@ -471,7 +477,7 @@ static void PCtoRDRXfrBlock( void ) } - ccidDriver.sCcidMessage.wLength = indexMessage; + ccidDriver.sCcidMessage.wLength = msglen; TRACE_DEBUG("USB: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n\r", ccidDriver.sCcidMessage.abData[0], ccidDriver.sCcidMessage.abData[1], ccidDriver.sCcidMessage.abData[2],