diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index b00a221c8..f7750ffd3 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -894,14 +894,14 @@ int CmdHF14ACmdRaw(const char *cmd) { if ((cmd[i]>='0' && cmd[i]<='9') || (cmd[i]>='a' && cmd[i]<='f') || (cmd[i]>='A' && cmd[i]<='F') ) { - buf[strlen(buf)+1]=0; - buf[strlen(buf)]=cmd[i]; + buf[strlen(buf)+1] = 0; + buf[strlen(buf)] = cmd[i]; i++; - if (strlen(buf)>=2) { - sscanf(buf,"%x",&temp); - data[datalen]=(uint8_t)(temp & 0xff); - *buf=0; + if (strlen(buf) >= 2) { + sscanf(buf, "%x", &temp); + data[datalen] = (uint8_t)(temp & 0xff); + *buf = 0; if (++datalen >= sizeof(data)){ if (crc) PrintAndLogEx(NORMAL, "Buffer is full, we can't add CRC to your data"); @@ -914,7 +914,7 @@ int CmdHF14ACmdRaw(const char *cmd) { return 0; } - if (crc && datalen>0 && datalen < sizeof(data)-2) { + if (crc && datalen > 0 && datalen < sizeof(data)-2) { uint8_t first, second; if (topazmode) { compute_crc(CRC_14443_B, data, datalen, &first, &second); @@ -989,7 +989,7 @@ static int waitCmd(uint8_t iSelect) { PrintAndLogEx(WARNING, "Can't select card."); } } else { - PrintAndLogEx(NORMAL, "received %i bytes:", len); + PrintAndLogEx(NORMAL, "received %i bytes", len); } if (!len) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 0697d2451..ab83c2af4 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -15,6 +15,8 @@ int usage_sm_raw(void) { PrintAndLogEx(NORMAL, "Usage: sc raw [h|r|c] d <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " r : do not read response"); + PrintAndLogEx(NORMAL, " a : active signal field ON without select"); + PrintAndLogEx(NORMAL, " s : active signal field ON with select"); PrintAndLogEx(NORMAL, " d : bytes to send"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -53,6 +55,8 @@ int usage_sm_upgrade(void) { int CmdSmartRaw(const char *Cmd) { int hexlen = 0; + bool active = false; + bool active_select = false; uint8_t cmdp = 0; bool errors = false, reply = true; uint8_t data[USB_CMD_DATA_SIZE] = {0x00}; @@ -64,6 +68,14 @@ int CmdSmartRaw(const char *Cmd) { reply = false; cmdp++; break; + case 'a': + active = true; + cmdp++; + break; + case 's': + active_select = true; + cmdp++; + break; case 'd': { switch (param_gethex_to_eol(Cmd, cmdp+1, data, sizeof(data), &hexlen)) { case 1: @@ -92,6 +104,17 @@ int CmdSmartRaw(const char *Cmd) { // arg0 = RFU flags // arg1 = length UsbCommand c = {CMD_SMART_RAW, {0, hexlen, 0}}; + + if (active || active_select) { + c.arg[0] |= SC_CONNECT; + if (active) + c.arg[0] |= SC_NO_SELECT; + } + + if (hexlen > 0) { + c.arg[0] |= SC_RAW; + } + memcpy(c.d.asBytes, data, hexlen ); clearCommandBuffer(); SendCommand(&c); @@ -103,14 +126,14 @@ int CmdSmartRaw(const char *Cmd) { PrintAndLogEx(WARNING, "smart card response failed"); return 1; } + uint32_t len = resp.arg[0]; - if ( !resp.arg[0] ) { + if ( !len ) { PrintAndLogEx(WARNING, "smart card response failed"); return 1; } - - uint32_t len = resp.arg[1]; - PrintAndLogEx(INFO, "received %i bytes:", len); + + PrintAndLogEx(INFO, "received %i bytes", len); if (!len) return 1; @@ -246,7 +269,7 @@ int CmdSmartInfo(const char *Cmd){ } //Validations - if (errors || cmdp == 0 ) return usage_sm_info(); + if (errors ) return usage_sm_info(); UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; clearCommandBuffer(); @@ -269,8 +292,9 @@ int CmdSmartInfo(const char *Cmd){ // print header PrintAndLogEx(INFO, "\n--- Smartcard Information ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PrintAndLogEx(INFO, "ATR : %s", sprint_hex(card.atr, card.atr_len)); - PrintAndLogEx(INFO, "\n todo - look up ATR "); + PrintAndLogEx(INFO, "ISO76183 ATR : %s", sprint_hex(card.atr, card.atr_len)); + PrintAndLogEx(INFO, "look up ATR"); + PrintAndLogEx(INFO, "http://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) ); return 0; } @@ -312,8 +336,7 @@ int CmdSmartReader(const char *Cmd){ smart_card_atr_t card; memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); - PrintAndLogEx(INFO, "ATR : %s", sprint_hex(card.atr, card.atr_len)); - + PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); return 0; } diff --git a/common/i2c.c b/common/i2c.c index db1d2951e..3546ead21 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -40,6 +40,9 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) + +#define ISO7618_MAX_FRAME 255 + void I2C_init(void) { // 配置复位引脚,关闭上拉,推挽输出,默认高 // Configure reset pin, close up pull up, push-pull output, default high @@ -124,13 +127,10 @@ bool WaitSCL_H(void) { // Which ever comes first bool WaitSCL_L_300ms(void){ volatile uint16_t delay = 300; - while ( delay-- ) { - + while ( delay-- ) { // exit on SCL LOW - if (!SCL_read) { - if ( MF_DBGLEVEL > 3 ) Dbprintf("300ms SCL delay counter %d", delay); - return true; - } + if (!SCL_read) + return true; SpinDelay(1); } @@ -155,17 +155,14 @@ bool I2C_Start(void) { bool I2C_WaitForSim() { // variable delay here. - if (!WaitSCL_L_300ms()) { - if ( MF_DBGLEVEL > 3 ) DbpString(" 300ms SCL delay - timed out"); + if (!WaitSCL_L_300ms()) return false; - } // 8051 speaks with smart card. // 1000*50*3.07 = 153.5ms - if (!WaitSCL_H_delay(1000*50) ) { - if ( MF_DBGLEVEL > 3 ) DbpString("wait for SCL HIGH - timed out"); + if (!WaitSCL_H_delay(1000*50) ) return false; - } + return true; } @@ -178,6 +175,7 @@ void I2C_Stop(void) { SDA_H; I2C_DELAY_XCLK(8); } + // Send i2c ACK void I2C_Ack(void) { SCL_L; I2C_DELAY_2CLK; @@ -400,7 +398,6 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d // 读取的第一个字节为后续长度 // The first byte in response is the message length if (!readcount && (len > *data)) { - if ( MF_DBGLEVEL > 3 ) Dbprintf("Old len %d , Repsonse message len %d", len, *data); len = *data; } else { data++; @@ -523,18 +520,15 @@ bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t d } void I2C_print_status(void) { - DbpString("Smart card module (ISO 7816)"); - uint8_t resp[] = {0,0,0}; + uint8_t resp[] = {0,0,0,0}; I2C_init(); I2C_Reset_EnterMainProgram(); uint8_t len = I2C_BufferRead(resp, sizeof(resp), I2C_DEVICE_CMD_GETVERSION, I2C_DEVICE_ADDRESS_MAIN); - if ( len > 0 ) { - Dbprintf(" version.................v%x.%02x", resp[0], resp[1]); - LogTrace(resp, len, 0, 0, NULL, false); - } else { - DbpString(" version.................FAILED"); - } + if ( len > 0 ) + Dbprintf(" version. ................v%x.%02x", resp[0], resp[1]); + else + DbpString(" version.................FAILED"); } bool GetATR(smart_card_atr_t *card_ptr) { @@ -559,8 +553,6 @@ bool GetATR(smart_card_atr_t *card_ptr) { if ( len == 0 ) return false; - - if ( MF_DBGLEVEL > 3 ) Dbprintf("counter %d", len); if ( card_ptr ) { card_ptr->atr_len = len; LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); @@ -576,59 +568,61 @@ void SmartCardAtr(void) { I2C_Reset_EnterMainProgram(); bool isOK = GetATR( &card ); cmd_send(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t)); - LED_D_OFF(); + set_tracing(false); + LEDsoff(); } void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) { LED_D_ON(); - clear_trace(); + + smartcard_command_t flags = arg0; + + if ((flags & SC_CONNECT)) + clear_trace(); + set_tracing(true); - - //uint64_t flags = arg0; - - #define ISO7618_MAX_FRAME 255 - I2C_Reset_EnterMainProgram(); uint8_t len = 0; uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME); - smart_card_atr_t card; - bool isOK = GetATR( &card ); - if ( !isOK ) - goto out; + if ((flags & SC_CONNECT)) { - // log raw bytes - LogTrace(data, arg1, 0, 0, NULL, true); + I2C_Reset_EnterMainProgram(); + + if ( !(flags & SC_NO_SELECT) ) { + smart_card_atr_t card; + bool gotATR = GetATR( &card ); + //cmd_send(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t)); + if ( !gotATR ) + goto OUT; + } + } - // Send raw bytes - // start [C0 02] A0 A4 00 00 02 stop - // asBytes = A0 A4 00 00 02 - // arg1 = len 5 - I2C_BufferWrite(data, arg1, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN); + if ((flags & SC_RAW)) { + + LogTrace(data, arg1, 0, 0, NULL, true); + + // Send raw bytes + // asBytes = A0 A4 00 00 02 + // arg1 = len 5 + I2C_BufferWrite(data, arg1, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN); + + //wait for sim card to answer. + if ( !I2C_WaitForSim() ) + goto OUT; + + // read response + // start [C0 03 start C1 len aa bb cc stop] + len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); - //wait for sim card to answer. - isOK = I2C_WaitForSim(); - if ( !isOK ) - goto out; - - // read response - // start [C0 03 start C1 len aa bb cc stop] - len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); - - if ( len == 0) - isOK = false; - - if ( MF_DBGLEVEL > 3 ) Dbprintf("counter %d", len); - -out: - cmd_send(CMD_ACK, isOK, len, 0, resp, len); - - // log answer - if ( len ) LogTrace(resp, len, 0, 0, NULL, false); + } - LED_D_OFF(); +OUT: + cmd_send(CMD_ACK, len, 0, 0, resp, len); + set_tracing(false); + LEDsoff(); } void SmartCardUpgrade(uint64_t arg0) { @@ -653,7 +647,7 @@ void SmartCardUpgrade(uint64_t arg0) { uint8_t msb = (pos >> 8) & 0xFF; uint8_t lsb = pos & 0xFF; - Dbprintf("FW %02X %02X", msb, lsb); + Dbprintf("FW %02X%02X", msb, lsb); size_t size = MIN(I2C_BLOCK_SIZE, length); diff --git a/common/i2c.h b/common/i2c.h index 751b561a6..fedaa08b7 100644 --- a/common/i2c.h +++ b/common/i2c.h @@ -6,7 +6,7 @@ #include "apps.h" #include "util.h" #include "BigBuf.h" - +#include "mifare.h" #define I2C_DEVICE_ADDRESS_BOOT 0xB0 #define I2C_DEVICE_ADDRESS_MAIN 0xC0 diff --git a/include/mifare.h b/include/mifare.h index 66f493d79..2ab7e3741 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -56,7 +56,6 @@ typedef struct { byte_t cid; } __attribute__((__packed__)) iso14b_card_select_t; - typedef enum ISO14B_COMMAND { ISO14B_CONNECT = (1 << 0), ISO14B_DISCONNECT = (1 << 1), @@ -106,6 +105,13 @@ typedef struct { uint8_t atr[30]; } __attribute__((__packed__)) smart_card_atr_t; +typedef enum SMARTCARD_COMMAND { + SC_CONNECT = (1 << 0), + SC_NO_DISCONNECT = (1 << 1), + SC_RAW = (1 << 2), + SC_NO_SELECT = (1 << 3) +} smartcard_command_t; + //----------------------------------------------------------------------------- // FeliCa //-----------------------------------------------------------------------------