From bcffde119838e2a3bf91c33b4a709846f64b589b Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 6 Jul 2018 11:16:46 +0200 Subject: [PATCH] chg: smartcard - wait until SCL goes high --- client/cmdsmartcard.c | 4 +-- common/i2c.c | 71 +++++++++++++++++++++++++++---------------- common/i2c.h | 3 ++ 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 90c5743b3..04eede4da 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -101,7 +101,7 @@ int CmdSmartRaw(const char *Cmd) { PrintAndLogEx(WARNING, "smart card response failed"); return 1; } - PrintAndLogEx(SUCCESS,"resp: %s", sprint_hex(resp.d.asBytes, resp.arg[0])); + PrintAndLogEx(SUCCESS,"isOK %d | resp: %s",resp.arg[0], sprint_hex(resp.d.asBytes, resp.arg[1])); } return 0; } @@ -259,7 +259,7 @@ int CmdSmartReader(const char *Cmd){ uint8_t isok = resp.arg[0] & 0xFF; if (!isok) { - PrintAndLogEx(FAILED, "failed"); + PrintAndLogEx(FAILED, "failed to get ATR"); return 1; } diff --git a/common/i2c.c b/common/i2c.c index dc51658b9..ddf4aea5e 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -111,10 +111,9 @@ void I2C_Reset_EnterBootloader(void) { // µÈ´ýʱÖÓ±ä¸ß // Wait for the clock to go High. -volatile uint16_t count; bool WaitSCL_H(void) { - count = 5000; + volatile uint16_t count = 50000; while (count--) { if (SCL_read) { @@ -500,50 +499,70 @@ void I2C_print_status(void) { DbpString(" FW version................FAILED"); } -void SmartCardAtr(void) { - I2C_Reset_EnterMainProgram(); +#define WAIT_SCL_MAX_300 +#define WAIT_UNTIL_SCL_GOES_HIGH while (!SCL_read) { I2C_DELAY_1CLK; } +bool WaitSCL_300(void){ + volatile uint16_t delay = 300; + while ( SCL_read || delay ) { + SpinDelay(1); + delay--; + } + return (delay == 0); +} + +bool GetATR(smart_card_atr_t *card_ptr) { - uint8_t *resp = BigBuf_malloc( sizeof(smart_card_atr_t) ); - smart_card_atr_t *card = (smart_card_atr_t *)resp; + if ( card_ptr ) { + card_ptr->atr_len = 0; + memset(card_ptr->atr, 0, sizeof(card_ptr->atr)); + } // Send ATR // start [C0 01] stop I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); - // writing takes time. - SpinDelay(50); + // variable delay here. + if (!WaitSCL_300()) + return false; + + // 8051 speaks with smart card. + WAIT_UNTIL_SCL_GOES_HIGH; // start [C0 03 start C1 len aa bb cc stop] - uint8_t len = I2C_BufferRead(card->atr, sizeof(card->atr), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); + uint8_t len = I2C_BufferRead(card_ptr->atr, sizeof(card_ptr->atr), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); // remove length byte from the read bytes. - card->atr_len = len - 1; + if ( card_ptr ) + card_ptr->atr_len = len - 1; - // print ATR - Dbhexdump(len, resp, false); + return true; +} + +void SmartCardAtr(void) { + + smart_card_atr_t card; - cmd_send(CMD_ACK, len, 0, 0, resp, sizeof(smart_card_atr_t)); + I2C_Reset_EnterMainProgram(); + + bool isOK = GetATR( &card ); + if ( isOK ) + Dbhexdump(card.atr_len, card.atr, false); + + cmd_send(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t)); } void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) { -#define ISO7618_MAX_FRAME 255 + #define ISO7618_MAX_FRAME 255 I2C_Reset_EnterMainProgram(); - uint8_t buf[30] = {0}; + uint8_t len = 0; uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME); - // Send ATR - // start [C0 01] stop - I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); - - // writing takes time. - SpinDelay(50); + smart_card_atr_t card; - // start [C0 03 start C1 len aa bb cc stop] (read ATR) - uint8_t len = I2C_BufferRead(buf, sizeof(buf), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); - if ( !len ) { + bool isOK = GetATR( &card ); + if ( !isOK ) goto out; - } // Send raw bytes // start [C0 02] A0 A4 00 00 02 stop @@ -556,7 +575,7 @@ void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) { len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); out: - cmd_send(CMD_ACK, len, 0, 0, resp, len); + cmd_send(CMD_ACK, isOK, len, 0, resp, len); } void SmartCardUpgrade(uint64_t arg0) { diff --git a/common/i2c.h b/common/i2c.h index 0e7e5e5ba..089cd2e8f 100644 --- a/common/i2c.h +++ b/common/i2c.h @@ -35,6 +35,9 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); +// +bool GetATR(smart_card_atr_t *card_ptr); + // generice functions void SmartCardAtr(void); void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data);