mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-09-11 18:29:22 -07:00
new sim module firmware, shorter delays for T=0 transfers
This commit is contained in:
+9
-30
@@ -45,13 +45,9 @@
|
||||
#define SC_PROTO_T0 (1 << 0)
|
||||
#define SC_PROTO_T1 (1 << 1)
|
||||
|
||||
// Protocols the last ATR offered, as a bit mask of (1 << T). Zero means we do
|
||||
// not know - no ATR has been read since the module was last reset.
|
||||
// protocols the last ATR offered, (1 << T). 0 = no ATR read since reset
|
||||
static uint8_t s_card_protocols = 0;
|
||||
|
||||
// Whether the protocol choice has already been reported this session. These
|
||||
// messages are worth seeing once; sc_raw_device_cmd() runs per APDU, and an
|
||||
// EMV AID sweep is 150 of them.
|
||||
// sc_raw_device_cmd() runs per APDU, so report the choice once per card
|
||||
static bool s_proto_announced = false;
|
||||
|
||||
// try i2c bus recovery at 100kHz = 5us high, 5us low
|
||||
@@ -848,11 +844,8 @@ bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* ISO/IEC 7816-3 clause 8: the protocols on offer are the low nibbles of the
|
||||
* TDi bytes. With no TD1 at all, only T=0 is offered. T=15 carries global
|
||||
* interface bytes rather than a transmission protocol and is ignored here.
|
||||
*/
|
||||
// ISO 7816-3 clause 8: offered protocols are the low nibbles of the TDi bytes.
|
||||
// No TD1 means T=0 only. T=15 is global interface bytes, not a protocol.
|
||||
static uint8_t atr_protocols(const uint8_t *atr, uint8_t len) {
|
||||
|
||||
if (len < 2) {
|
||||
@@ -892,10 +885,7 @@ static uint8_t atr_protocols(const uint8_t *atr, uint8_t len) {
|
||||
|
||||
uint8_t sc_raw_device_cmd(smartcard_command_t flags) {
|
||||
|
||||
// An explicit T=1 request is always honoured as asked - it is an override,
|
||||
// and a card that supports T=1 without advertising it is a real thing. But
|
||||
// say so when the ATR disagrees, because the alternative is silence from
|
||||
// the card and no clue why.
|
||||
// an explicit T=1 request is an override, honoured even if the ATR disagrees
|
||||
if ((flags & SC_RAW_T1) == SC_RAW_T1) {
|
||||
|
||||
if ((s_card_protocols != 0) && ((s_card_protocols & SC_PROTO_T1) == 0)) {
|
||||
@@ -909,21 +899,10 @@ uint8_t sc_raw_device_cmd(smartcard_command_t flags) {
|
||||
|
||||
if ((flags & SC_RAW_T0) == SC_RAW_T0) {
|
||||
|
||||
/*
|
||||
* A T=0 request to a card whose ATR offers no T=0 cannot work - the
|
||||
* card will not hear it at all, which shows up as silence rather than
|
||||
* an error. Most modern EMV and JCOP cards are T=1 only, and callers
|
||||
* like ExchangeAPDUSC() ask for T=0 unconditionally.
|
||||
*
|
||||
* Only this one case is redirected, and only once an ATR has actually
|
||||
* been read. A card that does offer T=0 is left alone even if it also
|
||||
* offers T=1, because there the caller's choice is a real one - use
|
||||
* SC_RAW_T1 to say otherwise.
|
||||
*
|
||||
* Note this cannot make anything worse even against a SIM module too
|
||||
* old to know SEND_T1: in the exact case it fires, the request as given
|
||||
* was already guaranteed to fail.
|
||||
*/
|
||||
// A T=0 request to a card offering no T=0 cannot work - it simply will
|
||||
// not hear it. Most modern EMV/JCOP cards are T=1 only and callers like
|
||||
// ExchangeAPDUSC() ask for T=0 unconditionally. Redirect only that case;
|
||||
// a card offering both keeps the caller's choice.
|
||||
if ((s_card_protocols != 0) &&
|
||||
((s_card_protocols & SC_PROTO_T0) == 0) &&
|
||||
((s_card_protocols & SC_PROTO_T1) == SC_PROTO_T1)) {
|
||||
|
||||
+11
-76
@@ -50,94 +50,29 @@
|
||||
// The SIM module v4 supports up to 384 bytes for the length.
|
||||
#define ISO7816_MAX_FRAME 270
|
||||
|
||||
/*
|
||||
* Bit banged bus timing.
|
||||
*
|
||||
* I2C_DELAY_1CLK is spent twice per bit and I2C_DELAY_2CLK once, so the bit
|
||||
* period is 2 * 1CLK + 2CLK. At 2/4 us that is ~125 kHz nominal; expect nearer
|
||||
* 90 kHz once SpinDelayUsPrecision()'s own overhead at these short durations is
|
||||
* counted.
|
||||
*
|
||||
* TODO DXL 修改了速度到比较慢的情况,测完需要改回来,原先是2和4
|
||||
*
|
||||
* ("the speed was changed to a slower setting; change it back after testing,
|
||||
* originally 2 and 4")
|
||||
*
|
||||
* That TODO belongs to the HAL refactoring for the Proxmark5 (Artery
|
||||
* AT32F435/437), where SpinDelayUsPrecision() is a different implementation
|
||||
* whose overhead at a two microsecond request has not been measured. The
|
||||
* 20/22 us it was raised to is kept for that platform rather than thrown away.
|
||||
*
|
||||
* Nothing depends on it yet: smartcard support is not built for PM5 - see the
|
||||
* "暂时不要编译i2c" note beside its PLATFORM_DEFS in common_arm/Makefile.hal -
|
||||
* so the AT32 branch below is an unvalidated starting point, not a measurement.
|
||||
* When that bring-up happens, measure the AT32 delay and set it here; every
|
||||
* timeout in this file is derived from these two numbers, so that is the only
|
||||
* place it needs to change.
|
||||
*/
|
||||
/*
|
||||
* 20/22 on both platforms for now.
|
||||
*
|
||||
* Dropping this to 2/4 was tried and the bus stopped working entirely - no ATR,
|
||||
* no answer to anything - even with the delay primitive's overshoot bug fixed
|
||||
* (see SpinDelayUsPrecision in common_arm/ticks/ticks_hw_at91.c). 8 us per bit
|
||||
* is about 125 kHz, and something in the path will not carry it: rise time
|
||||
* through the pull ups is the obvious candidate, but it was not measured.
|
||||
*
|
||||
* Worth revisiting with a scope on SCL and SDA rather than by trial. Every
|
||||
* timeout below is derived from these two numbers, so changing them is a
|
||||
* two line edit once someone knows what the bus can actually do.
|
||||
*/
|
||||
#define I2C_DELAY_1CLK_US 20
|
||||
#define I2C_DELAY_2CLK_US 22
|
||||
// Bit banged bus timing. 1CLK is spent twice per bit, 2CLK once, so the bit
|
||||
// period is 2 * 1CLK + 2CLK, here 17 us or about 59 kHz. Every timeout below
|
||||
// derives from these, so they are the only two numbers to change.
|
||||
#define I2C_DELAY_1CLK_US 5
|
||||
#define I2C_DELAY_2CLK_US 7
|
||||
|
||||
/*
|
||||
* Every SCL wait loop spends one I2C_DELAY_1CLK per iteration, so the timeouts
|
||||
* below are iteration counts rather than times - which is why changing the
|
||||
* delay used to silently rescale every one of them, and why the constants had
|
||||
* drifted to roughly 6.5x their documented length.
|
||||
*
|
||||
* They are written in milliseconds now and converted in one place, so the two
|
||||
* cannot come apart again. The conversion uses the nominal delay rather than a
|
||||
* measured one on purpose: with the real per-iteration cost being a little
|
||||
* higher, a timeout always lasts at least as long as it asks for.
|
||||
*/
|
||||
// The SCL wait loops spend one 1CLK per iteration, so their timeouts are
|
||||
// iteration counts. Written in ms and converted here so the two cannot drift.
|
||||
#define I2C_ITERS_PER_MS (1000U / I2C_DELAY_1CLK_US)
|
||||
#define I2C_ITERS_FOR_MS(ms) ((uint32_t)(ms) * (uint32_t)I2C_ITERS_PER_MS)
|
||||
|
||||
// How long the master tolerates the slave stretching SCL inside a transfer.
|
||||
#define I2C_STRETCH_TIMEOUT_MS 100
|
||||
|
||||
/*
|
||||
* How long to wait for the SIM module to finish an operation and release SCL.
|
||||
*
|
||||
* This has to cover the card's own thinking time. A T=1 card's block waiting
|
||||
* time is 1.4 s at the default BWI = 4, and a HID iCLASS SE SAM asks for
|
||||
* BWI = 5, i.e. 2.9 s - so 3 s is the smallest value that clears both.
|
||||
*/
|
||||
// Upper bound on a host supplied SC_WAIT, so the conversion cannot overflow.
|
||||
#define I2C_WAIT_MAX_MS 60000
|
||||
#define I2C_STRETCH_TIMEOUT_MS 100 // slave stretching SCL inside a transfer
|
||||
#define I2C_WAIT_MAX_MS 60000 // clamp on a host supplied SC_WAIT
|
||||
|
||||
// Must cover the card's block waiting time: 1.4 s at BWI=4, 2.9 s at BWI=5.
|
||||
#define SIM_WAIT_MS 3000
|
||||
#define SIM_WAIT_DELAY I2C_ITERS_FOR_MS(SIM_WAIT_MS)
|
||||
|
||||
/*
|
||||
* Compile time guards on the two numbers above. The build is -std=c99 so this
|
||||
* is the negative array size trick rather than _Static_assert.
|
||||
*/
|
||||
// -std=c99, so no _Static_assert
|
||||
#define I2C_BUILD_ASSERT(cond, name) typedef char i2c_assert_##name[(cond) ? 1 : -1]
|
||||
|
||||
// A delay that does not divide 1000 makes I2C_ITERS_PER_MS silently lose
|
||||
// precision, and every timeout with it.
|
||||
I2C_BUILD_ASSERT((1000U % I2C_DELAY_1CLK_US) == 0, clk_divides_ms);
|
||||
|
||||
// A T=1 card may sit quiet for its whole block waiting time before answering:
|
||||
// 1.4 s at the default BWI = 4, and 2.9 s at the BWI = 5 a HID iCLASS SE SAM
|
||||
// asks for. Shorten this and T=1 starts timing out on slow cards with nothing
|
||||
// to show for it but an empty response.
|
||||
I2C_BUILD_ASSERT(SIM_WAIT_MS >= 3000, sim_wait_covers_bwt);
|
||||
|
||||
// The largest host supplied wait must still fit the iteration counter.
|
||||
I2C_BUILD_ASSERT((uint64_t)I2C_WAIT_MAX_MS * I2C_ITERS_PER_MS <= 0xFFFFFFFFULL, wait_fits_u32);
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
9a3d623aa3c749ffb5125b6a4912f74e46902a9135441c427e1635be24d43c048e40e1f60a052175f383a1316c63dbddb999cac170a4224fe9a0d7df896391d4 *sim018.bin
|
||||
+24
-24
@@ -818,17 +818,10 @@ void annotateTopaz(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
|
||||
// iso 7816-3
|
||||
//
|
||||
// `contact` tells the two framings that reach this decoder apart:
|
||||
//
|
||||
// - contactless (ISO 14443-4 / T=CL): every frame is a block, its type is in
|
||||
// the first byte, and the length comes from the transport layer.
|
||||
// - contact (the SIM module): a T=0 frame is a bare APDU with no block layer
|
||||
// at all, and a T=1 frame is NAD PCB LEN INF[LEN] EDC, so its length is
|
||||
// fixed by LEN.
|
||||
//
|
||||
// Without that distinction a GSM APDU beginning with CLA 'A0' satisfies the
|
||||
// T=CL R-block test - 0xA0 & 0xD0 == 0x80 - and "A0 A4 00 00 02 3F 00" gets
|
||||
// annotated as "R-block ACK".
|
||||
// contact tells the two framings apart: a contactless frame is always a block
|
||||
// typed by its first byte, while a contact T=0 frame is a bare APDU and a T=1
|
||||
// frame is NAD PCB LEN INF EDC. Without it a GSM APDU starting with CLA 'A0'
|
||||
// matches the T=CL R-block test.
|
||||
void annotateIso7816(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response, bool contact) {
|
||||
|
||||
if (cmdsize < 2) {
|
||||
@@ -839,21 +832,29 @@ void annotateIso7816(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool
|
||||
return;
|
||||
}
|
||||
|
||||
// A contact frame is either a bare T=0 APDU or a T=1 block, and the two
|
||||
// framings put things in different places: T=1 is NAD PCB LEN INF[LEN] EDC,
|
||||
// so the block type is in cmd[1], not cmd[0] the way T=CL has it.
|
||||
//
|
||||
// Only the one byte LRC is considered when matching the length. A five
|
||||
// byte APDU whose P1 is zero - "A0 C0 00 00 22" - is indistinguishable from
|
||||
// a LEN=0 block with a two byte CRC, and CRC EDC is vanishingly rare.
|
||||
// Requiring NAD 0x00 rules out the rest; every card and this SIM module use
|
||||
// it exclusively.
|
||||
// T=1 puts the block type in cmd[1], not cmd[0] as T=CL does. Match only
|
||||
// the one byte LRC length - a five byte APDU with P1 zero is otherwise
|
||||
// indistinguishable from a LEN=0 block with a CRC. NAD must be 0x00.
|
||||
if (contact) {
|
||||
|
||||
if ((cmdsize >= 4) && (cmd[0] == 0x00) && ((int)cmdsize == (int)cmd[2] + 4)) {
|
||||
|
||||
uint8_t pcb = cmd[1];
|
||||
|
||||
// Length alone is not enough - "00 B2 01 0C 00" is a READ RECORD
|
||||
// that matches it. Require PCB and LEN to agree: an R-block carries
|
||||
// no INF, an S-block at most one byte.
|
||||
bool pcb_agrees = true;
|
||||
if ((pcb & 0xC0) == 0x80) {
|
||||
pcb_agrees = (cmd[2] == 0); /* R */
|
||||
} else if ((pcb & 0xC0) == 0xC0) {
|
||||
pcb_agrees = (cmd[2] <= 1); /* S */
|
||||
}
|
||||
|
||||
if (pcb_agrees == false) {
|
||||
goto not_a_block;
|
||||
}
|
||||
|
||||
if ((pcb & 0x80) == 0x00) {
|
||||
snprintf(exp, size, "I-block N(S)=%u%s", (pcb >> 6) & 1,
|
||||
(pcb & 0x20) ? " chained" : "");
|
||||
@@ -875,14 +876,13 @@ void annotateIso7816(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool
|
||||
}
|
||||
return;
|
||||
}
|
||||
// not a block, so it is a bare APDU - decoded below with pos = 1
|
||||
not_a_block:
|
||||
; // a bare APDU then - decoded below with pos = 1
|
||||
}
|
||||
|
||||
bool blocks = (contact == false);
|
||||
|
||||
// S-block. The test used to be a plain truthiness check on cmd[0] & 0xC0,
|
||||
// so any first byte from 0x40 up landed here - an R-block 0xA2 in a 3 byte
|
||||
// frame was reported as an S-block.
|
||||
// S-block
|
||||
if (blocks && ((cmd[0] & 0xC0) == 0xC0) && ((cmdsize == 3) || (cmdsize == 4))) {
|
||||
|
||||
switch ((cmd[0] & 0x3F)) {
|
||||
|
||||
+12
-40
@@ -327,18 +327,9 @@ static int smart_wait(uint8_t *out, int maxoutlen, bool verbose) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Which class byte a GET RESPONSE following a 61xx / 9Fxx should carry.
|
||||
//
|
||||
// There is no rule that can be derived from the command's own class, because
|
||||
// two cards that both use CLA 'A0' disagree:
|
||||
//
|
||||
// - a GSM 11.11 / TS 51.011 SIM answers 6D00 to '00 C0 ...' and needs 'A0 C0'
|
||||
// - a HID iCLASS SE SAM answers 6D00 to 'A0 C0 ...' and needs '00 C0'
|
||||
//
|
||||
// and EMV (Book 1, 9.3.1) fixes GET RESPONSE at '00' even after a proprietary
|
||||
// '80' command. So '00' is tried first - the historical behaviour, right for
|
||||
// EMV and for the SAM - and a card that rejects the class gets one retry with
|
||||
// the class of the command that produced the status word.
|
||||
// Class byte for a GET RESPONSE after 61xx / 9Fxx. No single rule works: a GSM
|
||||
// SIM needs 'A0 C0' and rejects '00 C0', a HID iCLASS SE SAM is the other way
|
||||
// round, and EMV fixes it at '00'. Try '00' first, then the command's own.
|
||||
#define GETRESP_TRY_FIRST 0
|
||||
#define GETRESP_TRY_RETRY 1
|
||||
|
||||
@@ -400,8 +391,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose, uint8_t c
|
||||
|
||||
if (verbose) PrintAndLogEx(INFO, "Requesting " _YELLOW_("0x%02X") " bytes response", len);
|
||||
|
||||
// '00' first, then one retry with the command's own class if the card
|
||||
// rejects it - see get_response_cla() for why neither works everywhere.
|
||||
// '00' first, then the command's own class if the card rejects it
|
||||
for (int attempt = GETRESP_TRY_FIRST; attempt <= GETRESP_TRY_RETRY; attempt++) {
|
||||
|
||||
uint8_t cmd_getresp[] = {
|
||||
@@ -442,20 +432,9 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose, uint8_t c
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two shapes are valid here, depending on how the GET RESPONSE went out:
|
||||
*
|
||||
* len + 2 the data and its status word. This is what SEND_T0
|
||||
* gives, because the module runs the procedure byte
|
||||
* exchange itself and strips the echoed INS.
|
||||
* len + 2 + 1 the same with that procedure byte still in front,
|
||||
* which is what the raw pass through leaves behind.
|
||||
*
|
||||
* Only the second needs unwrapping - but the first used to fall through
|
||||
* both branches without ever adding to totallen, so the caller got zero
|
||||
* bytes and reported "result length = 0" while the card had answered
|
||||
* perfectly. It went unnoticed while GET RESPONSE was always sent raw.
|
||||
*/
|
||||
// Two valid shapes: len+2 is data plus SW, which SEND_T0 gives since
|
||||
// the module strips the procedure byte; len+2+1 still has it in front,
|
||||
// as the raw pass through leaves it.
|
||||
if (datalen == len + 2) {
|
||||
totallen += datalen;
|
||||
} else {
|
||||
@@ -823,15 +802,14 @@ static int CmdSmartInfo(const char *Cmd) {
|
||||
SendCommandNG(CMD_SMART_ATR, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_SMART_ATR, &resp, 2500) == false) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(WARNING, "smart card timeout");
|
||||
}
|
||||
PrintAndLogEx(WARNING, "smart card timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "no ATR - check the card is present and seated");
|
||||
if (verbose) {
|
||||
PrintAndLogEx(WARNING, "smart card select failed");
|
||||
PrintAndLogEx(INFO, "module returned status %d", resp.status);
|
||||
}
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
@@ -1653,14 +1631,8 @@ int CmdSmartcard(const char *Cmd) {
|
||||
return CmdsParse(CommandTable, Cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Which protocol the contact exchanges below ask for.
|
||||
*
|
||||
* T=0 by default, which is what this has always sent. The ARM side already
|
||||
* redirects a T=0 request to T=1 when the card's ATR offers no T=0 at all - a
|
||||
* request that could not have worked as asked. This is for the other case: a
|
||||
* card that offers both, where T=0 would work but you want T=1 anyway.
|
||||
*/
|
||||
// Protocol the contact exchanges ask for. T=0 by default; the ARM redirects a
|
||||
// card offering no T=0 by itself, so this is for one that offers both.
|
||||
static smartcard_command_t s_sc_protocol = SC_RAW_T0;
|
||||
|
||||
void SetSmartcardProtocolT1(bool use_t1) {
|
||||
|
||||
+5
-25
@@ -575,16 +575,8 @@ static int emv_parse_card_details(uint8_t *response, size_t reslen, bool verbose
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve --t0 / --t1 for the contact interface.
|
||||
*
|
||||
* The ARM already switches a card whose ATR offers no T=0 over to T=1 by
|
||||
* itself, since a T=0 request to it could never have worked. This is for the
|
||||
* other case: a card offering both, where T=0 is a legitimate choice and the
|
||||
* caller wants T=1 anyway.
|
||||
*
|
||||
* Reports the problem and returns non-success if the flags make no sense.
|
||||
*/
|
||||
// Resolve --t0 / --t1 for the contact interface. The ARM switches a card
|
||||
// offering no T=0 over by itself; this is for one that offers both.
|
||||
static int emv_set_protocol(bool use_t0, bool use_t1, Iso7816CommandChannel channel) {
|
||||
|
||||
if (use_t0 && use_t1) {
|
||||
@@ -660,8 +652,6 @@ static int CmdEMVSelect(const char *Cmd) {
|
||||
if (sw == 0) {
|
||||
PrintAndLogEx(FAILED, "No answer from card ( %d )", res);
|
||||
if (channel == CC_CONTACT) {
|
||||
// Point the other way when T=1 was forced - suggesting the flag
|
||||
// that is already in use is worse than saying nothing.
|
||||
if (GetSmartcardProtocolT1()) {
|
||||
PrintAndLogEx(HINT, "Hint: card was driven as T=1, drop `" _YELLOW_("--t1") "` to use T=0");
|
||||
} else {
|
||||
@@ -2961,19 +2951,9 @@ static int CmdEMVReader(const char *Cmd) {
|
||||
const char *al = "Applets";
|
||||
struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
|
||||
|
||||
/*
|
||||
* Search the directory this channel expects first, then the other one.
|
||||
*
|
||||
* A contact card may carry either: 1PAY was the norm and 2PAY is what
|
||||
* modern cards use, and plenty carry only one of them. This used to
|
||||
* select 2PAY, throw the answer away, and then search whichever psenum
|
||||
* says - 1PAY on contact - so a card with only a PPSE fell through to
|
||||
* the AID list sweep with its directory already read and discarded.
|
||||
* The sweep then cannot find anything the built-in list does not carry,
|
||||
* which is most non-Visa/Mastercard applets.
|
||||
*
|
||||
* The first call activates the field; the fallback reuses it.
|
||||
*/
|
||||
// Search the expected directory then the other - a contact card may
|
||||
// carry 1PAY or 2PAY and plenty carry only one. First call activates
|
||||
// the field, the fallback reuses it.
|
||||
res = EMVSearchPSE(channel, true, true, psenum, false, tlvSelect, true);
|
||||
if (res) {
|
||||
res = EMVSearchPSE(channel, false, true, (psenum == 1) ? 2 : 1, false, tlvSelect, false);
|
||||
|
||||
@@ -475,6 +475,17 @@ int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFi
|
||||
}
|
||||
} else if (quiet == false) {
|
||||
PrintAndLogEx(ERR, "%s ERROR: Can't select PPSE AID. Error: %d", PSE_or_PPSE, res);
|
||||
|
||||
// an empty slot and a card that is simply not an EMV card both land
|
||||
// here, so ask the module which one it is
|
||||
if ((res < 0) && (channel == CC_CONTACT)) {
|
||||
smart_card_atr_t atr;
|
||||
if (smart_select(false, &atr)) {
|
||||
PrintAndLogEx(HINT, "Hint: card answered its ATR but not the APDU - is this an EMV card? try `" _YELLOW_("smart info") "`");
|
||||
} else {
|
||||
PrintAndLogEx(HINT, "Hint: no answer at all - is a card in the slot? try `" _YELLOW_("smart info") "`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!LeaveFieldON)
|
||||
@@ -503,12 +514,9 @@ int EMVSearch(Iso7816CommandChannel channel, bool ActivateField, bool LeaveField
|
||||
// retry if error and not returned sw error
|
||||
if (res && res != 5) {
|
||||
|
||||
// A negative result is a PM3_E* transport failure rather than
|
||||
// anything the card said - PM3_EIO when the field has gone
|
||||
// inactive, for instance. Retrying the same AID cannot fix that,
|
||||
// and neither can the ~150 AIDs still to come: without this it
|
||||
// retries each of them three times and prints a failure for every
|
||||
// attempt.
|
||||
// A negative result is a PM3_E* transport failure, not something
|
||||
// the card said. Retrying cannot fix it, nor can the ~150 AIDs
|
||||
// still to come.
|
||||
if (res < 0) {
|
||||
if (LeaveFieldON == false) {
|
||||
DropFieldEx(channel);
|
||||
|
||||
@@ -80,9 +80,11 @@ int Iso7816Connect(Iso7816CommandChannel channel) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on,
|
||||
sAPDU_t apdu, bool include_le, uint16_t le, uint8_t *result,
|
||||
size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||
// allow_le_retry gates the 6Cxx reissue below; the retry itself passes false
|
||||
static int iso7816_exchange_core(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on,
|
||||
sAPDU_t apdu, bool include_le, uint16_t le, uint8_t *result,
|
||||
size_t max_result_len, size_t *result_len, uint16_t *sw,
|
||||
bool allow_le_retry) {
|
||||
|
||||
*result_len = 0;
|
||||
if (sw) {
|
||||
@@ -178,6 +180,29 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool l
|
||||
*sw = isw;
|
||||
}
|
||||
|
||||
// 6Cxx is "wrong length, ask again for xx". Handled here rather than per
|
||||
// command since any case 2/4 APDU can get it - READ RECORD and GET DATA
|
||||
// both do. Once only; the card has named the length.
|
||||
if (allow_le_retry && ((isw >> 8) == 0x6C)) {
|
||||
|
||||
if (APDULogging) {
|
||||
PrintAndLogEx(INFO, ">>> wrong length, reissuing with Le=%02X...", isw & 0xFF);
|
||||
}
|
||||
|
||||
return iso7816_exchange_core(channel
|
||||
, false
|
||||
, leave_field_on
|
||||
, apdu
|
||||
, true
|
||||
, (uint16_t)(isw & 0xFF)
|
||||
, result
|
||||
, max_result_len
|
||||
, result_len
|
||||
, sw
|
||||
, false
|
||||
);
|
||||
}
|
||||
|
||||
if (isw != ISO7816_OK) {
|
||||
if (APDULogging) {
|
||||
if (*sw >> 8 == 0x61) {
|
||||
@@ -191,6 +216,14 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool l
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on,
|
||||
sAPDU_t apdu, bool include_le, uint16_t le, uint8_t *result,
|
||||
size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||
|
||||
return iso7816_exchange_core(channel, activate_field, leave_field_on, apdu, include_le, le,
|
||||
result, max_result_len, result_len, sw, true);
|
||||
}
|
||||
|
||||
int Iso7816Exchange(Iso7816CommandChannel channel, bool leave_field_on, sAPDU_t apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||
return Iso7816ExchangeEx(channel
|
||||
, false
|
||||
@@ -220,22 +253,10 @@ int Iso7816Select(Iso7816CommandChannel channel, bool activate_field, bool leave
|
||||
, sw
|
||||
);
|
||||
|
||||
/*
|
||||
* A contact card running T=1 needs the Le that a T=0 card must not be
|
||||
* given. T=0 answers a case 4 command with 61xx and hands the data over
|
||||
* through GET RESPONSE, so the Le is left off; T=1 carries the whole APDU
|
||||
* in one block and has no such step, so the command has to ask for its
|
||||
* length up front. Send one without and a strict card answers 6700.
|
||||
*
|
||||
* Rather than work out which protocol the link ended up on - the ARM may
|
||||
* have switched to T=1 on its own, off the ATR, without the client being
|
||||
* told - let the card say so and reissue. EMVReadRecord() and
|
||||
* EMVGenerateChallenge() already do the mirror image of this.
|
||||
*
|
||||
* Only on 6700/6F00, and only on contact: a T=0 card has no reason to
|
||||
* answer a SELECT that way, and if one did the retry costs a single extra
|
||||
* APDU that it will reject just as it rejected the first.
|
||||
*/
|
||||
// T=1 carries the whole APDU in one block, so a case 4 command must include
|
||||
// Le - unlike T=0, which answers 61xx and hands the data over via GET
|
||||
// RESPONSE. A strict card answers 6700 without it. Reissue rather than work
|
||||
// out which protocol the link ended up on.
|
||||
if ((channel == CC_CONTACT) && (sw != NULL) && ((*sw == 0x6700) || (*sw == 0x6F00))) {
|
||||
|
||||
if (APDULogging) {
|
||||
|
||||
Reference in New Issue
Block a user