mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
gave 14b commands some serious love and overhaul. package handling for APDU and different selects is improved. return codes now consequent
This commit is contained in:
parent
5709d8959d
commit
82aa6ac08c
11 changed files with 350 additions and 337 deletions
|
@ -183,6 +183,10 @@
|
|||
# define ISO14B_TR2 HF14_ETU_TO_SSP(14)
|
||||
#endif
|
||||
|
||||
#ifndef ISO14B_BLOCK_SIZE
|
||||
# define ISO14B_BLOCK_SIZE 4
|
||||
#endif
|
||||
|
||||
// 4sample
|
||||
#define SEND4STUFFBIT(x) tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);
|
||||
|
||||
|
@ -472,7 +476,9 @@ static void iso14b_set_maxframesize(uint16_t size) {
|
|||
}
|
||||
|
||||
Uart.byteCntMax = size;
|
||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax);
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -662,7 +668,7 @@ static RAMFUNC int Handle14443bSampleFromReader(uint8_t bit) {
|
|||
// Assume that we're called with the SSC (to the FPGA) and ADC path set
|
||||
// correctly.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
|
||||
static bool GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
|
||||
// Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen
|
||||
// only, since we are receiving, not transmitting).
|
||||
// Signal field is off with the appropriate LED
|
||||
|
@ -764,7 +770,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
|||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
|
||||
// prepare "ATQB" tag answer (encoded):
|
||||
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
||||
|
@ -797,10 +803,13 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
|||
LED_A_ON();
|
||||
}
|
||||
}
|
||||
if (cardSTATE == SIM_NOFIELD) continue;
|
||||
|
||||
if (cardSTATE == SIM_NOFIELD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get reader command
|
||||
if (!GetIso14443bCommandFromReader(receivedCmd, &len)) {
|
||||
if (GetIso14443bCommandFromReader(receivedCmd, &len) == false) {
|
||||
Dbprintf("button pressed, received %d commands", cmdsReceived);
|
||||
break;
|
||||
}
|
||||
|
@ -810,9 +819,11 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
|||
// WUP in HALTED state
|
||||
if (len == 5) {
|
||||
if ((receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8) == 0x8 && cardSTATE == SIM_HALTED) ||
|
||||
receivedCmd[0] == ISO14443B_REQB) {
|
||||
receivedCmd[0] == ISO14443B_REQB) {
|
||||
|
||||
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
||||
cardSTATE = SIM_SELECTING;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -861,13 +872,14 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
|||
// - SLOT MARKER
|
||||
// - ISO7816
|
||||
// - emulate with a memory dump
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived);
|
||||
}
|
||||
|
||||
// CRC Check
|
||||
if (len >= 3) { // if crc exists
|
||||
// CRC Check, if long enough
|
||||
if (len >= 3) {
|
||||
|
||||
if (!check_crc(CRC_14443_B, receivedCmd, len)) {
|
||||
if (check_crc(CRC_14443_B, receivedCmd, len) == false) {
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("CRC fail");
|
||||
}
|
||||
|
@ -1000,7 +1012,7 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
|
|||
if (cardSTATE == SIM_NOFIELD) continue;
|
||||
|
||||
// Get reader command
|
||||
if (!GetIso14443bCommandFromReader(receivedCmd, &len)) {
|
||||
if (GetIso14443bCommandFromReader(receivedCmd, &len) == false) {
|
||||
Dbprintf("button pressed, received %d commands", cmdsReceived);
|
||||
break;
|
||||
}
|
||||
|
@ -1067,7 +1079,7 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
|
|||
// CRC Check
|
||||
if (len >= 3) { // if crc exists
|
||||
|
||||
if (!check_crc(CRC_14443_B, receivedCmd, len)) {
|
||||
if (check_crc(CRC_14443_B, receivedCmd, len) == false) {
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("CRC fail");
|
||||
}
|
||||
|
@ -1314,7 +1326,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
|
|||
|
||||
if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) {
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting");
|
||||
return -1;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
uint32_t dma_start_time = 0;
|
||||
|
@ -1328,8 +1340,9 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
|
|||
for (;;) {
|
||||
|
||||
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
|
||||
if (behindBy == 0)
|
||||
if (behindBy == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
samples++;
|
||||
|
||||
|
@ -1375,13 +1388,13 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
|
|||
*eof_time = GetCountSspClkDelta(dma_start_time) - DELAY_TAG_TO_ARM; // end of EOF
|
||||
|
||||
if (Demod.len > Demod.max_len) {
|
||||
ret = -2; // overflow
|
||||
ret = PM3_EOVFLOW; // overflow
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (((GetCountSspClkDelta(dma_start_time)) > timeout) && Demod.state < DEMOD_PHASE_REF_TRAINING) {
|
||||
ret = -1;
|
||||
ret = PM3_ETIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1399,8 +1412,6 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
|
|||
+ (10)); // time for EOF transfer
|
||||
LogTrace(Demod.output, Demod.len, sof_time, *eof_time, NULL, false);
|
||||
}
|
||||
|
||||
|
||||
return Demod.len;
|
||||
}
|
||||
|
||||
|
@ -1568,7 +1579,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t
|
|||
/* Sends an APDU to the tag
|
||||
* TODO: check CRC and preamble
|
||||
*/
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res) {
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res, int *reponselen) {
|
||||
|
||||
uint8_t real_cmd[msg_len + 4];
|
||||
|
||||
|
@ -1598,10 +1609,9 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
|||
|
||||
eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER;
|
||||
|
||||
// Activation frame waiting time
|
||||
// 65536/fc == 4833 µS
|
||||
// SSP_CLK = 4833 µS * 3.39 = 16384
|
||||
|
||||
// Activation frame waiting time
|
||||
// 65536/fc == 4833 µS
|
||||
// SSP_CLK = 4833 µS * 3.39 = 16384
|
||||
|
||||
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time);
|
||||
FpgaDisableTracing();
|
||||
|
@ -1609,7 +1619,8 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
|||
uint8_t *data_bytes = (uint8_t *) rxdata;
|
||||
|
||||
if (len <= 0) {
|
||||
return 0; //DATA LINK ERROR
|
||||
// DATA LINK ERROR
|
||||
return PM3_ECARDEXCHANGE;
|
||||
} else {
|
||||
// S-Block WTX
|
||||
while (len && ((data_bytes[0] & 0xF2) == 0xF2)) {
|
||||
|
@ -1648,20 +1659,23 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
|||
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
// current block number, toggle the current block number
|
||||
if (len >= 3 // PCB + CRC = 3 bytes
|
||||
&& ((data_bytes[0] & 0xC0) == 0 // I-Block
|
||||
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
||||
&& (data_bytes[0] & 0x01) == iso14b_pcb_blocknum) { // equal block numbers
|
||||
|
||||
if ((len >= 3) && // PCB + CRC = 3 bytes
|
||||
(((data_bytes[0] & 0xC0) == 0) || (data_bytes[0] & 0xD0) == 0x80) && // I-Block OR R-Block with ACK bit set to 0
|
||||
((data_bytes[0] & 0x01) == iso14b_pcb_blocknum)) { // equal block numbers
|
||||
|
||||
iso14b_pcb_blocknum ^= 1;
|
||||
|
||||
}
|
||||
|
||||
// if we received I-block with chaining we need to send ACK and receive another block of data
|
||||
if (res)
|
||||
if (res) {
|
||||
*res = data_bytes[0];
|
||||
}
|
||||
|
||||
// crc check
|
||||
if (len >= 3 && !check_crc(CRC_14443_B, data_bytes, len)) {
|
||||
return -1;
|
||||
if (len >= 3 && (check_crc(CRC_14443_B, data_bytes, len) == false)) {
|
||||
return PM3_ECRC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1674,7 +1688,10 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
|||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
if (reponselen) {
|
||||
*reponselen = len;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1686,10 +1703,11 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
uint8_t cmdMSBUID[] = {ASK_SELECT, 0xFF, 0xFF, 0x00, 0x00};
|
||||
uint8_t cmdLSBUID[] = {0xC4, 0x00, 0x00};
|
||||
|
||||
// iceman: todo static crc
|
||||
AddCrc14B(cmdMSBUID, 3);
|
||||
AddCrc14B(cmdLSBUID, 1);
|
||||
|
||||
uint8_t r[8];
|
||||
uint8_t r[8] = { 0x00 };
|
||||
|
||||
uint32_t start_time = 0;
|
||||
uint32_t eof_time = 0;
|
||||
|
@ -1700,10 +1718,10 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen != 4) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
@ -1720,10 +1738,10 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen != 4) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
@ -1738,17 +1756,17 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen != 4) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
memcpy(card->uid + 2, r, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* SRx Initialise.
|
||||
|
@ -1756,9 +1774,9 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||
// INITIATE command: wake up the tag using the INITIATE
|
||||
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
|
||||
uint8_t r_init[3] = {0x0};
|
||||
uint8_t r_select[3] = {0x0};
|
||||
uint8_t r_papid[10] = {0x0};
|
||||
uint8_t r_init[3] = { 0x00 };
|
||||
uint8_t r_select[3] = { 0x00 };
|
||||
uint8_t r_papid[10] = { 0x00 };
|
||||
|
||||
uint32_t start_time = 0;
|
||||
uint32_t eof_time = 0;
|
||||
|
@ -1769,7 +1787,7 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen <= 0) {
|
||||
return -1;
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// Randomly generated Chip ID
|
||||
|
@ -1791,42 +1809,43 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen != 3) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
if (check_crc(CRC_14443_B, r_select, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
// Check response from the tag: should be the same UID as the command we just sent:
|
||||
if (select_srx[1] != r_select[0]) {
|
||||
return -3;
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
// First get the tag's UID:
|
||||
select_srx[0] = ISO14443B_GET_UID;
|
||||
|
||||
AddCrc14B(select_srx, 1);
|
||||
select_srx[1] = 0xAB;
|
||||
select_srx[2] = 0x4E;
|
||||
|
||||
start_time = eof_time + ISO14B_TR2;
|
||||
CodeAndTransmit14443bAsReader(select_srx, 3, &start_time, &eof_time, true); // Only first three bytes for this one
|
||||
|
||||
eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER;
|
||||
retlen = Get14443bAnswerFromTag(r_papid, sizeof(r_papid), iso14b_timeout, &eof_time);
|
||||
|
||||
FpgaDisableTracing();
|
||||
|
||||
if (retlen != 10) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
if (!check_crc(CRC_14443_B, r_papid, retlen)) {
|
||||
return -2;
|
||||
|
||||
if (check_crc(CRC_14443_B, r_papid, retlen) == false) {
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
card->uidlen = 8;
|
||||
memcpy(card->uid, r_papid, 8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Xerox tag connect function: wup, anticoll, attrib, password
|
||||
|
@ -1837,9 +1856,8 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
// AFI
|
||||
static const uint8_t x_wup1[] = { 0x0D, 0x37, 0x21, 0x92, 0xf2 };
|
||||
static const uint8_t x_wup2[] = { 0x5D, 0x37, 0x21, 0x71, 0x71 };
|
||||
uint8_t slot_mark[1];
|
||||
|
||||
uint8_t x_atqb[24] = {0x0}; // ATQB len = 18
|
||||
uint8_t slot_mark[1] = { 0x00 };
|
||||
uint8_t x_atqb[24] = { 0x00 }; // ATQB len = 18
|
||||
|
||||
uint32_t start_time = 0;
|
||||
uint32_t eof_time = 0;
|
||||
|
@ -1870,7 +1888,7 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
|
||||
Dbprintf("unexpected data %d", retlen);
|
||||
Dbprintf("crc %s", check_crc(CRC_14443_B, x_atqb, retlen) ? "OK" : "BAD");
|
||||
return 1;
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// tx unframed slot-marker
|
||||
|
@ -1893,7 +1911,7 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("no answer to anticollision");
|
||||
}
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1905,16 +1923,16 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
|
||||
// ATQB too short?
|
||||
if (retlen < 18) {
|
||||
return 1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
// VALIDATE CRC
|
||||
if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch
|
||||
return 3;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (x_atqb[0] != 0x50) {
|
||||
return 1;
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
@ -1944,15 +1962,15 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
FpgaDisableTracing();
|
||||
|
||||
if (retlen < 3) {
|
||||
return 2;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
if (check_crc(CRC_14443_B, x_atqb, 3) == false) {
|
||||
return 3;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (x_atqb[0] != 0) {
|
||||
return 2;
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
// apply PASSWORD command
|
||||
|
@ -1975,18 +1993,18 @@ static int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time);
|
||||
|
||||
if (retlen < 4) {
|
||||
return 4;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
if (check_crc(CRC_14443_B, x_atqb, 4) == false) {
|
||||
return 3;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (x_atqb[0] != 2 || x_atqb[1] != 0) {
|
||||
return 4;
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/* Perform the ISO 14443 B Card Selection procedure
|
||||
|
@ -2003,10 +2021,9 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
|
|||
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xff };
|
||||
|
||||
// ATTRIB command (with space for CRC)
|
||||
uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
uint8_t r_pupid[14] = {0x0};
|
||||
uint8_t r_attrib[3] = {0x0};
|
||||
uint8_t attrib[11] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t r_pupid[14] = { 0x00 };
|
||||
uint8_t r_attrib[3] = { 0x00 };
|
||||
|
||||
// first, wake up the tag
|
||||
uint32_t start_time = 0;
|
||||
|
@ -2019,12 +2036,12 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
|
|||
|
||||
// ATQB too short?
|
||||
if (retlen < 14) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
// VALIDATE CRC
|
||||
if (check_crc(CRC_14443_B, r_pupid, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
@ -2048,12 +2065,12 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
|
|||
|
||||
// Answer to ATTRIB too short?
|
||||
if (retlen < 3) {
|
||||
return -1;
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
// VALIDATE CRC
|
||||
if (check_crc(CRC_14443_B, r_attrib, retlen) == false) {
|
||||
return -2;
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
@ -2079,7 +2096,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
|
|||
}
|
||||
// reset PCB block number
|
||||
iso14b_pcb_blocknum = 0;
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Set up ISO 14443 Type B communication (similar to iso14443a_setup)
|
||||
|
@ -2128,8 +2145,9 @@ void iso14443b_setup(void) {
|
|||
//
|
||||
// I tried to be systematic and check every answer of the tag, every CRC, etc...
|
||||
//-----------------------------------------------------------------------------
|
||||
static int read_srx_block(uint8_t blocknr, uint8_t *block) {
|
||||
static int read_14b_srx_block(uint8_t blocknr, uint8_t *block) {
|
||||
|
||||
// iceman: todo add static CRC
|
||||
uint8_t cmd[] = {ISO14443B_READ_BLK, blocknr, 0x00, 0x00};
|
||||
AddCrc14B(cmd, 2);
|
||||
|
||||
|
@ -2155,7 +2173,7 @@ static int read_srx_block(uint8_t blocknr, uint8_t *block) {
|
|||
}
|
||||
|
||||
if (block) {
|
||||
memcpy(block, r_block, 4);
|
||||
memcpy(block, r_block, ISO14B_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
|
@ -2169,25 +2187,25 @@ static int read_srx_block(uint8_t blocknr, uint8_t *block) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
void ReadSTBlock(uint8_t blocknr) {
|
||||
void read_14b_st_block(uint8_t blocknr) {
|
||||
iso14443b_setup();
|
||||
iso14b_card_select_t card;
|
||||
int res = iso14443b_select_srx_card(&card);
|
||||
|
||||
uint8_t *data = BigBuf_calloc(ISO14B_BLOCK_SIZE);
|
||||
iso14b_card_select_t *card = (iso14b_card_select_t *) BigBuf_calloc(sizeof(iso14b_card_select_t));
|
||||
|
||||
int res = iso14443b_select_srx_card(card);
|
||||
// 0: OK -1 wrong len, -2: attrib fail, -3:crc fail,
|
||||
switch (res) {
|
||||
case -1:
|
||||
case -3: {
|
||||
reply_ng(CMD_HF_SRI_READ, PM3_EWRONGANSWER, NULL, 0);
|
||||
goto out;
|
||||
}
|
||||
case -2: {
|
||||
reply_ng(CMD_HF_SRI_READ, PM3_ECRC, NULL, 0);
|
||||
case PM3_ELENGTH:
|
||||
case PM3_EWRONGANSWER:
|
||||
case PM3_ECRC: {
|
||||
reply_ng(CMD_HF_SRI_READ, res, NULL, 0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
uint8_t *data = BigBuf_malloc(4);
|
||||
res = read_srx_block(blocknr, data);
|
||||
reply_ng(CMD_HF_SRI_READ, res, data, 4);
|
||||
|
||||
res = read_14b_srx_block(blocknr, data);
|
||||
reply_ng(CMD_HF_SRI_READ, res, data, ISO14B_BLOCK_SIZE);
|
||||
|
||||
out:
|
||||
BigBuf_free();
|
||||
|
@ -2392,9 +2410,6 @@ static void iso14b_set_trigger(bool enable) {
|
|||
|
||||
void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *p) {
|
||||
|
||||
// receive buffer
|
||||
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
// turn on trigger (LED_A)
|
||||
if ((p->flags & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER) {
|
||||
iso14b_set_trigger(true);
|
||||
|
@ -2414,68 +2429,76 @@ void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *p) {
|
|||
}
|
||||
set_tracing(true);
|
||||
|
||||
// receive buffer
|
||||
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
int status = 0;
|
||||
uint32_t sendlen = sizeof(iso14b_card_select_t);
|
||||
iso14b_card_select_t *card = (iso14b_card_select_t *)buf;
|
||||
|
||||
if ((p->flags & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) {
|
||||
status = iso14443b_select_card(card);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
||||
// 0: OK -1: attrib fail, -2:crc fail,
|
||||
if (status != 0) goto out;
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, (uint8_t *)card, sendlen);
|
||||
if (status != PM3_SUCCESS) goto out;
|
||||
}
|
||||
|
||||
if ((p->flags & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) {
|
||||
memset(card, 0, sizeof(iso14b_card_select_t));
|
||||
status = iso14443b_select_srx_card(card);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
||||
// 0: OK 2: demod fail, 3:crc fail,
|
||||
if (status > 0) goto out;
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, (uint8_t *)card, sendlen);
|
||||
if (status != PM3_SUCCESS) goto out;
|
||||
}
|
||||
|
||||
if ((p->flags & ISO14B_SELECT_XRX) == ISO14B_SELECT_XRX) {
|
||||
memset(card, 0, sizeof(iso14b_card_select_t));
|
||||
status = iso14443b_select_xrx_card(card);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, (uint8_t *)card, sendlen);
|
||||
// 0: OK, 1: select fail, 2: attrib fail, 3: crc fail, 4: password fail
|
||||
if (status != 0) goto out;
|
||||
if (status != PM3_SUCCESS) goto out;
|
||||
}
|
||||
|
||||
if ((p->flags & ISO14B_SELECT_CTS) == ISO14B_SELECT_CTS) {
|
||||
iso14b_cts_card_select_t *cts = (iso14b_cts_card_select_t *)buf;
|
||||
memset(cts, 0, sizeof(iso14b_cts_card_select_t));
|
||||
sendlen = sizeof(iso14b_cts_card_select_t);
|
||||
status = iso14443b_select_cts_card(cts);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&cts, sendlen);
|
||||
// 0: OK 2: demod fail, 3:crc fail,
|
||||
if (status > 0) goto out;
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, (uint8_t *)cts, sendlen);
|
||||
if (status > PM3_SUCCESS) goto out;
|
||||
}
|
||||
|
||||
if ((p->flags & ISO14B_APDU) == ISO14B_APDU) {
|
||||
uint8_t res = 0;
|
||||
status = iso14443b_apdu(p->raw, p->rawlen, (p->flags & ISO14B_SEND_CHAINING), buf, sizeof(buf), &res);
|
||||
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE_MIX);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, res, 0, buf, sendlen);
|
||||
|
||||
iso14b_raw_apdu_response_t packet = {
|
||||
.response_byte = 0,
|
||||
.datalen = 0,
|
||||
};
|
||||
|
||||
int responselen = 0;
|
||||
status = iso14443b_apdu(p->raw, p->rawlen, (p->flags & ISO14B_SEND_CHAINING), buf, sizeof(buf), &packet.response_byte, &responselen);
|
||||
packet.datalen = MIN(responselen, PM3_CMD_DATA_SIZE);
|
||||
memcpy(packet.data, buf, packet.datalen);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, (uint8_t*)&packet, sizeof(iso14b_raw_apdu_response_t) + packet.datalen);
|
||||
}
|
||||
|
||||
if ((p->flags & ISO14B_RAW) == ISO14B_RAW) {
|
||||
if ((p->flags & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) {
|
||||
if (p->rawlen > 0) {
|
||||
AddCrc14B(p->raw, p->rawlen);
|
||||
p->rawlen += 2;
|
||||
}
|
||||
if (
|
||||
((p->flags & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) && (p->rawlen)) {
|
||||
AddCrc14B(p->raw, p->rawlen);
|
||||
p->rawlen += 2;
|
||||
}
|
||||
|
||||
uint32_t start_time = 0;
|
||||
uint32_t eof_time = 0;
|
||||
CodeAndTransmit14443bAsReader(p->raw, p->rawlen, &start_time, &eof_time, true);
|
||||
|
||||
FpgaDisableTracing();
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, PM3_ETEAROFF, NULL, 0);
|
||||
} else {
|
||||
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_MIX);
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, Demod.output, sendlen);
|
||||
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, Demod.output, sendlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue