mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 02:27:26 -07:00
hf 14b got some love
This commit is contained in:
parent
96e9d0f5cd
commit
2119c4e7bd
11 changed files with 645 additions and 393 deletions
23
CHANGELOG.md
23
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 <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
|
||||
disconnect14443b()
|
||||
return nil, 'Aborted by user'
|
||||
end
|
||||
|
||||
local library = {
|
||||
read = read14443b,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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", "<dec>", "number in ETU"),
|
||||
arg_int0(NULL, "us", "<dec>", "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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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", "<hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
|
||||
arg_lit0(NULL, "decode", "decode apdu request if it possible"),
|
||||
arg_str0("m", "make", "<hex>", "make apdu with head from this field and data from data field.\n"
|
||||
" must be 4 bytes: <CLA INS P1 P2>"),
|
||||
arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"),
|
||||
arg_int0("l", "le", "<int>", "Le apdu parameter if `m` parameter included"),
|
||||
arg_strx1(NULL, "hex", "<hex>", "<APDU | data> if `m` parameter included"),
|
||||
arg_strx1("d", "data", "<hex>", "<APDU | data> if `m` parameter included"),
|
||||
arg_int0(NULL, "timeout", "<dec>", "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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue