From b6e1344e1c46438e4e1f7b4171f435968c880fc4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 16 Sep 2023 18:38:53 +0200 Subject: [PATCH] added a custom timeout parameter to the smart raw command --- CHANGELOG.md | 1 + armsrc/i2c.c | 44 ++++++++++++++++++++++++++------------- armsrc/i2c.h | 2 +- client/src/cmdsmartcard.c | 11 +++++++++- include/pm3_cmd.h | 2 ++ 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ea0b13fd..bd279eca9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `smart raw --timeout` - allows for a custom timeout (@iceman1001) - Changed `lf t55 detectp1` - now also accepts 0xE039 Silicon Craft Tech as valid card (@iceman1001) - Fixed `utils.lua` library function "convertdectohex" wasn't working (@iceman1001) - Added `hf iclass creditepurse` command to allow crediting the epurse debit value (@nvx) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 016ae2f13..c06eab580 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -39,6 +39,11 @@ #define I2C_ERROR "I2C_WaitAck Error" +// 8051 speaks with smart card. +// 1000*50*3.07 = 153.5ms +// 1 byte transfer == 1ms with max frame being 256 bytes +#define SIM_WAIT_DELAY 109773 // about 337.7ms delay + // Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz, // delay=1 is about 200kbps // timer. @@ -168,8 +173,8 @@ static bool WaitSCL_H_delay(uint32_t delay) { return false; } -// 5000 * 3.07us = 15350us. 15.35ms -// 15000 * 3.07us = 46050us. 46.05ms +// 5000 * 3.07us = 15350 us = 15.35 ms +// 15000 * 3.07us = 46050 us = 46.05 ms static bool WaitSCL_H(void) { return WaitSCL_H_delay(5000); } @@ -194,7 +199,7 @@ static bool WaitSCL_L(void) { // It timeout reading response from card // Which ever comes first static bool WaitSCL_L_timeout(void) { - volatile uint32_t delay = 200; + volatile uint32_t delay = 1800; while (delay--) { // exit on SCL LOW if (SCL_read == false) @@ -227,17 +232,22 @@ static bool I2C_Start(void) { return true; } -static bool I2C_WaitForSim(void) { +static bool I2C_WaitForSim(uint32_t wait) { // wait for data from card - if (!WaitSCL_L_timeout()) + if (WaitSCL_L_timeout() == false) { return false; + } // 8051 speaks with smart card. - // 1000*50*3.07 = 153.5ms - // 1000*110*3.07 = 337.7ms + // 1000*50*3.07 = 153.5ms + // 1000*110*3.07 = 337.7ms (337700) + // 4 560 000 * 3.07 = 13999,2ms (13999200) // 1byte transfer == 1ms with max frame being 256bytes - return WaitSCL_H_delay(1000 * 110); + + // fct WaitSCL_H_delay uses a I2C_DELAY_1CLK in the loop with "wait" as number of iterations. + // I2C_DELAY_1CLK == I2CSpinDelayClk(1) = 3.07us + return WaitSCL_H_delay(wait); } // send i2c STOP @@ -670,13 +680,13 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) { } // Will read response from smart card module, retries 3 times to get the data. -bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen) { +bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait) { uint8_t i = 5; int16_t len = 0; while (i--) { - I2C_WaitForSim(); + I2C_WaitForSim(wait); len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); @@ -703,6 +713,7 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { if (card_ptr == NULL) return false; + card_ptr->atr_len = 0; memset(card_ptr->atr, 0, sizeof(card_ptr->atr)); @@ -712,13 +723,13 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); //wait for sim card to answer. - // 1byte = 1ms , max frame 256bytes. Should wait 256ms atleast just in case. - if (I2C_WaitForSim() == false) + // 1byte = 1ms , max frame 256bytes. Should wait 256ms atleast just in case. + if (I2C_WaitForSim(SIM_WAIT_DELAY) == false) return false; // read bytes from module uint16_t len = sizeof(card_ptr->atr); - if (sc_rx_bytes(card_ptr->atr, &len) == false) + if (sc_rx_bytes(card_ptr->atr, &len, SIM_WAIT_DELAY) == false) return false; if (len > sizeof(card_ptr->atr)) { @@ -805,6 +816,11 @@ void SmartCardRaw(const smart_card_raw_t *p) { if ((flags & SC_RAW) || (flags & SC_RAW_T0)) { + uint32_t wait = SIM_WAIT_DELAY; + if ((flags & SC_WAIT) == SC_WAIT) { + wait = (uint32_t)((p->wait_delay * 1000) / 3.07); + } + LogTrace(p->data, p->len, 0, 0, NULL, true); bool res = I2C_BufferWrite( @@ -821,7 +837,7 @@ void SmartCardRaw(const smart_card_raw_t *p) { // read bytes from module len = ISO7816_MAX_FRAME; - res = sc_rx_bytes(resp, &len); + res = sc_rx_bytes(resp, &len, wait); if (res) { LogTrace(resp, len, 0, 0, NULL, false); } else { diff --git a/armsrc/i2c.h b/armsrc/i2c.h index 6fa8b8809..da5da0532 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -48,7 +48,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); bool I2C_WriteFW(const uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); -bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen); +bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait); // bool GetATR(smart_card_atr_t *card_ptr, bool verbose); diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 8c6dbda2b..55a3b62e4 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -416,6 +416,7 @@ static int CmdSmartRaw(const char *Cmd) { arg_lit0("s", NULL, "active smartcard with select (get ATR)"), arg_lit0("t", "tlv", "executes TLV decoder if it possible"), arg_lit0("0", NULL, "use protocol T=0"), + arg_int0(NULL, "timeout", "", "Timeout in MS waiting for SIM to respond. (def 337ms)"), arg_str1("d", "data", "", "bytes to send"), arg_param_end }; @@ -426,10 +427,11 @@ static int CmdSmartRaw(const char *Cmd) { bool active_select = arg_get_lit(ctx, 3); bool decode_tlv = arg_get_lit(ctx, 4); bool use_t0 = arg_get_lit(ctx, 5); + int timeout = arg_get_int_def(ctx, 6, -1); int dlen = 0; uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; - int res = CLIParamHexToBuf(arg_get_str(ctx, 6), data, sizeof(data), &dlen); + int res = CLIParamHexToBuf(arg_get_str(ctx, 7), data, sizeof(data), &dlen); CLIParserFree(ctx); if (res) { @@ -452,6 +454,13 @@ static int CmdSmartRaw(const char *Cmd) { if (active_select) payload->flags |= SC_SELECT; } + + payload->wait_delay = 0; + if (timeout > -1) { + payload->flags |= SC_WAIT; + payload->wait_delay = timeout; + } + PrintAndLogEx(DEBUG, "SIM Card timeout... %u ms", payload->wait_delay); if (dlen > 0) { if (use_t0) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e84a4183b..05b313482 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -338,10 +338,12 @@ typedef enum SMARTCARD_COMMAND { SC_RAW_T0 = (1 << 4), SC_CLEARLOG = (1 << 5), SC_LOG = (1 << 6), + SC_WAIT = (1 << 7), } smartcard_command_t; typedef struct { uint8_t flags; + uint32_t wait_delay; uint16_t len; uint8_t data[]; } PACKED smart_card_raw_t;