From 1941b9ca8b3d1373ed6283d9b3d6ce8f3e03674f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 17 Dec 2018 23:48:05 +0200 Subject: [PATCH 1/5] sdd sc raw t0 --- include/mifare.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mifare.h b/include/mifare.h index 63cdf0fb6..6f87a0e6d 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -110,6 +110,7 @@ typedef enum SMARTCARD_COMMAND { SC_NO_DISCONNECT = (1 << 1), SC_RAW = (1 << 2), SC_SELECT = (1 << 3) + SC_RAW_T0 = (1 << 4), } smartcard_command_t; //----------------------------------------------------------------------------- From 85729d55e7e356ca20504707bca7c479cdec22ab Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 17 Dec 2018 23:48:30 +0200 Subject: [PATCH 2/5] added arm side --- common/i2c.c | 4 ++-- common/i2c.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/i2c.c b/common/i2c.c index ecf5a5bd9..ea830a1bd 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -698,14 +698,14 @@ void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) { } } - if ((flags & SC_RAW)) { + if ((flags & SC_RAW) || (flags & SC_RAW_T0)) { LogTrace(data, arg1, 0, 0, NULL, true); // Send raw bytes // asBytes = A0 A4 00 00 02 // arg1 = len 5 - bool res = I2C_BufferWrite(data, arg1, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN); + bool res = I2C_BufferWrite(data, arg1, ((flags & SC_RAW_T0) ? I2C_DEVICE_CMD_SEND_T0 : I2C_DEVICE_CMD_SEND), I2C_DEVICE_ADDRESS_MAIN); if ( !res && MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR); // read bytes from module diff --git a/common/i2c.h b/common/i2c.h index 8350029bd..e5ff26e4d 100644 --- a/common/i2c.h +++ b/common/i2c.h @@ -17,6 +17,7 @@ #define I2C_DEVICE_CMD_SETBAUD 0x04 #define I2C_DEVICE_CMD_SIM_CLC 0x05 #define I2C_DEVICE_CMD_GETVERSION 0x06 +#define I2C_DEVICE_CMD_SEND_T0 0x07 void I2C_recovery(void); From a759e94af0ca06dd64700c0ae5d19861d26b4896 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 17 Dec 2018 23:48:56 +0200 Subject: [PATCH 3/5] add client side and get rid of reset --- client/cmdsmartcard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index d97451e47..e09ca5b48 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -473,9 +473,9 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave smart_select(false); printf("* APDU SC\n"); - UsbCommand c = {CMD_SMART_RAW, {SC_RAW | SC_CONNECT, datainlen, 0}}; + UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, datainlen, 0}}; if (activateCard) { - c.arg[0] |= SC_SELECT; + c.arg[0] |= SC_SELECT | SC_CONNECT; } memcpy(c.d.asBytes, datain, datainlen); clearCommandBuffer(); @@ -489,7 +489,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave // retry if (len > 1 && dataout[len - 2] == 0x6c && datainlen > 4) { - UsbCommand c2 = {CMD_SMART_RAW, {SC_RAW, datainlen, 0}}; + UsbCommand c2 = {CMD_SMART_RAW, {SC_RAW_T0, datainlen, 0}}; memcpy(c2.d.asBytes, datain, datainlen); int vlen = 5 + datain[4]; From f32088e25cfa67a4bfe74a6285b84a4bca09e226 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 18 Dec 2018 14:33:28 +0200 Subject: [PATCH 4/5] fix states and get rid of INS code in receive (that code checks by controller) --- client/cmdsmartcard.c | 48 +++++++++++++++++++++---------------------- include/mifare.h | 2 +- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index e09ca5b48..0d4e7a46d 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -306,7 +306,7 @@ static int smart_wait(uint8_t *data) { return len; } -static int smart_response(uint8_t apduINS, uint8_t *data) { +static int smart_response(uint8_t *data) { int datalen = smart_wait(data); bool needGetData = false; @@ -315,12 +315,6 @@ static int smart_response(uint8_t apduINS, uint8_t *data) { goto out; } - if (datalen > 2 && data[0] != apduINS) { - PrintAndLogEx(ERR, "Card ACK error. len=0x%x data[0]=%02x", datalen, data[0]); - datalen = 0; - goto out; - } - if ( data[datalen - 2] == 0x61 || data[datalen - 2] == 0x9F ) { needGetData = true; } @@ -339,22 +333,26 @@ static int smart_response(uint8_t apduINS, uint8_t *data) { if (datalen < 2 ) { goto out; } - - if (datalen > 2 && data[0] != ISO7816_GETSTATUS) { - PrintAndLogEx(ERR, "GetResponse ACK error. len=0x%x data[0]=%02x", len, data[0]); - datalen = 0; - goto out; - } - if (datalen != len + 2 + 1) { // 2 - response, 1 - ACK - PrintAndLogEx(WARNING, "GetResponse wrong length. Must be: 0x%02x but: 0x%02x", len, datalen - 3); + // data wo ACK + if (datalen != len + 2) { + // data with ACK + if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK + if (data[0] != ISO7816_GETSTATUS) { + PrintAndLogEx(ERR, "GetResponse ACK error. len=0x%x data[0]=%02x", len, data[0]); + datalen = 0; + goto out; + } + + datalen--; + memmove(data, &data[1], datalen); + } else { + // wrong length + PrintAndLogEx(WARNING, "GetResponse wrong length. Must be: 0x%02x but: 0x%02x", len, datalen - 3); + } } } - if (datalen > 2) { - datalen--; - memmove(data, &data[1], datalen); - } out: return datalen; } @@ -441,7 +439,7 @@ int CmdSmartRaw(const char *Cmd) { if ( !buf ) return 1; - int len = smart_response(data[1], buf); + int len = smart_response(buf); if ( len < 0 ) { free(buf); return 2; @@ -453,7 +451,7 @@ int CmdSmartRaw(const char *Cmd) { memcpy(c.d.asBytes, data, sizeof(data) ); clearCommandBuffer(); SendCommand(&c); - len = smart_response(data[1], buf); + len = smart_response(buf); data[4] = 0; } @@ -481,7 +479,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave clearCommandBuffer(); SendCommand(&c); - int len = smart_response(datain[1], dataout); + int len = smart_response(dataout); if ( len < 0 ) { return 2; @@ -501,7 +499,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave clearCommandBuffer(); SendCommand(&c2); - len = smart_response(datain[1], dataout); + len = smart_response(dataout); } *dataoutlen = len; @@ -822,7 +820,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { clearCommandBuffer(); SendCommand(&c); - smart_response(data[1], buf); + smart_response(buf); // if 0x6C if ( buf[0] == 0x6C ) { @@ -831,7 +829,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { memcpy(c.d.asBytes, data, sizeof(data) ); clearCommandBuffer(); SendCommand(&c); - uint8_t len = smart_response(data[1], buf); + uint8_t len = smart_response(buf); // TLV decoder if (len > 4) diff --git a/include/mifare.h b/include/mifare.h index 6f87a0e6d..cda7cfe9d 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -109,7 +109,7 @@ typedef enum SMARTCARD_COMMAND { SC_CONNECT = (1 << 0), SC_NO_DISCONNECT = (1 << 1), SC_RAW = (1 << 2), - SC_SELECT = (1 << 3) + SC_SELECT = (1 << 3), SC_RAW_T0 = (1 << 4), } smartcard_command_t; From 8ab9b6d0ea74d7c83463448fc4e9b0c069130cab Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 18 Dec 2018 16:14:52 +0200 Subject: [PATCH 5/5] sw 0x6cxx works --- client/cmdsmartcard.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 0d4e7a46d..24803035c 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -488,13 +488,10 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave // retry if (len > 1 && dataout[len - 2] == 0x6c && datainlen > 4) { UsbCommand c2 = {CMD_SMART_RAW, {SC_RAW_T0, datainlen, 0}}; - memcpy(c2.d.asBytes, datain, datainlen); + memcpy(c2.d.asBytes, datain, 5); - int vlen = 5 + datain[4]; - if (datainlen == vlen) - datainlen++; - - c2.d.asBytes[vlen] = dataout[len - 1]; + // transfer length via T=0 + c2.d.asBytes[4] = dataout[len - 1]; clearCommandBuffer(); SendCommand(&c2);