From fca841122f20ac8a8134dc4364d2c705c3592932 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 5 Jul 2018 16:32:10 +0200 Subject: [PATCH] chg: 'sc reader' - hooked up atr. --- armsrc/appmain.c | 80 +++--------------------- client/cmdsmartcard.c | 19 ++++-- common/i2c.c | 140 +++++++++++++++++++++++++++++++++++++++++- common/i2c.h | 7 +++ include/mifare.h | 8 +++ include/usb_cmd.h | 3 +- 6 files changed, 174 insertions(+), 83 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4f8ee6c99..a5e38216e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1023,22 +1023,12 @@ void UsbPacketReceived(uint8_t *packet, int len) { #endif #ifdef WITH_SMARTCARD - case CMD_SMART_SEND: { - - I2C_init(); - I2C_Reset_EnterMainProgram(); - - // sample: - // [C0 02 C1] A0 A4 00 00 02 - // asBytes = A0 A4 00 00 02 - // arg0 = len 5 - I2C_BufferWrite(c->d.asBytes, c->arg[0], I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN); - - uint8_t resp[255] = {0}; - uint8_t len = I2C_BufferRead(resp, 255, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); - Dbhexdump(len, resp, false); - - cmd_send(CMD_ACK, len, 0, 0, resp, len); + case CMD_SMART_ATR: { + SmartCardAtr(); + break; + } + case CMD_SMART_RAW: { + SmartCardRaw(c->arg[0], c->d.asBytes); break; } case CMD_SMART_UPLOAD: { @@ -1049,63 +1039,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { break; } case CMD_SMART_UPGRADE: { - - #define I2C_BLOCK_SIZE 128 - // write. Sector0, with 11,22,33,44 - // erase is 128bytes. - - StartTicks(); - I2C_init(); - I2C_Reset_EnterBootloader(); - - bool isOK = true; - uint8_t res = 0; - uint16_t length = c->arg[0]; - uint16_t pos = 0; - uint8_t *fwdata = BigBuf_get_addr(); - uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE); - - while (length) { - - uint8_t msb = (pos >> 8) & 0xFF; - uint8_t lsb = pos & 0xFF; - - Dbprintf("FW %02X %02X", msb, lsb); - - size_t size = MIN(I2C_BLOCK_SIZE, length); - - // write - res = I2C_WriteFW(fwdata+pos, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); - if ( !res ) { - Dbprintf("Writing failed"); - isOK = false; - break; - } - - // writing takes time. - WaitMS(50); - - // read - res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); - if ( res == 0) { - Dbprintf("Reading back failed"); - isOK = false; - break; - } - - // cmp - if ( 0 != memcmp(fwdata+pos, verfiydata, size)) { - Dbprintf("not equal data"); - isOK = false; - break; - } - - length -= size; - pos += size; - } - - cmd_send(CMD_ACK, isOK, pos, 0, 0, 0); - StopTicks(); + SmartCardUpgrade(c->arg[0]); break; } #endif diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 9c2a91592..44d1141b7 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -65,7 +65,7 @@ int CmdSmartRaw(const char *Cmd) { if (errors || cmdp == 0 ) return usage_sm_raw(); - UsbCommand c = {CMD_SMART_SEND, {hexlen, 0, 0}}; + UsbCommand c = {CMD_SMART_RAW, {hexlen, 0, 0}}; memcpy(c.d.asBytes, data, hexlen ); clearCommandBuffer(); SendCommand(&c); @@ -170,12 +170,16 @@ int CmdSmartUpgrade(const char *Cmd) { // trigger the firmware upgrade UsbCommand c = {CMD_SMART_UPGRADE, {bytes_read, 0, 0}}; clearCommandBuffer(); - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500) ) { + SendCommand(&c); + UsbCommand resp; + if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return 1; } - PrintAndLogEx(SUCCESS, "Smartcard socket firmware updated successful"); + if ( (resp.arg[0] && 0xFF ) ) + PrintAndLogEx(SUCCESS, "Smartcard socket firmware upgraded successful"); + else + PrintAndLogEx(FAILED, "Smartcard socket firmware updating failed"); return 0; } @@ -227,7 +231,7 @@ int CmdSmartReader(const char *Cmd){ //Validations if (errors ) return usage_sm_reader(); - UsbCommand c = {CMD_SMART_SEND, {0, 0, 0}}; + UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -242,9 +246,12 @@ int CmdSmartReader(const char *Cmd){ return 1; } + smart_card_atr_t *card = (smart_card_atr_t *)resp.d.asBytes; + // print header PrintAndLogEx(INFO, "\n--- Smartcard Information ---------"); - PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "ATR : %s", sprint_hex(card->atr, sizeof(card->atr_len))); return 0; } diff --git a/common/i2c.c b/common/i2c.c index 4bcfc5c6e..ac9617334 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -46,7 +46,6 @@ void I2C_DELAY_1(void) { I2CSpinDelayClk(1);} void I2C_DELAY_2(void) { I2CSpinDelayClk(2);} void I2C_DELAY_X(uint16_t delay) { I2CSpinDelayClk(delay);} - void I2C_init(void) { // 配置复位引脚,关闭上拉,推挽输出,默认高 // Configure reset pin, close up pull up, push-pull output, default high @@ -227,6 +226,34 @@ uint8_t I2C_ReadByte(void) { return b; } +// Only send address, and cmd. For ATR +bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) { + bool bBreak = true; + do { + if (!I2C_Start()) + return false; + + I2C_SendByte(device_address & 0xFE); + if (!I2C_WaitAck()) + break; + + I2C_SendByte(device_cmd); + if (!I2C_WaitAck()) + break; + + bBreak = false; + } while (false); + + if (bBreak) { + I2C_Stop(); + if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR); + return false; + } + + I2C_Stop(); + return true; +} + // 写入1字节数据 (待写入数据,待写入地址,器件类型) // Writes 1 byte data (Data to be written,command to be written , SlaveDevice address ). bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { @@ -236,7 +263,6 @@ bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { return false; I2C_SendByte(device_address & 0xFE); - if (!I2C_WaitAck()) break; @@ -317,7 +343,6 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d // 0xB0 or 0xC0 i2c write I2C_SendByte(device_address & 0xFE); - if (!I2C_WaitAck()) break; @@ -475,4 +500,113 @@ void I2C_print_status(void) { Dbprintf(" FW version................v%x.%02x", resp[1], resp[2]); else DbpString(" FW version................FAILED"); +} + +void SmartCardAtr(void) { + StartTicks(); + I2C_Reset_EnterMainProgram(); + + // Send ATR + // start [C0 01] stop + I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); + + // writing takes time. + WaitMS(50); + + uint8_t resp[31] = {0}; + smart_card_atr_t *card = (smart_card_atr_t *)resp; + + // 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); + + card->atr_len = len; + + // print ATR + Dbhexdump(len, resp, false); + + StopTicks(); + cmd_send(CMD_ACK, len, 0, 0, resp, sizeof(smart_card_atr_t)); +} + +void SmartCardRaw( uint64_t arg0, uint8_t *data ) { +#define ISO7618_MAX_FRAME 255 + StartTicks(); + I2C_Reset_EnterMainProgram(); + + // Send ATR + // start [C0 01] stop + I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); + + // writing takes time. + WaitMS(50); + + // sample: + // start [C0 02] A0 A4 00 00 02 stop + // asBytes = A0 A4 00 00 02 + // arg0 = len 5 + I2C_BufferWrite(data, arg0, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN); + + uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME); + + // start [C0 03 start C1 len aa bb cc stop] + uint8_t len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); + StopTicks(); + cmd_send(CMD_ACK, len, 0, 0, resp, len); +} + +void SmartCardUpgrade(uint64_t arg0) { +#define I2C_BLOCK_SIZE 128 +// write. Sector0, with 11,22,33,44 +// erase is 128bytes. + + StartTicks(); + I2C_Reset_EnterBootloader(); + + bool isOK = true; + uint8_t res = 0; + uint16_t length = arg0; + uint16_t pos = 0; + uint8_t *fwdata = BigBuf_get_addr(); + uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE); + + while (length) { + + uint8_t msb = (pos >> 8) & 0xFF; + uint8_t lsb = pos & 0xFF; + + Dbprintf("FW %02X %02X", msb, lsb); + + size_t size = MIN(I2C_BLOCK_SIZE, length); + + // write + res = I2C_WriteFW(fwdata+pos, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); + if ( !res ) { + Dbprintf("Writing failed"); + isOK = false; + break; + } + + // writing takes time. + WaitMS(50); + + // read + res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); + if ( res == 0) { + Dbprintf("Reading back failed"); + isOK = false; + break; + } + + // cmp + if ( 0 != memcmp(fwdata+pos, verfiydata, size)) { + Dbprintf("not equal data"); + isOK = false; + break; + } + + length -= size; + pos += size; + } + StopTicks(); + cmd_send(CMD_ACK, isOK, pos, 0, 0, 0); } \ No newline at end of file diff --git a/common/i2c.h b/common/i2c.h index c2d8dc0aa..bb41c76f4 100644 --- a/common/i2c.h +++ b/common/i2c.h @@ -5,6 +5,7 @@ #include "proxmark3.h" #include "apps.h" #include "util.h" +#include "BigBuf.h" #define I2C_DEVICE_ADDRESS_BOOT 0xB0 @@ -25,6 +26,7 @@ void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA); void I2C_Reset_EnterMainProgram(void); void I2C_Reset_EnterBootloader(void); +bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address); bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address); bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); @@ -33,5 +35,10 @@ 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); +// generice functions +void SmartCardAtr(void); +void SmartCardRaw(uint64_t arg0, uint8_t *data); +void SmartCardUpgrade(uint64_t arg0); + void I2C_print_status(void); #endif \ No newline at end of file diff --git a/include/mifare.h b/include/mifare.h index 99ea45534..66f493d79 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -98,6 +98,14 @@ typedef struct { } state; } nonces_t; +//----------------------------------------------------------------------------- +// ISO 7618 Smart Card +//----------------------------------------------------------------------------- +typedef struct { + uint8_t atr_len; + uint8_t atr[30]; +} __attribute__((__packed__)) smart_card_atr_t; + //----------------------------------------------------------------------------- // FeliCa //----------------------------------------------------------------------------- diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 5c8df8f9c..c136d8b21 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -76,9 +76,10 @@ typedef struct{ #define CMD_INFO_FLASH_MEM 0x0125 // RDV40, Smart card operations -#define CMD_SMART_SEND 0x0140 +#define CMD_SMART_RAW 0x0140 #define CMD_SMART_UPGRADE 0x0141 #define CMD_SMART_UPLOAD 0x0142 +#define CMD_SMART_ATR 0x0143 // For low-frequency tags #define CMD_READ_TI_TYPE 0x0202