diff --git a/CHANGELOG.md b/CHANGELOG.md index 327ac9f61..0764ec252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,18 +3,21 @@ 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] - - Change `hf 14a/14b/15 list etc alias commands now unified helptext (@doegox) - - Change `trace list` - now colors whole reader line (@iceman1001) - - Change `lf search` - add option `-c` to continue searching after first hit (@doegox) + - Changed calypso scripts to work with NG (@iceman1001) + - Changed HF 14b - fixed timings on device side (@iceman1001) + - Changed `hf 14b raw` - now uses NG (@iceman1001) + - Changed `hf 14a/14b/15 list etc alias commands now unified helptext (@doegox) + - Changed `trace list` - now colors whole reader line (@iceman1001) + - Changed `lf search` - add option `-c` to continue searching after first hit (@doegox) - Fix DESFire mis-annotation (@VortixDev) - - Change `lf pac demod` - now also search for inverted bitstreams (@iceman1001) - - Change `hf 14b reader` - now supports continous mode (@iceman1001) + - Changed `lf pac demod` - now also search for inverted bitstreams (@iceman1001) + - Changed `hf 14b reader` - now supports continous mode (@iceman1001) - Fix `hf search` - now doesn't false identify ISO15693 (@iceman1001) - - Change emv commands now works with tokenized cards (@merlokk) - - Change `hf 15 restore` - now also support EML/JSON (@iceman1001) - - Change - all commands now use cliparser (@iceman1001) - - Change `lf t55xx restore` - now also support JSON (@iceman1001) - - Change `hf mf csetuid` - adapted to accept 7byte uids ~untested~ (@iceman1001) + - Changed emv commands now works with tokenized cards (@merlokk) + - Changed `hf 15 restore` - now also support EML/JSON (@iceman1001) + - Changed - all commands now use cliparser (@iceman1001) + - Changed `lf t55xx restore` - now also support JSON (@iceman1001) + - Changed `hf mf csetuid` - adapted to accept 7byte uids ~untested~ (@iceman1001) - Added `hf mf view/eload/cload` - now accepts bin/eml/json (@iceman1001) - Added `hf mf eload/cload' - now accepts bin/eml/json (@iceman1001) - Fix RESTORE mis-annotation (@VortixDev) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 0b4051505..27f27fc31 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -24,78 +24,183 @@ #include "commonutil.h" #include "dbprint.h" #include "ticks.h" +#include "iso14b.h" // defines for ETU conversions - -// Delays in SSP_CLK ticks. -// SSP_CLK runs at 13,56MHz / 32 = 423.75kHz when simulating a tag -#define DELAY_READER_TO_ARM 8 -#define DELAY_ARM_TO_READER 0 - -//SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when acting as reader. All values should be multiples of 16 -#define DELAY_ARM_TO_TAG 16 -#define DELAY_TAG_TO_ARM 32 - -//SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when sniffing. All values should be multiples of 16 -#define DELAY_TAG_TO_ARM_SNIFF 32 -#define DELAY_READER_TO_ARM_SNIFF 32 - -// defaults to 2000ms -#ifndef FWT_TIMEOUT_14B -# define FWT_TIMEOUT_14B 35312U -#endif - -// 1 tick == 1/13.56 mhz -// 1 us = 1.5 tick - -// 330/848kHz = 1558us / 4 == 400us, -#define ISO14443B_READER_TIMEOUT 10000 //330 - -// 1024/3.39MHz = 302.1us between end of tag response and next reader cmd -#define DELAY_ISO14443B_VICC_TO_VCD_READER (28*9) // 1024 ( counting from start of PICC EOF 14 ETU's) -#define DELAY_ISO14443B_VCD_TO_VICC_READER (28*9) // 1056 +/* +* Current timing issues with ISO14443-b implementation +* Proxmark3 +* Carrier Frequency 13.56MHz +* SSP_CLK runs at 13.56MHz / 4 = 3,39MHz +* +* +* PROBLEM 1. +* ---------- +* one way of calculating time, that relates both to PM3 ssp_clk 3.39MHz, ISO freq of 13.56Mhz and ETUs +* convert from µS -> our SSP_CLK units which is used in the DEFINES.. +* convert from ms -> our SSP_CLK units... +* convert from ETU -> our SSP_CLK units... +* All ETU -> µS -> ms should be diveded by for to match Proxmark3 FPGA SSP_CLK :) +* +* +* PROBLEM 2. +* ---------- +* all DEFINES is in SSP_CLK ticks +* all delays is in SSP_CLK ticks +*/ #ifndef RECEIVE_MASK # define RECEIVE_MASK (DMA_BUFFER_SIZE - 1) #endif -// Guard Time (per 14443-2) -#ifndef TR0 -# define TR0 32 // TR0 max is 151/fs = 151/(848kHz) = 302us or 64 samples from FPGA +// SSP_CLK runs at 13,56MHz / 32 = 423.75kHz when simulating a tag +// All values should be multiples of 2 (?) +#define DELAY_READER_TO_ARM 8 +#define DELAY_ARM_TO_READER 0 + +// SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when acting as reader. +// All values should be multiples of 16 +#define DELAY_ARM_TO_TAG 16 +#define DELAY_TAG_TO_ARM 32 + +// SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when sniffing. +// All values should be multiples of 16 +#define DELAY_TAG_TO_ARM_SNIFF 32 +#define DELAY_READER_TO_ARM_SNIFF 32 + +/* ISO14443-4 +* +* Frame Waiting Time Integer (FWI) +* can be between 0 and 14. +* FWI_default = 4 +* FWI_max = 14 +* +* Frame Waiting Time (FWT) formula +* -------------------------------- +* FWT = (256 x 16 / fc) * 2 to the power for FWI +* +* sample: +* ------- 2 to the power of FWI(4) +* FWT = (256 x 16 / fc) * (2*2*2*2) == 4.833 ms + +* FTW(default) == FWT(4) == 4.822ms +* +* FWI_max == 2^14 = 16384 +* FWT(max) = (256 x 16 / fc) * 16384 == 4949 +* +* Which gives a maximum Frame Waiting time of FWT(max) == 4949 ms +* FWT(max) in ETU 4949000 / 9.4395 µS = 524286 ETU +* +* Simple calc to convert to ETU or µS +* ----------------------------------- +* uint32_t fwt_time_etu = (32 << fwt); +* uint32_t fwt_time_us = (302 << fwt); +* +*/ + +#ifndef MAX_14B_TIMEOUT +// FWT(max) = 4949 ms or 4.95 seconds. +// SSP_CLK = 4949000 * 3.39 = 16777120 +# define MAX_14B_TIMEOUT (16777120U) #endif -// Synchronization time (per 14443-2) -#ifndef TR1 -# define TR1 0 +// Activation frame waiting time +// 512 ETU? +// 65536/fc == 4833 µS or 4.833ms +// SSP_CLK = 4833 µS * 3.39 = 16384 +#ifndef FWT_TIMEOUT_14B +# define FWT_TIMEOUT_14B (16384) +#endif + +// ETU 14 * 9.4395 µS = 132 µS == 0.132ms +// TR2, counting from start of PICC EOF 14 ETU. +#define DELAY_ISO14443B_PICC_TO_PCD_READER ETU_TO_SSP(14) +#define DELAY_ISO14443B_PCD_TO_PICC_READER ETU_TO_SSP(15) + +/* Guard Time (per 14443-2) in ETU +* +* Transition time. TR0 - guard time +* TR0 - 8 ETU's minimum. +* TR0 - 32 ETU's maximum for ATQB only +* TR0 - FWT for all other commands +* 32,64,128,256,512, ... , 262144, 524288 ETU +* TR0 = FWT(1), FWT(2), FWT(3) .. FWT(14) +* +* +* TR0 +*/ +#ifndef ISO14B_TR0 +# define ISO14B_TR0 ETU_TO_SSP(32) #endif -// Frame Delay Time PICC to PCD (per 14443-3 Amendment 1) -#ifndef TR2 -# define TR2 0 + +#ifndef ISO14B_TR0_MAX +# define ISO14B_TR0_MAX ETU_TO_SSP(32) +// * TR0 - 32 ETU's maximum for ATQB only +// * TR0 - FWT for all other commands + +// TR0 max is 151/fsc = 151/848kHz = 302us or 64 samples from FPGA +// 32 ETU * 9.4395 µS == 302 µS +// 32 * 8 = 256 sub carrier cycles, +// 256 / 4 = 64 I/Q pairs. +// since 1 I/Q pair after 4 subcarrier cycles at 848kHz subcarrier +#endif + +// 8 ETU = 75 µS == 256 SSP_CLK +#ifndef ISO14B_TR0_MIN +# define ISO14B_TR0_MIN ETU_TO_SSP(8) +#endif + +// Synchronization time (per 14443-2) in ETU +// 10 ETU = 94,39 µS == 320 SSP_CLK +#ifndef ISO14B_TR1_MIN +# define ISO14B_TR1_MIN ETU_TO_SSP(10) +#endif +// Synchronization time (per 14443-2) in ETU +// 25 ETU == 236 µS == 800 SSP_CLK +#ifndef ISO14B_TR1_MAX +# define ISO14B_TR1 ETU_TO_SSP(25) +#endif + +// Frame Delay Time PICC to PCD (per 14443-3 Amendment 1) in ETU +// 14 ETU == 132 µS == 448 SSP_CLK +#ifndef ISO14B_TR2 +# define ISO14B_TR2 ETU_TO_SSP(14) #endif // 4sample #define SEND4STUFFBIT(x) tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x); -static void iso14b_set_timeout(uint32_t timeout); +static void iso14b_set_timeout(uint32_t timeout_etu); static void iso14b_set_maxframesize(uint16_t size); +static void iso14b_set_fwt(uint8_t fwt); // the block number for the ISO14443-4 PCB (used with APDUs) static uint8_t iso14b_pcb_blocknum = 0; +static uint8_t iso14b_fwt = 9; static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; -/* ISO 14443 B -* +/* +* ISO 14443-B communications +* -------------------------- * Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig) * Card to reader | BPSK - Binary Phase Shift Keying Modulation, (PICC to PCD for Type B) * +* It uses half duplex with a 106 kbit per second data rate in each direction. +* Data transmitted by the card is load modulated with a 847.5 kHz subcarrier. +* * fc - carrier frequency 13.56 MHz * TR0 - Guard Time per 14443-2 * TR1 - Synchronization Time per 14443-2 * TR2 - PICC to PCD Frame Delay Time (per 14443-3 Amendment 1) * -* Elementary Time Unit (ETU) is -* - 128 Carrier Cycles (9.4395 µS) = 8 Subcarrier Units - +* Elementary Time Unit (ETU) +* -------------------------- +* ETU is used to denotate 1 bit period i.e. how long one bit transfer takes. +* +* - 128 Carrier cycles / 13.56MHz = 8 Subcarrier units / 848kHz = 1/106kHz = 9.4395 µS +* - 16 Carrier cycles = 1 Subcarrier unit = 1.17 µS +* * Definition +* ---------- * 1 ETU = 128 / ( D x fc ) * where * D = divisor. Which inital is 1 @@ -104,13 +209,26 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; * 1 ETU = 128 / fc * 1 ETU = 128 / 13 560 000 = 9.4395 µS * 1 ETU = 9.4395 µS - -* It seems we are using the subcarrier as base for our time calculations, -* rather than the field clock - -* - 1 ETU = 8 subcarrier units -* - 1 ETU = 1 bit -* - 10 ETU = 1 startbit, 8 databits, 1 stopbit (10bits length) +* +* (note: It seems we are using the subcarrier as base for our time calculations rather than the field clock) +* +* - 1 ETU = 1/106 KHz +* - 1 ETU = 8 subcarrier units ( 8 / 848kHz ) +* - 1 ETU = 1 bit period +* +* +* Card sends data at 848kHz subcarrier +* subcar |duration| FC division| I/Q pairs +* -------+--------+------------+-------- +* 106kHz | 9.44µS | FC/128 | 16 +* 212kHz | 4.72µS | FC/64 | 8 +* 424kHz | 2.36µS | FC/32 | 4 +* 848kHz | 1.18µS | FC/16 | 2 +* -------+--------+------------+-------- +* +* +* One Character consists of 1 start, 1 stop, 8 databit with a total length of 10bits. +* - 1 Character = 10 ETU = 1 startbit, 8 databits, 1 stopbit * - startbit is a 0 * - stopbit is a 1 * @@ -121,52 +239,82 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; * End of frame (EOF) is * - [10-11] ETU of ZEROS, unmodulated time * -* -TO VERIFY THIS BELOW- -* The mode FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK which we use to simulate tag -* works like this: -* - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (1.18µS / pulse) == 9.44us -* - A 0-bit input to the FPGA becomes an unmodulated time of 1.18µS or does it become 8 nonpulses for 9.44us -* -* FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead. -* -* Card sends data ub 847.e kHz subcarrier -* subcar |duration| FC division| I/Q pairs -* -------+--------+------------+-------- -* 106kHz | 9.44µS | FC/128 | 16 -* 212kHz | 4.72µS | FC/64 | 8 -* 424kHz | 2.36µS | FC/32 | 4 -* 848kHz | 1.18µS | FC/16 | 2 -* -------+--------+------------+-------- -* -* Reader data transmission: +* Reader data transmission +* ------------------------ * - no modulation ONES * - SOF -* - Command, data and CRC_B +* - Command, data and CRC_B (1 Character) * - EOF * - no modulation ONES * -* Card data transmission +* Card data transmission +* ---------------------- * - TR1 * - SOF -* - data (each bytes is: 1startbit, 8bits, 1stopbit) +* - data (1 Character) * - CRC_B * - EOF * -* FPGA implementation : -* At this point only Type A is implemented. This means that we are using a -* bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make -* things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) +* Transfer times +* -------------- +* let calc how long it takes the reader to send a message +* SOF 10 ETU + 4 data bytes + 2 crc bytes + EOF 2 ETU +* 10 + (4+2 * 10) + 2 = 72 ETU +* 72 * 9.4395 = 680 µS or 0.68 ms +* * +* -> TO VERIFY THIS BELOW <- +* -------------------------- +* The mode FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK which we use to simulate tag +* works like this: +* Simulation per definition is "inversed" effect on the reader antenna. +* - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (1.18µS / pulse) == 9.44us +* - A 0-bit input to the FPGA becomes an unmodulated time of 1.18µS or does it become 8 nonpulses for 9.44us +* +* +* FPGA implementation +* ------------------- +* Piwi implemented a I/Q sampling mode for the FPGA, where... +* +* FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead. +* +* This means that we are using a bit rate of 106 kbit/s, or fc/128. +* Oversample by 4, which ought to make things practical for the ARM +* (fc/32, 423.8 kbits/s, ~52 kbytes/s) +* +* We are sampling the signal at FC/32, we are reporting over SSP to PM3 each +* +* Current I/Q pair sampling +* ------------------------- * Let us report a correlation every 64 samples. I.e. -* 1 I/Q pair after 4 subcarrier cycles for the 848kHz subcarrier, -* 1 I/Q pair after 2 subcarrier cycles for the 424kHz subcarrier, -* 1 I/Q pair for each subcarrier cyle for the 212kHz subcarrier. - -* 2 I/Q pairs for 1 ETU when 848kHz -* 4 I/Q pairs for 1 ETU when 424kHz -* 8 I/Q pairs for 1 ETU when 212kHz +* 1 I/Q pair after 4 subcarrier cycles for the 848kHz subcarrier, +* 1 I/Q pair after 2 subcarrier cycles for the 424kHz subcarrier, */ + +/* +* Formula to calculate FWT (in ETUs) by timeout (in ms): +* +* 1 tick is about 1.5µS +* 1000 ms/s +* +* FWT = 13560000 * 1000 / (8*16) * timeout +* FWT = 13560000 * 1000 / 128 * timeout +* +* sample: 3sec == 3000ms +* +* 13560000 * 1000 / 128 * 3000 == 13560000000 / 384000 == +* 13560000 / 384 = 35312 FWT +* +* 35312 * 9.4395 == +* +* @param timeout is in frame wait time, fwt, measured in ETUs +* +* However we need to compensate for SSP_CLK ... +*/ + + + //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using // a UART kind of thing that's implemented in software. When we get a @@ -237,10 +385,10 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { SEND4STUFFBIT(0); } - // why this? - for (i = 0; i < 2; i++) { - SEND4STUFFBIT(1); - } + // why this? push out transfers between arm and fpga? + //for (i = 0; i < 2; i++) { + // SEND4STUFFBIT(1); + //} tosend_t *ts = get_tosend(); // Convert from last byte pos to length @@ -280,6 +428,34 @@ static void Uart14bInit(uint8_t *data) { Uart14bReset(); } +// param timeout accepts ETU +static void iso14b_set_timeout(uint32_t timeout_etu) { + + uint32_t ssp = ETU_TO_SSP(timeout_etu); + + if (ssp > MAX_14B_TIMEOUT) + ssp = MAX_14B_TIMEOUT; + + iso14b_timeout = ssp; + if (DBGLEVEL >= DBG_DEBUG) { + Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout); + } +} + +// keep track of FWT, also updates the timeout +static void iso14b_set_fwt(uint8_t fwt) { + iso14b_fwt = fwt; + iso14b_set_timeout( 32 << fwt ); +} + +static void iso14b_set_maxframesize(uint16_t size) { + if (size > 256) + size = MAX_FRAME_SIZE; + + Uart.byteCntMax = size; + if (DBGLEVEL >= DBG_DEBUG) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax); +} + //----------------------------------------------------------------------------- // The software Demod that receives commands from the tag, and its state variables. //----------------------------------------------------------------------------- @@ -324,36 +500,6 @@ static void Demod14bInit(uint8_t *data, uint16_t max_len) { Demod14bReset(); } -/* -* 9.4395 us = 1 ETU and clock is about 1.5 us -* 13560000Hz -* 1000ms/s -* timeout in ETUs (time to transfer 1 bit, 9.4395 us) -* -* Formula to calculate FWT (in ETUs) by timeout (in ms): -* fwt = 13560000 * 1000 / (8*16) * timeout; -* Sample: 3sec == 3000ms -* 13560000 * 1000 / (8*16) * 3000 == -* 13560000000 / 384000 = 35312 FWT -* @param timeout is in frame wait time, fwt, measured in ETUs -*/ -static void iso14b_set_timeout(uint32_t timeout) { -#define MAX_TIMEOUT 40542464U // 13560000Hz * 1000ms / (2^32-1) * (8*16) - if (timeout > MAX_TIMEOUT) - timeout = MAX_TIMEOUT; - - iso14b_timeout = timeout; - if (DBGLEVEL >= DBG_DEBUG) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout); -} - -static void iso14b_set_maxframesize(uint16_t size) { - if (size > 256) - size = MAX_FRAME_SIZE; - - Uart.byteCntMax = size; - if (DBGLEVEL >= DBG_DEBUG) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax); -} - /* Receive & handle a bit coming from the reader. * * This function is called 4 times per bit (every 2 subcarrier cycles). @@ -523,7 +669,6 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { return false; } - static void TransmitFor14443b_AsTag(uint8_t *response, uint16_t len) { // Signal field is off with the appropriate LED @@ -1148,9 +1293,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) { /* * Demodulate the samples we received from the tag, also log to tracebuffer */ -static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeout, uint32_t *eof_time) { - - int samples = 0, ret = 0; +static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t timeout, uint32_t *eof_time) { // Set up the demodulator for tag -> reader responses. Demod14bInit(response, max_len); @@ -1167,6 +1310,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo uint32_t dma_start_time = 0; uint16_t *upTo = dma->buf; + int samples = 0, ret = 0; // Put FPGA in the appropriate mode FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); @@ -1218,7 +1362,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo if (Handle14443bSamplesFromTag(ci, cq)) { - *eof_time = GetCountSspClkDelta(dma_start_time) - (DELAY_TAG_TO_ARM * 128); // end of EOF + *eof_time = GetCountSspClkDelta(dma_start_time) - DELAY_TAG_TO_ARM; // end of EOF if (Demod.len > Demod.max_len) { ret = -2; // overflow @@ -1226,7 +1370,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo break; } - if (((GetCountSspClkDelta(dma_start_time) >> 7) > timeout) && Demod.state < DEMOD_PHASE_REF_TRAINING) { + if (((GetCountSspClkDelta(dma_start_time) ) > timeout) && Demod.state < DEMOD_PHASE_REF_TRAINING) { ret = -1; break; } @@ -1240,8 +1384,9 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo if (Demod.len > 0) { uint32_t sof_time = *eof_time - (Demod.len * (8 + 2)) // time for byte transfers - - (12) // time for SOF transfer - - (12); // time for EOF transfer + - (10) // time for TR1 + - (10 + 2) // time for SOF transfer + - (10); // time for EOF transfer LogTrace(Demod.output, Demod.len, sof_time, *eof_time, NULL, false); } return Demod.len; @@ -1250,18 +1395,22 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo //----------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. //----------------------------------------------------------------------------- +// param start_time in SSP_CLK static void TransmitFor14443b_AsReader(uint32_t *start_time) { tosend_t *ts = get_tosend(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); + // TR2 minimum 14 ETUs - if (*start_time < DELAY_ARM_TO_TAG) { - *start_time = DELAY_ARM_TO_TAG; + if (*start_time < ISO14B_TR0) { +// *start_time = DELAY_ARM_TO_TAG; + *start_time = ISO14B_TR0; } - *start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0; +// *start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0; + *start_time = (*start_time & 0xfffffff0); if (GetCountSspClk() > *start_time) { // we may miss the intended time *start_time = (GetCountSspClk() + 32) & 0xfffffff0; // next possible time @@ -1301,18 +1450,6 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { //----------------------------------------------------------------------------- static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { /* - * Reader data transmission: - * - no modulation ONES - * - SOF - * - Command, data and CRC_B - * - EOF - * - no modulation ONES - * - * 1 ETU == 1 BIT! - * TR0 - 8 ETU's minimum. - * TR0 - 32 ETU's maximum for ATQB only - * TR0 - FWT for all other commands - * * QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode? * 1 "stuffbit" = 1ETU (9us) * @@ -1326,7 +1463,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { // Send SOF // 10-11 ETUs of ZERO - for (i = 0; i < 11; i++) { + for (i = 0; i < 10; i++) { tosend_stuffbit(0); } // 2-3 ETUs of ONE @@ -1359,20 +1496,15 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { // Send EOF // 10-11 ETUs of ZERO - for (i = 0; i < 11; i++) { + for (i = 0; i < 10; i++) { tosend_stuffbit(0); } - /* Transition time. TR0 - guard time - * TR0 - 8 ETU's minimum. - * TR0 - 32 ETU's maximum for ATQB only - * TR0 - FWT for all other commands - * 32,64,128,256,512, ... , 262144, 524288 ETU - */ - int pad = (11 + 2 + (len * 10) + 11) & 0x7; + int pad = (10 + 2 + (len * 10) + 10) & 0x7; for (i = 0; i < 16 - pad; ++i) tosend_stuffbit(1); + } /* @@ -1416,7 +1548,7 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time); FpgaDisableTracing(); @@ -1427,12 +1559,22 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void } else { // S-Block WTX while (len && ((data_bytes[0] & 0xF2) == 0xF2)) { - uint32_t save_iso14b_timeout = iso14b_timeout; + + uint32_t save_iso14b_timeout_spp = iso14b_timeout; + + // 2 high bits mandatory set to 0b + // byte1 - WTXM [1..59]. + uint8_t wtxm = data_bytes[1] & 0x3F; + + // command FWT = FWT * WTXM + uint32_t fwt_temp = iso14b_fwt * wtxm; + // temporarily increase timeout - iso14b_set_timeout(MAX((data_bytes[1] & 0x3f) * save_iso14b_timeout, ISO14443B_READER_TIMEOUT)); + iso14b_set_timeout( (32 << fwt_temp)); + // Transmit WTX back - // byte1 - WTXM [1..59]. command FWT = FWT * WTXM - data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b + data_bytes[1] = wtxm; + // now need to fix CRC. AddCrc14B(data_bytes, len - 2); @@ -1440,13 +1582,14 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void CodeAndTransmit14443bAsReader(data_bytes, len, &start_time, &eof_time); // retrieve the result again (with increased timeout) - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time); FpgaDisableTracing(); data_bytes = rxdata; + // restore timeout - iso14b_set_timeout(save_iso14b_timeout); + iso14b_timeout = save_iso14b_timeout_spp; } // if we received an I- or R(ACK)-Block with a block number equal to the @@ -1497,10 +1640,12 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(cmdINIT, sizeof(cmdINIT), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - int retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + int retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); FpgaDisableTracing(); + Dbprintf("cts : s %u e %u", start_time, eof_time); + if (retlen != 4) { return -1; } @@ -1514,11 +1659,11 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { card->fc = r[1]; } - start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER; + start_time = eof_time + ISO14B_TR2; CodeAndTransmit14443bAsReader(cmdMSBUID, sizeof(cmdMSBUID), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); FpgaDisableTracing(); if (retlen != 4) { @@ -1532,11 +1677,11 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { memcpy(card->uid, r, 2); } - start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER; + start_time = eof_time + ISO14B_TR2; CodeAndTransmit14443bAsReader(cmdLSBUID, sizeof(cmdLSBUID), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); FpgaDisableTracing(); if (retlen != 4) { @@ -1566,10 +1711,11 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), iso14b_timeout, &eof_time); FpgaDisableTracing(); + Dbprintf("srx : s %u e %u", start_time, eof_time); if (retlen <= 0) { return -1; } @@ -1585,17 +1731,17 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { AddCrc14B(select_srx, 2); - start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER; + start_time = eof_time + ISO14B_TR2; CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - retlen = Get14443bAnswerFromTag(r_select, sizeof(r_select), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(r_select, sizeof(r_select), iso14b_timeout, &eof_time); FpgaDisableTracing(); if (retlen != 3) { return -1; } - if (!check_crc(CRC_14443_B, r_select, retlen)) { + if (check_crc(CRC_14443_B, r_select, retlen) == false) { return -2; } @@ -1609,11 +1755,11 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { AddCrc14B(select_srx, 1); - start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER; + start_time = eof_time + ISO14B_TR2; CodeAndTransmit14443bAsReader(select_srx, 3, &start_time, &eof_time); // Only first three bytes for this one - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - retlen = Get14443bAnswerFromTag(r_papid, sizeof(r_papid), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(r_papid, sizeof(r_papid), iso14b_timeout, &eof_time); FpgaDisableTracing(); if (retlen != 10) { @@ -1654,8 +1800,8 @@ int iso14443b_select_card(iso14b_card_select_t *card) { uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(wupb, sizeof(wupb), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;; - int retlen = Get14443bAnswerFromTag(r_pupid, sizeof(r_pupid), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + int retlen = Get14443bAnswerFromTag(r_pupid, sizeof(r_pupid), iso14b_timeout, &eof_time); FpgaDisableTracing(); // ATQB too short? @@ -1664,7 +1810,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) { } // VALIDATE CRC - if (!check_crc(CRC_14443_B, r_pupid, retlen)) { + if (check_crc(CRC_14443_B, r_pupid, retlen) == false) { return -2; } @@ -1680,11 +1826,11 @@ int iso14443b_select_card(iso14b_card_select_t *card) { // copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into ATTRIB (Param 3) attrib[7] = r_pupid[10] & 0x0F; AddCrc14B(attrib, 9); - start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER; + start_time = eof_time + ISO14B_TR2; CodeAndTransmit14443bAsReader(attrib, sizeof(attrib), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - retlen = Get14443bAnswerFromTag(r_attrib, sizeof(r_attrib), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(r_attrib, sizeof(r_attrib), iso14b_timeout, &eof_time); FpgaDisableTracing(); // Answer to ATTRIB too short? @@ -1693,7 +1839,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) { } // VALIDATE CRC - if (!check_crc(CRC_14443_B, r_attrib, retlen)) { + if (check_crc(CRC_14443_B, r_attrib, retlen) == false) { return -2; } @@ -1714,9 +1860,8 @@ int iso14443b_select_card(iso14b_card_select_t *card) { // FWT uint8_t fwt = card->atqb[6] >> 4; - if (fwt < 16) { - uint32_t fwt_time = (302 << fwt); - iso14b_set_timeout(fwt_time); + if (fwt < 15) { + iso14b_set_fwt(fwt); } } // reset PCB block number @@ -1751,6 +1896,9 @@ void iso14443b_setup(void) { // Start the timer StartCountSspClk(); + // reset timeout + iso14b_set_fwt(9); + LED_D_ON(); } @@ -1774,8 +1922,8 @@ static int read_srx_block(uint8_t blocknr, uint8_t *block) { uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(cmd, sizeof(cmd), &start_time, &eof_time); - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - int retlen = Get14443bAnswerFromTag(r_block, sizeof(r_block), ISO14443B_READER_TIMEOUT, &eof_time); + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + int retlen = Get14443bAnswerFromTag(r_block, sizeof(r_block), iso14b_timeout, &eof_time); FpgaDisableTracing(); // Check if we got an answer from the tag @@ -2027,31 +2175,11 @@ static void iso14b_set_trigger(bool enable) { g_trigger = enable; } -/* - * Send raw command to tag ISO14443B - * @Input - * param flags enum ISO14B_COMMAND. (mifare.h) - * len len of buffer data - * data buffer with bytes to send - * - * @Output - * none - * - */ void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *o) { - /* - iso14b_command_t param = c->oldarg[0]; - size_t len = o->oldarg[1] & 0xffff; - uint32_t timeout = o->oldarg[2]; - uint8_t *cmd = o->data.asBytes; - */ - // receive buffer uint8_t buf[PM3_CMD_DATA_SIZE]; memset(buf, 0 , sizeof(buf)); - - if (DBGLEVEL > DBG_DEBUG) { Dbprintf("14b raw: param, %04x", o->flags); } @@ -2123,8 +2251,8 @@ void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *o) { FpgaDisableTracing(); reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0); } else { - eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER; - status = Get14443bAnswerFromTag(buf, sizeof(buf), 5 * ISO14443B_READER_TIMEOUT, &eof_time); // raw + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + status = Get14443bAnswerFromTag(buf, sizeof(buf), iso14b_timeout, &eof_time); // raw FpgaDisableTracing(); sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE); diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index dbbc3b131..d10a32cfe 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -181,7 +181,6 @@ function Command:sendNG( ignore_response, timeout ) count, data, ng = bin.unpack('H'..length..'C', response, count) --[[ uncomment if you want to debug - print('NG package received') print('CMD ::', tostring(cmd)) print('Length ::', tostring(length)) diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index 88bba22cd..1fb978caa 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -15,7 +15,7 @@ local cmds = require('commands') local utils = require('utils') -- Shouldn't take longer than 2.5 seconds -local TIMEOUT = 2000 +local TIMEOUT = 1000 local ISO14B_COMMAND = { ISO14B_CONNECT = 0x1, @@ -34,7 +34,6 @@ local ISO14B_COMMAND = { local function parse14443b(data) --[[ - Based on this struct : typedef struct { @@ -44,10 +43,15 @@ local function parse14443b(data) uint8_t chipid; uint8_t cid; } PACKED iso14b_card_select_t; - +--- local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data) --]] - local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data) + local uid = data:sub(1, 20) + local uidlen = data:sub(21, 22) + local atqb = data:sub(23, 36) + local chipid = data:sub(37, 38) + local cid = data:sub(39, 40) + uid = uid:sub(1, 2 * uidlen) return { uid = uid, @@ -62,9 +66,6 @@ end -- @return if successful: an table containing card info -- @return if unsuccessful : nil, error local function read14443b(disconnect) - - local result, info, err, data - local flags = ISO14B_COMMAND.ISO14B_CONNECT + ISO14B_COMMAND.ISO14B_SELECT_STD @@ -72,18 +73,18 @@ local function read14443b(disconnect) print('DISCONNECT') flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT end - - local senddata = ('%04x%08x%04x'):format(flags, 0, 0) + + local flags_str = ('%04x'):format(utils.SwapEndianness(('%04x'):format(flags), 16)) + local time_str = ('%08x'):format(0) + local rawlen_str = ('%04x'):format(0) + local senddata = ('%s%s%s'):format(flags_str, time_str, rawlen_str) local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata} - info = nil - + local info = nil local result, err = c:sendNG(false, TIMEOUT) - if result then - local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result) - if arg0 == 0 then - data = string.sub(result, count) - info, err = parse14443b(data) + if result and result.Status == 0 then + if result.Oldarg0 == 0 then + info, err = parse14443b(result.Data) else err = 'iso14443b card select failed' end @@ -97,34 +98,35 @@ local function read14443b(disconnect) return info, nil end --- --- Waits for a mifare card to be placed within the vicinity of the reader. --- @return if successful: an table containing card info --- @return if unsuccessful : nil, error -local function waitFor14443b() - print('Waiting for card... press Enter to quit') - while not core.kbd_enter_pressed() do - res, err = read14443b(false) - if res then return res, err end - -- err means that there was no response from card - end - return nil, 'Aborted by user' -end ---- -- turns on the HF field. local function connect14443b() - local data = ('%04x%08x%04x'):format(ISO14B_COMMAND.ISO14B_CONNECT, 0, 0) + local data = ('%04x%08x%04x'):format(utils.SwapEndianness(('%04x'):format(ISO14B_COMMAND.ISO14B_CONNECT), 16), 0,0) local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = data} return c:sendNG(true) end --- -- Sends an instruction to do nothing, only disconnect local function disconnect14443b() - local data = ('%04x%08x%04x'):format(ISO14B_COMMAND.ISO14B_DISCONNECT, 0, 0) + local data = ('%04x%08x%04x'):format(utils.SwapEndianness(('%04x'):format(ISO14B_COMMAND.ISO14B_DISCONNECT), 16), 0,0) local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = data} -- We can ignore the response here, no ACK is returned for this command -- Check /armsrc/iso14443b.c, ReaderIso14443b() for details return c:sendNG(true) end +--- +-- Waits for a mifare card to be placed within the vicinity of the reader. +-- @return if successful: an table containing card info +-- @return if unsuccessful : nil, error +local function waitFor14443b() + print('Waiting for card... press to quit') + while not core.kbd_enter_pressed() do + res, err = read14443b(false) + if res then return res, err end + -- err means that there was no response from card + end + disconnect14443b() + return nil, 'Aborted by user' +end local library = { read = read14443b, diff --git a/client/luascripts/hf_14b_calypso.lua b/client/luascripts/hf_14b_calypso.lua index 058d28179..bb492debf 100644 --- a/client/luascripts/hf_14b_calypso.lua +++ b/client/luascripts/hf_14b_calypso.lua @@ -30,15 +30,14 @@ device-side. ]] local function calypso_parse(result) - local r = Command.parse(result) - if r.arg1 >= 0 then - local len = r.arg1 * 2 + if result.Oldarg0 >= 0 then + local len = result.Oldarg0 * 2 if len > 0 then - r.data = string.sub(r.data, 0, len); - return r, nil - end + local d = string.sub(result.Data, 0, len); + return d, nil + end end - return nil,nil + return nil, "calypso_parse failed" end --- -- A debug printout-function @@ -115,19 +114,22 @@ local function calypso_send_cmd_raw(data, ignoreresponse ) local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU -- flags = lib14b.ISO14B_COMMAND.ISO14B_RAW + -- lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC - + local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU data = data or "" -- LEN of data, half the length of the ASCII-string hex string -- 2 bytes flags -- 4 bytes timeout -- 2 bytes raw len -- n bytes raw - local senddata = ('%04x%08x%04x%s'):format(flags, 0, ( 8 + #data/2), data ) + + local flags_str = ('%04x'):format(utils.SwapEndianness(('%04x'):format(flags), 16)) + local time_str = ('%08x'):format(0) + local rawlen_str = ('%04x'):format(utils.SwapEndianness(('%04x'):format(( 8 + #data/2)), 16)) + local senddata = ('%s%s%s%s'):format(flags_str, time_str, rawlen_str,data) local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata} local result, err = c:sendNG(ignoreresponse, 2000) if result then - local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result) - if arg0 >= 0 then + if result.Oldarg0 >= 0 then return calypso_parse(result) else err = 'card response failed' @@ -248,13 +250,13 @@ function main(args) for i, apdu in spairs(_calypso_cmds) do print('>> '..ansicolors.yellow..i..ansicolors.reset) apdu = apdu:gsub('%s+', '') - result, err = calypso_send_cmd_raw(apdu , false) + data, err = calypso_send_cmd_raw(apdu , false) if err then print('<< '..err) else - if result then - local status, desc, err = calypso_apdu_status(result.data) - local d = result.data:sub(3, (#result.data - 8)) + if data then + local status, desc, err = calypso_apdu_status(data) + local d = data:sub(3, (#data - 8)) if status then print('<< '..d..' ('..ansicolors.green..'ok'..ansicolors.reset..')') else diff --git a/client/luascripts/hf_14b_mobib.lua b/client/luascripts/hf_14b_mobib.lua index 9a74f2503..eda33f48f 100644 --- a/client/luascripts/hf_14b_mobib.lua +++ b/client/luascripts/hf_14b_mobib.lua @@ -7,7 +7,7 @@ local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is a script to communicate with a MOBIB tag using the '14b raw' commands ]] @@ -30,16 +30,15 @@ Check there for details about data format and how commands are interpreted on th device-side. ]] -local function calypso_parse(result) - local r = Command.parse(result) - if r.arg1 >= 0 then - local len = r.arg1 * 2 +local function mobib_parse(result) + if result.Oldarg0 >= 0 then + local len = result.Oldarg0 * 2 if len > 0 then - r.data = string.sub(r.data, 0, len); - return r, nil + d = string.sub(result.Data, 0, len); + return d, nil end end - return nil,nil + return nil, "mobib_parse failed" end --- -- A debug printout-function @@ -111,23 +110,24 @@ end --- -- Sends a usbpackage , "hf 14b raw" -- if it reads the response, it converts it to a lua object "Command" first and the Data is cut to correct length. -local function calypso_send_cmd_raw(data, ignoreresponse ) +local function mobib_send_cmd_raw(data, ignoreresponse ) local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU - data = data or "" -- LEN of data, half the length of the ASCII-string hex string -- 2 bytes flags -- 4 bytes timeout -- 2 bytes raw len -- n bytes raw - local senddata = ('%04x%08x%04x%s'):format(flags, 0, ( 8 + #data/2), data) + local flags_str = ('%04x'):format(utils.SwapEndianness(('%04x'):format(flags), 16)) + local time_str = ('%08x'):format(0) + local rawlen_str = ('%04x'):format(utils.SwapEndianness(('%04x'):format(( 8 + #data/2)), 16)) + local senddata = ('%s%s%s%s'):format(flags_str, time_str, rawlen_str,data) local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata} - local result, err = command:sendNG(ignoreresponse, 2000) + local result, err = c:sendNG(ignoreresponse, 2000) if result then - local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result) - if arg0 >= 0 then - return calypso_parse(result) + if result.Oldarg0 >= 0 then + return mobib_parse(result) else err = 'card response failed' end @@ -137,9 +137,9 @@ local function calypso_send_cmd_raw(data, ignoreresponse ) return result, err end --- --- calypso_card_num : Reads card number from ATR and +-- mobib_card_num : Reads card number from ATR and -- writes it in the tree in decimal format. -local function calypso_card_num(card) +local function mobib_card_num(card) if not card then return end local card_num = tonumber( card.uid:sub(1,8),16 ) print('') @@ -149,7 +149,7 @@ local function calypso_card_num(card) end --- -- analyse CALYPSO apdu status bytes. -local function calypso_apdu_status(apdu) +local function mobib_apdu_status(apdu) -- last two is CRC -- next two is APDU status bytes. local mess = 'FAIL' @@ -233,19 +233,19 @@ function main(args) card, err = lib14b.waitFor14443b() if not card then return oops(err) end - calypso_card_num(card) + mobib_card_num(card) cid = card.cid for i, apdu in spairs(_calypso_cmds) do print('>> '..ansicolors.yellow..i..ansicolors.reset) apdu = apdu:gsub('%s+', '') - result, err = calypso_send_cmd_raw(apdu , false) + data, err = mobib_send_cmd_raw(apdu , false) if err then print('<< '..err) else - if result then - local status, desc, err = calypso_apdu_status(result.data) - local d = result.data:sub(3, (#result.data - 8)) + if data then + local status, desc, err = mobib_apdu_status(data) + local d = data:sub(3, (#data - 8)) if status then print('<< '..d..' ('..ansicolors.green..'ok'..ansicolors.reset..')') else diff --git a/client/src/cmdanalyse.c b/client/src/cmdanalyse.c index 1ddf77350..cddc692d6 100644 --- a/client/src/cmdanalyse.c +++ b/client/src/cmdanalyse.c @@ -28,6 +28,7 @@ #include "proxgui.h" #include "cliparser.h" #include "generator.h" // generate nuid +#include "iso14b.h" // defines for ETU conversions static int CmdHelp(const char *Cmd); @@ -1078,6 +1079,81 @@ static int CmdAnalyseFoo(const char *Cmd) { return PM3_SUCCESS; } +static int CmdAnalyseUnits(const char* Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "analyse units", + "experiments of unit conversions found in HF. ETU (1/13.56mhz), US or SSP_CLK (1/3.39MHz)", + "analyse uints --etu 10" + "analyse uints --us 100" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0(NULL, "etu", "", "number in ETU"), + arg_int0(NULL, "us", "", "number in micro seconds (us)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int etu = arg_get_int_def(ctx, 1, -1); + int us = arg_get_int_def(ctx, 2, -1); + CLIParserFree(ctx); + + if (etu == -1 && us == -1) { + PrintAndLogEx(INFO, "US to ETU conversions"); + PrintAndLogEx(INFO, " 9 US = %u ETU (expect 1) " _GREEN_("ok"), US_TO_ETU(9)); + PrintAndLogEx(INFO, " 10 US = %u ETU (expect 1) " _GREEN_("ok"), US_TO_ETU(10)); + PrintAndLogEx(INFO, " 94 US = %u ETU (expect 10) " _GREEN_("ok"), US_TO_ETU(94)); + PrintAndLogEx(INFO, " 95 US = %u ETU (expect 10) " _GREEN_("ok"), US_TO_ETU(95)); + PrintAndLogEx(INFO, " 302 US = %u ETU (expect 32) " _GREEN_("ok"), US_TO_ETU(302)); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(INFO, "ETU to US conversions"); + PrintAndLogEx(INFO, " 1 ETU = %u US (expect 9.43) " _GREEN_("ok"), ETU_TO_US(1)); + PrintAndLogEx(INFO, " 10 ETU = %u US (expect 94.39) " _GREEN_("ok"), ETU_TO_US(10)); + PrintAndLogEx(INFO, " 32 ETU = %u US (expect 302) " _GREEN_("ok"), ETU_TO_US(32)); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(INFO, "US to SSP CLK 3.39MHz conversions"); + PrintAndLogEx(INFO, " 9 US = %u SSP (expect 32) ", US_TO_SSP(9)); + PrintAndLogEx(INFO, " 10 US = %u SSP (expect 32 or 48) ", US_TO_SSP(10)); + PrintAndLogEx(INFO, " 94 US = %u SSP (expect 320) ", US_TO_SSP(94)); + PrintAndLogEx(INFO, " 95 US = %u SSP (expect 320 or 336) ", US_TO_SSP(95)); + PrintAndLogEx(INFO, " 302 US = %u SSP (expect 1024) ", US_TO_SSP(302)); + + PrintAndLogEx(INFO, " 4949000 US = %u SSP ", US_TO_SSP(4949000)); + + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(INFO, "SSP CLK 3.39MHz to US conversions"); + PrintAndLogEx(INFO, " 32 SSP = %u US (expext 9 or 10) " _GREEN_("ok"), SSP_TO_US(32)); + PrintAndLogEx(INFO, " 320 SSP = %u US (expext 94 or 95) " _GREEN_("ok"), SSP_TO_US(320)); + PrintAndLogEx(INFO, "1024 SSP = %u US (expext 302) " _GREEN_("ok"), SSP_TO_US(1024)); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(INFO, "ETU to SSP CLK 3.39MHz conversions"); + PrintAndLogEx(INFO, " 1 ETU = %u SSP (expect 32) " _GREEN_("ok"), ETU_TO_SSP(1)); + PrintAndLogEx(INFO, " 10 ETU = %u SSP (expect 320) " _GREEN_("ok"), ETU_TO_SSP(10)); + PrintAndLogEx(INFO, " 32 ETU = %u SSP (expect 1024) " _GREEN_("ok"), ETU_TO_SSP(32)); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(INFO, "SSP CLK 3.39MHz to ETU conversions"); + PrintAndLogEx(INFO, "1024 SSP = %u ETU (expect 32) " _GREEN_("ok"), SSP_TO_ETU(1024)); + PrintAndLogEx(INFO, " 320 SSP = %u ETU (expect 10) " _GREEN_("ok"), SSP_TO_ETU(320)); + PrintAndLogEx(INFO, " 32 SSP = %u ETU (expect 1) " _GREEN_("ok"), SSP_TO_ETU(32)); + } else if (etu) { + + PrintAndLogEx(INFO, " %d ETU = %u us ", ETU_TO_US(etu)); + PrintAndLogEx(INFO, " %d ETU = %u SSP ", ETU_TO_SSP(etu)); + } else if (us) { + PrintAndLogEx(INFO, " %d us = %u ETU ", US_TO_ETU(us)); + PrintAndLogEx(INFO, " %d us = %u SSP ", US_TO_SSP(us)); + } + + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"lcr", CmdAnalyseLCR, AlwaysAvailable, "Generate final byte for XOR LRC"}, @@ -1090,7 +1166,8 @@ static command_t CommandTable[] = { {"nuid", CmdAnalyseNuid, AlwaysAvailable, "create NUID from 7byte UID"}, {"demodbuff", CmdAnalyseDemodBuffer, AlwaysAvailable, "Load binary string to demodbuffer"}, {"freq", CmdAnalyseFreq, AlwaysAvailable, "Calc wave lengths"}, - {"foo", CmdAnalyseFoo, AlwaysAvailable, "muxer"}, + {"foo", CmdAnalyseFoo, AlwaysAvailable, "muxer"}, + {"units", CmdAnalyseUnits, AlwaysAvailable, "convert ETU <> US <> SSP_CLK (3.39MHz)"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 0cf9bcc37..a0bb0dba7 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -127,6 +127,16 @@ int CmdHFSearch(const char *Cmd) { } } + // 14b is the longest test + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, " Searching for ISO14443-B tag..."); + if (IfPm3Iso14443b()) { + if (readHF14B(false, false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO 14443-B tag") " found\n"); + res = PM3_SUCCESS; + } + } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for FeliCa tag..."); if (IfPm3Felica()) { @@ -136,15 +146,6 @@ int CmdHFSearch(const char *Cmd) { } } - // 14b is the longest test (put last) - PROMPT_CLEARLINE; - PrintAndLogEx(INPLACE, " Searching for ISO14443-B tag..."); - if (IfPm3Iso14443b()) { - if (readHF14B(false, false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO 14443-B tag") " found\n"); - res = PM3_SUCCESS; - } - } /* PROMPT_CLEARLINE; diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 1af9c5199..ec1c784c5 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -26,9 +26,13 @@ #include "mifare/ndef.h" // NDEFRecordsDecodeAndPrint #include "aidsearch.h" -#define MAX_14B_TIMEOUT (4949000U >> 2) -#define TIMEOUT 2000 -#define APDU_TIMEOUT 2000 +#define MAX_14B_TIMEOUT_MS (4949U) + +// client side time out, waiting for device to ask tag. +#define TIMEOUT 1000 + +// client side time out, waiting for device to ask tag a APDU to answer +#define APDU_TIMEOUT 2000 // iso14b apdu input frame length static uint16_t apdu_frame_length = 0; @@ -152,55 +156,53 @@ static void hf14b_aid_search(bool verbose) { PrintAndLogEx(INFO, "----------------------------------------------------"); } -static bool wait_cmd_14b(bool verbose, bool is_select) { +static bool wait_cmd_14b(bool verbose, bool is_select, uint32_t timeout) { PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { - - uint16_t len = (resp.oldarg[1] & 0xFFFF); - uint8_t *data = resp.data.asBytes; - - // handle select responses - if (is_select) { - - // 0: OK; -1: attrib fail; -2:crc fail - int status = (int)resp.oldarg[0]; - if (status == 0) { - - if (verbose) { - PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len); - PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); - } - return true; - } else { - return false; - } - } - - // handle raw bytes responses - if (verbose) { - - if (len >= 3) { - bool crc = check_crc(CRC_14443_B, data, len); - - PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len); - PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s", - sprint_hex(data, len - 2), - data[len - 2], - data[len - 1], - (crc) ? _GREEN_("ok") : _RED_("fail") - ); - } else if (len == 0) { - PrintAndLogEx(INFO, "no response from tag"); - } else { - PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); - } - } - return true; - } else { + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, MAX(TIMEOUT, timeout)) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); return false; } + + uint16_t len = (resp.oldarg[1] & 0xFFFF); + uint8_t *data = resp.data.asBytes; + + // handle select responses + if (is_select) { + + // 0: OK; -1: attrib fail; -2:crc fail + int status = (int)resp.oldarg[0]; + if (status == 0) { + + if (verbose) { + PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len); + PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); + } + return true; + } else { + return false; + } + } + + // handle raw bytes responses + if (verbose) { + if (len >= 3) { + bool crc = check_crc(CRC_14443_B, data, len); + + PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len); + PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s", + sprint_hex(data, len - 2), + data[len - 2], + data[len - 1], + (crc) ? _GREEN_("ok") : _RED_("fail") + ); + } else if (len == 0) { + PrintAndLogEx(INFO, "no response from tag"); + } else { + PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); + } + } + return true; } static int CmdHF14BList(const char *Cmd) { @@ -331,14 +333,15 @@ static int CmdHF14BCmdRaw(const char *Cmd) { flags |= ISO14B_SET_TIMEOUT; - uint32_t max_timeout = user_timeout; - if (max_timeout > MAX_14B_TIMEOUT) { - max_timeout = MAX_14B_TIMEOUT; + if (user_timeout > MAX_14B_TIMEOUT_MS) { + user_timeout = MAX_14B_TIMEOUT_MS; PrintAndLogEx(INFO, "set timeout to 4.9 seconds. The max we can wait for response"); } - time_wait = ((13560000 / 1000 / (8 * 16)) * max_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) + + // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) + time_wait = (uint32_t)((13560 / 128) * user_timeout); if (verbose) - PrintAndLogEx(INFO, "using timeout %u", max_timeout); + PrintAndLogEx(INFO, " new raw timeout : %u ETU ( %u ms )", time_wait, user_timeout); } if (keep_field_on == 0) @@ -350,15 +353,20 @@ static int CmdHF14BCmdRaw(const char *Cmd) { // Max buffer is PM3_CMD_DATA_SIZE datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; - iso14b_raw_cmd_t packet = { - .flags = flags, - .timeout = time_wait, - .rawlen = datalen, - }; - memcpy(packet.raw, data, datalen); + + iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t*)calloc(1, sizeof(iso14b_raw_cmd_t) + datalen); + if (packet == NULL) { + PrintAndLogEx(FAILED, "failed to allocate memory"); + return PM3_EMALLOC; + } + packet->flags = flags; + packet->timeout = time_wait; + packet->rawlen = datalen; + memcpy(packet->raw, data, datalen); clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(packet) + datalen); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen); + free(packet); if (read_reply == false) { clearCommandBuffer(); @@ -369,26 +377,26 @@ static int CmdHF14BCmdRaw(const char *Cmd) { // Select, device will send back iso14b_card_select_t, don't print it. if (select_std) { - success = wait_cmd_14b(verbose, true); + success = wait_cmd_14b(verbose, true, user_timeout); if (verbose && success) PrintAndLogEx(SUCCESS, "Got response for standard select"); } if (select_sr) { - success = wait_cmd_14b(verbose, true); + success = wait_cmd_14b(verbose, true, user_timeout); if (verbose && success) PrintAndLogEx(SUCCESS, "Got response for ST/SRx select"); } if (select_cts) { - success = wait_cmd_14b(verbose, true); + success = wait_cmd_14b(verbose, true, user_timeout); if (verbose && success) PrintAndLogEx(SUCCESS, "Got response for ASK/C-ticket select"); } // get back response from the raw bytes you sent. if (success && datalen > 0) { - wait_cmd_14b(true, false); + wait_cmd_14b(true, false, user_timeout); } return PM3_SUCCESS; @@ -783,13 +791,13 @@ static bool HF14B_Std_Info(bool verbose, bool do_aid_search) { return true; } case -1: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 STD ATTRIB fail"); break; case -2: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CRC fail"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 STD CRC fail"); break; default: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select failed"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b STD select failed"); break; } @@ -888,7 +896,7 @@ static bool HF14B_st_reader(bool verbose) { if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST random chip id fail"); break; default: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b ST card select SRx failed"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b ST select SRx failed"); break; } return false; @@ -973,7 +981,7 @@ static bool HF14B_ask_ct_reader(bool verbose) { break; } default: { - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b CTS card select failed"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b CTS select failed"); break; } } @@ -1351,7 +1359,7 @@ static int CmdHF14BDump(const char *Cmd) { packet->raw[1] = blocknum & 0xFF; clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t) + 2); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + 2); if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { status = resp.oldarg[0]; @@ -1433,9 +1441,9 @@ static int CmdHF14BDump(const char *Cmd) { } size_t datalen = (blocks + 1) * 4; - saveFileEML(filename, data, datalen, 4); saveFile(filename, ".bin", data, datalen); - // JSON? + saveFileEML(filename, data, datalen, 4); + saveFileJSON(filename, jsf14b, data, datalen, NULL); return switch_off_field_14b(); } /* @@ -1606,7 +1614,10 @@ static int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card) { return PM3_SUCCESS; } -static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout, int user_timeout) { +static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, + bool activateField, uint8_t *dataout, int maxdataoutlen, + int *dataoutlen, bool *chainingout, int user_timeout) { + *chainingout = false; if (activateField) { @@ -1630,12 +1641,13 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool if (user_timeout > 0) { packet->flags |= ISO14B_SET_TIMEOUT; - if (user_timeout > MAX_14B_TIMEOUT) { - user_timeout = MAX_14B_TIMEOUT; + if (user_timeout > MAX_14B_TIMEOUT_MS) { + user_timeout = MAX_14B_TIMEOUT_MS; PrintAndLogEx(INFO, "set timeout to 4.9 seconds. The max we can wait for response"); } - // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) - packet->timeout = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_timeout); + + // timeout in ETU + packet->timeout = (uint32_t)((13560 / 128) * user_timeout); } // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes @@ -1696,7 +1708,10 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool return PM3_SUCCESS; } -int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout) { +int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, + bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, + int *dataoutlen, int user_timeout) { + *dataoutlen = 0; bool chaining = false; int res; @@ -1785,22 +1800,24 @@ static int CmdHF14BAPDU(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14b apdu", - "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", - "hf 14b apdu -s --hex 94a40800043f000002\n" - "hf 14b apdu -sd --hex 00A404000E325041592E5359532E444446303100 -> decode apdu\n" - "hf 14b apdu -sm 00A40400 -l 256 --hex 325041592E5359532E4444463031 -> encode standard apdu\n" - "hf 14b apdu -sm 00A40400 -el 65536 --hex 325041592E5359532E4444463031 -> encode extended apdu\n"); + "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL).\n" + "works with all apdu types from ISO 7816-4:2013", + "hf 14b apdu -s -d 94a40800043f000002\n" + "hf 14b apdu -s --decode -d 00A404000E325041592E5359532E444446303100 -> decode apdu\n" + "hf 14b apdu -sm 00A40400 -l 256 -d 325041592E5359532E4444463031 -> encode standard apdu\n" + "hf 14b apdu -sm 00A40400 -el 65536 -d 325041592E5359532E4444463031 -> encode extended apdu\n"); void *argtable[] = { arg_param_begin, arg_lit0("s", "select", "activate field and select card"), arg_lit0("k", "keep", "leave the signal field ON after receive response"), arg_lit0("t", "tlv", "executes TLV decoder if it possible"), - arg_lit0("d", "decode", "decode apdu request if it possible"), - arg_str0("m", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), + arg_lit0(NULL, "decode", "decode apdu request if it possible"), + arg_str0("m", "make", "", "make apdu with head from this field and data from data field.\n" + " must be 4 bytes: "), arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"), arg_int0("l", "le", "", "Le apdu parameter if `m` parameter included"), - arg_strx1(NULL, "hex", "", " if `m` parameter included"), + arg_strx1("d", "data", "", " if `m` parameter included"), arg_int0(NULL, "timeout", "", "timeout in ms"), arg_param_end }; @@ -2000,14 +2017,15 @@ out: static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"apdu", CmdHF14BAPDU, IfPm3Iso14443b, "Send ISO 14443-4 APDU to tag"}, - {"dump", CmdHF14BDump, IfPm3Iso14443b, "Read all memory pages of an ISO14443-B tag, save to file"}, + {"dump", CmdHF14BDump, IfPm3Iso14443b, "Read all memory pages of an ISO-14443-B tag, save to file"}, {"info", CmdHF14Binfo, IfPm3Iso14443b, "Tag information"}, - {"list", CmdHF14BList, AlwaysAvailable, "List ISO 14443B history"}, + {"list", CmdHF14BList, AlwaysAvailable, "List ISO-14443-B history"}, {"ndef", CmdHF14BNdef, IfPm3Iso14443b, "Read NDEF file on tag"}, {"raw", CmdHF14BCmdRaw, IfPm3Iso14443b, "Send raw hex data to tag"}, - {"reader", CmdHF14BReader, IfPm3Iso14443b, "Act as a 14443B reader to identify a tag"}, - {"sim", CmdHF14BSim, IfPm3Iso14443b, "Fake ISO 14443B tag"}, - {"sniff", CmdHF14BSniff, IfPm3Iso14443b, "Eavesdrop ISO 14443B"}, + {"reader", CmdHF14BReader, IfPm3Iso14443b, "Act as a ISO-14443-B reader to identify a tag"}, +// {"restore", CmdHF14BRestore, IfPm3Iso14443b, "Restore from file to all memory pages of an ISO-14443-B tag"}, + {"sim", CmdHF14BSim, IfPm3Iso14443b, "Fake ISO ISO-14443-B tag"}, + {"sniff", CmdHF14BSniff, IfPm3Iso14443b, "Eavesdrop ISO-14443-B"}, {"rdbl", CmdHF14BSriRdBl, IfPm3Iso14443b, "Read SRI512/SRIX4x block"}, {"sriwrite", CmdHF14BWriteSri, IfPm3Iso14443b, "Write data to a SRI512 or SRIX4K tag"}, // {"valid", srix4kValid, AlwaysAvailable, "srix4k checksum test"}, @@ -2044,7 +2062,6 @@ int infoHF14B(bool verbose, bool do_aid_search) { // get and print general info about all known 14b chips int readHF14B(bool loop, bool verbose) { - do { // try std 14b (atqb) if (HF14B_std_reader(verbose)) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index ddac6071b..7e39ed304 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -197,7 +197,7 @@ static bool emrtd_exchange_commands(const char *cmd, uint8_t *dataout, int *data int res; if (use_14b) { // need to add a long timeout for passports with activated anti-bruteforce measure - res = exchange_14b_apdu(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen, 15000); + res = exchange_14b_apdu(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen, 4000); } else { res = ExchangeAPDU14a(aCMD, aCMD_n, activate_field, keep_field_on, response, sizeof(response), &resplen); } @@ -657,6 +657,8 @@ static int emrtd_read_file(uint8_t *dataout, int *dataoutlen, uint8_t *kenc, uin int readlen = datalen - (3 - emrtd_get_asn1_field_length(response, resplen, 1)); offset = 4; + uint8_t lnbreak = 32; + PrintAndLogEx(INFO, "." NOLF); while (readlen > 0) { toread = readlen; if (readlen > 118) { @@ -665,10 +667,12 @@ static int emrtd_read_file(uint8_t *dataout, int *dataoutlen, uint8_t *kenc, uin if (use_secure) { if (_emrtd_secure_read_binary_decrypt(kenc, kmac, ssc, offset, toread, tempresponse, &tempresplen, use_14b) == false) { + PrintAndLogEx(NORMAL, ""); return false; } } else { if (_emrtd_read_binary(offset, toread, tempresponse, &tempresplen, use_14b) == false) { + PrintAndLogEx(NORMAL, ""); return false; } } @@ -677,7 +681,17 @@ static int emrtd_read_file(uint8_t *dataout, int *dataoutlen, uint8_t *kenc, uin offset += toread; readlen -= toread; resplen += tempresplen; + + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + lnbreak--; + if (lnbreak == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "." NOLF); + lnbreak = 32; + } } + PrintAndLogEx(NORMAL, ""); memcpy(dataout, &response, resplen); *dataoutlen = resplen; @@ -1007,7 +1021,7 @@ static bool emrtd_connect(bool *use_14b) { SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); PacketResponseNG resp; bool failed_14a = false; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { DropField(); failed_14a = true; } @@ -1022,7 +1036,7 @@ static bool emrtd_connect(bool *use_14b) { }; clearCommandBuffer(); SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t)); - if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2500) == false) { + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000) == false) { PrintAndLogEx(INFO, "timeout, no eMRTD spotted with 14b, exiting"); return false; } @@ -1090,7 +1104,7 @@ int dumpHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab bool use_14b = false; // Select the eMRTD - if (!emrtd_connect(&use_14b)) { + if (emrtd_connect(&use_14b) == false) { DropField(); return PM3_ESOFT; } diff --git a/include/iso14b.h b/include/iso14b.h index eb72d263b..766ca851c 100644 --- a/include/iso14b.h +++ b/include/iso14b.h @@ -44,9 +44,18 @@ typedef enum ISO14B_COMMAND { typedef struct { uint16_t flags; // the ISO14B_COMMAND enum uint32_t timeout; - size_t rawlen; + uint16_t rawlen; uint8_t raw[]; } PACKED iso14b_raw_cmd_t; +#define US_TO_SSP(x) ( (uint32_t)((x) * 3.39) ) +#define SSP_TO_US(x) ( (uint32_t)((x) / 3.39) ) + +#define ETU_TO_SSP(x) ((x) * 32) +#define SSP_TO_ETU(x) ((x) / 32) + +#define ETU_TO_US(x) ((((x) * 9440000) / 1000000) + 0.5) +#define US_TO_ETU(x) ((((x) * 1000000 / 9440000) + 0.5)) + #endif // _ISO14B_H_