mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
convert 14b raw to use NG
This commit is contained in:
parent
5ddfade1f9
commit
b267ee8ef5
11 changed files with 453 additions and 303 deletions
|
@ -190,7 +190,7 @@ Use this bibtex to cite this repository:
|
||||||
author={Iceman1001},
|
author={Iceman1001},
|
||||||
year={2019.08},
|
year={2019.08},
|
||||||
publisher={Github},
|
publisher={Github},
|
||||||
keywords = {rfid nfc iceman proxmark3 125khz 134khz 13.56mhz},
|
keywords={rfid nfc iceman proxmark3 125khz 134khz 13.56mhz},
|
||||||
journal={GitHub repository},
|
journal={GitHub repository},
|
||||||
howpublished={\url{https://github.com/rfidresearchgroup/proxmark3}},
|
howpublished={\url{https://github.com/rfidresearchgroup/proxmark3}},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1308,8 +1308,9 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
SimulateIso14443bTag(packet->data.asBytes);
|
SimulateIso14443bTag(packet->data.asBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO14443B_COMMAND: {
|
case CMD_HF_ISO14443B_COMMAND: {
|
||||||
SendRawCommand14443B_Ex(packet);
|
iso14b_raw_cmd_t *payload = (iso14b_raw_cmd_t*)packet->data.asBytes;
|
||||||
|
SendRawCommand14443B_Ex(payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_CRYPTORF_SIM : {
|
case CMD_HF_CRYPTORF_SIM : {
|
||||||
|
|
|
@ -94,6 +94,21 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
|
||||||
*
|
*
|
||||||
* Elementary Time Unit (ETU) is
|
* Elementary Time Unit (ETU) is
|
||||||
* - 128 Carrier Cycles (9.4395 µS) = 8 Subcarrier Units
|
* - 128 Carrier Cycles (9.4395 µS) = 8 Subcarrier Units
|
||||||
|
|
||||||
|
* Definition
|
||||||
|
* 1 ETU = 128 / ( D x fc )
|
||||||
|
* where
|
||||||
|
* D = divisor. Which inital is 1
|
||||||
|
* fc = carrier frequency
|
||||||
|
* gives
|
||||||
|
* 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
|
* - 1 ETU = 1 bit
|
||||||
* - 10 ETU = 1 startbit, 8 databits, 1 stopbit (10bits length)
|
* - 10 ETU = 1 startbit, 8 databits, 1 stopbit (10bits length)
|
||||||
* - startbit is a 0
|
* - startbit is a 0
|
||||||
|
@ -115,13 +130,13 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
|
||||||
* FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead.
|
* FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead.
|
||||||
*
|
*
|
||||||
* Card sends data ub 847.e kHz subcarrier
|
* Card sends data ub 847.e kHz subcarrier
|
||||||
* subcar |duration| FC division
|
* subcar |duration| FC division| I/Q pairs
|
||||||
* -------+--------+------------
|
* -------+--------+------------+--------
|
||||||
* 106kHz | 9.44µS | FC/128
|
* 106kHz | 9.44µS | FC/128 | 16
|
||||||
* 212kHz | 4.72µS | FC/64
|
* 212kHz | 4.72µS | FC/64 | 8
|
||||||
* 424kHz | 2.36µS | FC/32
|
* 424kHz | 2.36µS | FC/32 | 4
|
||||||
* 848kHz | 1.18µS | FC/16
|
* 848kHz | 1.18µS | FC/16 | 2
|
||||||
* -------+--------+------------
|
* -------+--------+------------+--------
|
||||||
*
|
*
|
||||||
* Reader data transmission:
|
* Reader data transmission:
|
||||||
* - no modulation ONES
|
* - no modulation ONES
|
||||||
|
@ -143,13 +158,15 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
|
||||||
* things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s)
|
* things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s)
|
||||||
*
|
*
|
||||||
* Let us report a correlation every 64 samples. I.e.
|
* Let us report a correlation every 64 samples. I.e.
|
||||||
* one Q/I pair after 4 subcarrier cycles for the 848kHz subcarrier,
|
* 1 I/Q pair after 4 subcarrier cycles for the 848kHz subcarrier,
|
||||||
* one Q/I pair after 2 subcarrier cycles for the 424kHz subcarrier,
|
* 1 I/Q pair after 2 subcarrier cycles for the 424kHz subcarrier,
|
||||||
* one Q/I pair for each subcarrier cyle for the 212kHz 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// An ISO 14443 Type B tag. We listen for commands from the reader, using
|
// 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
|
// a UART kind of thing that's implemented in software. When we get a
|
||||||
|
@ -2021,29 +2038,37 @@ static void iso14b_set_trigger(bool enable) {
|
||||||
* none
|
* none
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *o) {
|
||||||
|
|
||||||
|
/*
|
||||||
iso14b_command_t param = c->oldarg[0];
|
iso14b_command_t param = c->oldarg[0];
|
||||||
size_t len = c->oldarg[1] & 0xffff;
|
size_t len = o->oldarg[1] & 0xffff;
|
||||||
uint32_t timeout = c->oldarg[2];
|
uint32_t timeout = o->oldarg[2];
|
||||||
uint8_t *cmd = c->data.asBytes;
|
uint8_t *cmd = o->data.asBytes;
|
||||||
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
|
*/
|
||||||
|
|
||||||
if (DBGLEVEL > DBG_DEBUG) Dbprintf("14b raw: param, %04x", param);
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
// turn on trigger (LED_A)
|
// turn on trigger (LED_A)
|
||||||
if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER)
|
if ((o->flags & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER)
|
||||||
iso14b_set_trigger(true);
|
iso14b_set_trigger(true);
|
||||||
|
|
||||||
if ((param & ISO14B_CONNECT) == ISO14B_CONNECT) {
|
if ((o->flags & ISO14B_CONNECT) == ISO14B_CONNECT) {
|
||||||
iso14443b_setup();
|
iso14443b_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_SET_TIMEOUT) == ISO14B_SET_TIMEOUT) {
|
if ((o->flags & ISO14B_SET_TIMEOUT) == ISO14B_SET_TIMEOUT) {
|
||||||
iso14b_set_timeout(timeout);
|
iso14b_set_timeout(o->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_CLEARTRACE) == ISO14B_CLEARTRACE) {
|
if ((o->flags & ISO14B_CLEARTRACE) == ISO14B_CLEARTRACE) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
}
|
}
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
@ -2053,21 +2078,21 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
||||||
iso14b_card_select_t card;
|
iso14b_card_select_t card;
|
||||||
memset((void *)&card, 0x00, sizeof(card));
|
memset((void *)&card, 0x00, sizeof(card));
|
||||||
|
|
||||||
if ((param & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) {
|
if ((o->flags & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) {
|
||||||
status = iso14443b_select_card(&card);
|
status = iso14443b_select_card(&card);
|
||||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
||||||
// 0: OK -1: attrib fail, -2:crc fail,
|
// 0: OK -1: attrib fail, -2:crc fail,
|
||||||
if (status != 0) goto out;
|
if (status != 0) goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) {
|
if ((o->flags & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) {
|
||||||
status = iso14443b_select_srx_card(&card);
|
status = iso14443b_select_srx_card(&card);
|
||||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen);
|
||||||
// 0: OK 2: demod fail, 3:crc fail,
|
// 0: OK 2: demod fail, 3:crc fail,
|
||||||
if (status > 0) goto out;
|
if (status > 0) goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_SELECT_CTS) == ISO14B_SELECT_CTS) {
|
if ((o->flags & ISO14B_SELECT_CTS) == ISO14B_SELECT_CTS) {
|
||||||
iso14b_cts_card_select_t cts;
|
iso14b_cts_card_select_t cts;
|
||||||
sendlen = sizeof(iso14b_cts_card_select_t);
|
sendlen = sizeof(iso14b_cts_card_select_t);
|
||||||
status = iso14443b_select_cts_card(&cts);
|
status = iso14443b_select_cts_card(&cts);
|
||||||
|
@ -2076,21 +2101,23 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
||||||
if (status > 0) goto out;
|
if (status > 0) goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_APDU) == ISO14B_APDU) {
|
if ((o->flags & ISO14B_APDU) == ISO14B_APDU) {
|
||||||
uint8_t res;
|
uint8_t res;
|
||||||
status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf), &res);
|
status = iso14443b_apdu(o->raw, o->rawlen, (o->flags & ISO14B_SEND_CHAINING), buf, sizeof(buf), &res);
|
||||||
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
|
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
|
||||||
reply_mix(CMD_HF_ISO14443B_COMMAND, status, res, 0, buf, sendlen);
|
reply_mix(CMD_HF_ISO14443B_COMMAND, status, res, 0, buf, sendlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_RAW) == ISO14B_RAW) {
|
if ((o->flags & ISO14B_RAW) == ISO14B_RAW) {
|
||||||
if ((param & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) {
|
if ((o->flags & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) {
|
||||||
AddCrc14B(cmd, len);
|
if (o->rawlen > 0) {
|
||||||
len += 2;
|
AddCrc14B(o->raw, o->rawlen);
|
||||||
|
o->rawlen += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uint32_t start_time = 0;
|
uint32_t start_time = 0;
|
||||||
uint32_t eof_time = 0;
|
uint32_t eof_time = 0;
|
||||||
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);
|
CodeAndTransmit14443bAsReader(o->raw, o->rawlen, &start_time, &eof_time);
|
||||||
|
|
||||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
@ -2107,12 +2134,12 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
||||||
|
|
||||||
out:
|
out:
|
||||||
// turn off trigger (LED_A)
|
// turn off trigger (LED_A)
|
||||||
if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER)
|
if ((o->flags & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER)
|
||||||
iso14b_set_trigger(false);
|
iso14b_set_trigger(false);
|
||||||
|
|
||||||
// turn off antenna et al
|
// turn off antenna et al
|
||||||
// we don't send a HALT command.
|
// we don't send a HALT command.
|
||||||
if ((param & ISO14B_DISCONNECT) == ISO14B_DISCONNECT) {
|
if ((o->flags & ISO14B_DISCONNECT) == ISO14B_DISCONNECT) {
|
||||||
switch_off(); // disconnect raw
|
switch_off(); // disconnect raw
|
||||||
SpinDelay(20);
|
SpinDelay(20);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
|
||||||
void ReadSTBlock(uint8_t blocknr);
|
void ReadSTBlock(uint8_t blocknr);
|
||||||
void SniffIso14443b(void);
|
void SniffIso14443b(void);
|
||||||
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
|
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
|
||||||
void SendRawCommand14443B_Ex(PacketCommandNG *c);
|
void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *c);
|
||||||
|
|
||||||
// States for 14B SIM command
|
// States for 14B SIM command
|
||||||
#define SIM_NOFIELD 0
|
#define SIM_NOFIELD 0
|
||||||
|
|
|
@ -27,6 +27,9 @@ local ISO14B_COMMAND = {
|
||||||
ISO14B_SELECT_STD = 0x40,
|
ISO14B_SELECT_STD = 0x40,
|
||||||
ISO14B_SELECT_SR = 0x80,
|
ISO14B_SELECT_SR = 0x80,
|
||||||
ISO14B_SET_TIMEOUT = 0x100,
|
ISO14B_SET_TIMEOUT = 0x100,
|
||||||
|
ISO14B_SEND_CHAINING = 0x200,
|
||||||
|
ISO14B_SELECT_CTS = 0x400,
|
||||||
|
ISO14B_CLEARTRACE = 0x800,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function parse14443b(data)
|
local function parse14443b(data)
|
||||||
|
@ -60,7 +63,7 @@ end
|
||||||
-- @return if unsuccessful : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function read14443b(disconnect)
|
local function read14443b(disconnect)
|
||||||
|
|
||||||
local command, result, info, err, data
|
local result, info, err, data
|
||||||
|
|
||||||
local flags = ISO14B_COMMAND.ISO14B_CONNECT +
|
local flags = ISO14B_COMMAND.ISO14B_CONNECT +
|
||||||
ISO14B_COMMAND.ISO14B_SELECT_STD
|
ISO14B_COMMAND.ISO14B_SELECT_STD
|
||||||
|
@ -69,15 +72,13 @@ local function read14443b(disconnect)
|
||||||
print('DISCONNECT')
|
print('DISCONNECT')
|
||||||
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
|
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
|
||||||
end
|
end
|
||||||
|
|
||||||
command = Command:newMIX{
|
local senddata = ('%04x%08x%04x'):format(flags, 0, 0)
|
||||||
cmd = cmds.CMD_HF_ISO14443B_COMMAND,
|
local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata}
|
||||||
arg1 = flags
|
|
||||||
}
|
|
||||||
|
|
||||||
info = nil
|
info = nil
|
||||||
|
|
||||||
local result, err = command:sendMIX(false, TIMEOUT, true)
|
local result, err = c:sendNG(false, TIMEOUT)
|
||||||
if result then
|
if result then
|
||||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
||||||
if arg0 == 0 then
|
if arg0 == 0 then
|
||||||
|
@ -111,16 +112,18 @@ end
|
||||||
---
|
---
|
||||||
-- turns on the HF field.
|
-- turns on the HF field.
|
||||||
local function connect14443b()
|
local function connect14443b()
|
||||||
local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_CONNECT}
|
local data = ('%04x%08x%04x'):format(ISO14B_COMMAND.ISO14B_CONNECT, 0, 0)
|
||||||
return c:sendMIX(true)
|
local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = data}
|
||||||
|
return c:sendNG(true)
|
||||||
end
|
end
|
||||||
---
|
---
|
||||||
-- Sends an instruction to do nothing, only disconnect
|
-- Sends an instruction to do nothing, only disconnect
|
||||||
local function disconnect14443b()
|
local function disconnect14443b()
|
||||||
local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_DISCONNECT}
|
local data = ('%04x%08x%04x'):format(ISO14B_COMMAND.ISO14B_DISCONNECT, 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
|
-- We can ignore the response here, no ACK is returned for this command
|
||||||
-- Check /armsrc/iso14443b.c, ReaderIso14443b() for details
|
-- Check /armsrc/iso14443b.c, ReaderIso14443b() for details
|
||||||
return c:sendMIX(true)
|
return c:sendNG(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
local library = {
|
local library = {
|
||||||
|
|
|
@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
|
||||||
|
|
||||||
copyright = ''
|
copyright = ''
|
||||||
author = 'Iceman'
|
author = 'Iceman'
|
||||||
version = 'v1.0.4'
|
version = 'v1.0.5'
|
||||||
desc = [[
|
desc = [[
|
||||||
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
|
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
|
||||||
]]
|
]]
|
||||||
|
@ -112,21 +112,19 @@ end
|
||||||
-- if it reads the response, it converts it to a lua object "Command" first and the Data is cut to correct length.
|
-- 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 calypso_send_cmd_raw(data, ignoreresponse )
|
||||||
|
|
||||||
local command, flags, result, err
|
local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
|
||||||
flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
|
|
||||||
-- flags = lib14b.ISO14B_COMMAND.ISO14B_RAW +
|
-- flags = lib14b.ISO14B_COMMAND.ISO14B_RAW +
|
||||||
-- lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC
|
-- lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC
|
||||||
|
|
||||||
data = data or "00"
|
data = data or ""
|
||||||
|
-- LEN of data, half the length of the ASCII-string hex string
|
||||||
command = Command:newMIX{
|
-- 2 bytes flags
|
||||||
cmd = cmds.CMD_HF_ISO14443B_COMMAND,
|
-- 4 bytes timeout
|
||||||
arg1 = flags,
|
-- 2 bytes raw len
|
||||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
-- n bytes raw
|
||||||
data = data} -- data bytes (commands etc)
|
local senddata = ('%04x%08x%04x%s'):format(flags, 0, ( 8 + #data/2), data )
|
||||||
|
local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata}
|
||||||
local use_cmd_ack = true
|
local result, err = c:sendNG(ignoreresponse, 2000)
|
||||||
result, err = command:sendMIX(ignoreresponse, 2000, use_cmd_ack)
|
|
||||||
if result then
|
if result then
|
||||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
||||||
if arg0 >= 0 then
|
if arg0 >= 0 then
|
||||||
|
|
|
@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
|
||||||
|
|
||||||
copyright = ''
|
copyright = ''
|
||||||
author = 'Iceman'
|
author = 'Iceman'
|
||||||
version = 'v1.0.0'
|
version = 'v1.0.1'
|
||||||
desc = [[
|
desc = [[
|
||||||
This is a script to communicate with a MOBIB tag using the '14b raw' commands
|
This is a script to communicate with a MOBIB tag using the '14b raw' commands
|
||||||
]]
|
]]
|
||||||
|
@ -112,20 +112,18 @@ end
|
||||||
-- Sends a usbpackage , "hf 14b raw"
|
-- 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.
|
-- 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 calypso_send_cmd_raw(data, ignoreresponse )
|
||||||
|
local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
|
||||||
|
|
||||||
local command, flags, result, err
|
data = data or ""
|
||||||
flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
|
-- 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 c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata}
|
||||||
|
|
||||||
data = data or "00"
|
local result, err = command:sendNG(ignoreresponse, 2000)
|
||||||
|
|
||||||
command = Command:newMIX{
|
|
||||||
cmd = cmds.CMD_HF_ISO14443B_COMMAND,
|
|
||||||
arg1 = flags,
|
|
||||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
|
||||||
data = data} -- data bytes (commands etc)
|
|
||||||
|
|
||||||
local use_cmd_ack = true
|
|
||||||
result, err = command:sendMIX(ignoreresponse, 2000, use_cmd_ack)
|
|
||||||
if result then
|
if result then
|
||||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
|
||||||
if arg0 >= 0 then
|
if arg0 >= 0 then
|
||||||
|
|
|
@ -38,8 +38,13 @@ bool apdu_in_framing_enable = true;
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int switch_off_field_14b(void) {
|
static int switch_off_field_14b(void) {
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = ISO14B_DISCONNECT,
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +334,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
|
||||||
uint32_t max_timeout = user_timeout;
|
uint32_t max_timeout = user_timeout;
|
||||||
if (max_timeout > MAX_14B_TIMEOUT) {
|
if (max_timeout > MAX_14B_TIMEOUT) {
|
||||||
max_timeout = MAX_14B_TIMEOUT;
|
max_timeout = MAX_14B_TIMEOUT;
|
||||||
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
|
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)
|
time_wait = ((13560000 / 1000 / (8 * 16)) * max_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
@ -345,8 +350,16 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
|
||||||
// Max buffer is PM3_CMD_DATA_SIZE
|
// Max buffer is PM3_CMD_DATA_SIZE
|
||||||
datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen;
|
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);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, datalen, time_wait, data, datalen);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(packet) + datalen);
|
||||||
|
|
||||||
if (read_reply == false) {
|
if (read_reply == false) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -386,32 +399,37 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
|
||||||
if (card == NULL)
|
if (card == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int status;
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||||
|
|
||||||
status = resp.oldarg[0];
|
if (resp.oldarg[0] == 0) {
|
||||||
if (status == 0) {
|
|
||||||
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test 14b standard
|
// test 14b standard
|
||||||
|
packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||||
|
|
||||||
status = resp.oldarg[0];
|
if (resp.oldarg[0] == 0) {
|
||||||
if (status == 0) {
|
|
||||||
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,25 +745,28 @@ static void print_ct_general_info(void *vcard) {
|
||||||
|
|
||||||
// 14b get and print Full Info (as much as we know)
|
// 14b get and print Full Info (as much as we know)
|
||||||
static bool HF14B_Std_Info(bool verbose, bool do_aid_search) {
|
static bool HF14B_Std_Info(bool verbose, bool do_aid_search) {
|
||||||
|
|
||||||
bool is_success = false;
|
|
||||||
|
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (verbose) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
return is_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso14b_card_select_t card;
|
iso14b_card_select_t card;
|
||||||
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||||
|
|
||||||
int status = resp.oldarg[0];
|
int status = resp.oldarg[0];
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0: {
|
case 0: {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -759,8 +780,7 @@ static bool HF14B_Std_Info(bool verbose, bool do_aid_search) {
|
||||||
hf14b_aid_search(verbose);
|
hf14b_aid_search(verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_success = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case -1:
|
case -1:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
||||||
|
@ -773,17 +793,25 @@ static bool HF14B_Std_Info(bool verbose, bool do_aid_search) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRx get and print full info (needs more info...)
|
// SRx get and print full info (needs more info...)
|
||||||
static bool HF14B_ST_Info(bool verbose, bool do_aid_search) {
|
static bool HF14B_ST_Info(bool verbose, bool do_aid_search) {
|
||||||
|
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (verbose) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,28 +853,31 @@ static int CmdHF14Binfo(const char *Cmd) {
|
||||||
|
|
||||||
static bool HF14B_st_reader(bool verbose) {
|
static bool HF14B_st_reader(bool verbose) {
|
||||||
|
|
||||||
bool is_success = false;
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
// SRx get and print general info about SRx chip from UID
|
// SRx get and print general info about SRx chip from UID
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (verbose) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
return is_success;
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso14b_card_select_t card;
|
iso14b_card_select_t card;
|
||||||
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||||
|
|
||||||
int status = resp.oldarg[0];
|
int status = resp.oldarg[0];
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
print_st_general_info(card.uid, card.uidlen);
|
print_st_general_info(card.uid, card.uidlen);
|
||||||
is_success = true;
|
return true;
|
||||||
break;
|
|
||||||
case -1:
|
case -1:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST ATTRIB fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST ATTRIB fail");
|
||||||
break;
|
break;
|
||||||
|
@ -860,25 +891,28 @@ static bool HF14B_st_reader(bool verbose) {
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b ST card select SRx failed");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b ST card select SRx failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return is_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HF14B_std_reader(bool verbose) {
|
static bool HF14B_std_reader(bool verbose) {
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
bool is_success = false;
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
if (verbose) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = resp.oldarg[0];
|
int status = resp.oldarg[0];
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0: {
|
case 0: {
|
||||||
iso14b_card_select_t card;
|
iso14b_card_select_t card;
|
||||||
|
@ -888,8 +922,7 @@ static bool HF14B_std_reader(bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||||
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
||||||
print_atqb_resp(card.atqb, card.cid);
|
print_atqb_resp(card.atqb, card.cid);
|
||||||
is_success = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case -1: {
|
case -1: {
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
||||||
|
@ -904,17 +937,21 @@ static bool HF14B_std_reader(bool verbose) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return is_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HF14B_ask_ct_reader(bool verbose) {
|
static bool HF14B_ask_ct_reader(bool verbose) {
|
||||||
|
|
||||||
bool is_success = false;
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
return false;
|
return false;
|
||||||
|
@ -925,8 +962,7 @@ static bool HF14B_ask_ct_reader(bool verbose) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0: {
|
case 0: {
|
||||||
print_ct_general_info(resp.data.asBytes);
|
print_ct_general_info(resp.data.asBytes);
|
||||||
is_success = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case -1: {
|
case -1: {
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS wrong length");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS wrong length");
|
||||||
|
@ -941,24 +977,32 @@ static bool HF14B_ask_ct_reader(bool verbose) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return is_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for other 14b type tags (mimic another reader - don't have tags to identify)
|
// test for other 14b type tags (mimic another reader - don't have tags to identify)
|
||||||
static bool HF14B_other_reader(bool verbose) {
|
static bool HF14B_other_reader(bool verbose) {
|
||||||
|
|
||||||
uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
|
iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t*)calloc(1, sizeof(iso14b_raw_cmd_t) + 4);
|
||||||
uint8_t datalen = 4;
|
if (packet == NULL) {
|
||||||
|
PrintAndLogEx(FAILED, "failed to allocate memory");
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
packet->flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC);
|
||||||
|
packet->timeout = 0;
|
||||||
|
packet->rawlen = 4;
|
||||||
|
memcpy(packet->raw, "\x00\x0b\x3f\x80", 4);
|
||||||
|
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, datalen, 0, data, datalen);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen);
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (verbose) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
|
free(packet);
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -969,21 +1013,27 @@ static bool HF14B_other_reader(bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
||||||
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x000b3f80 command ans:");
|
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x000b3f80 command ans:");
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
free(packet);
|
||||||
return true;
|
return true;
|
||||||
} else if (status > 0) {
|
} else if (status > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
||||||
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x000b3f80 command ans:");
|
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x000b3f80 command ans:");
|
||||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp.data.asBytes, status));
|
PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp.data.asBytes, status));
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
free(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[0] = ISO14443B_AUTHENTICATE;
|
packet->rawlen = 1;
|
||||||
|
packet->raw[0] = ISO14443B_AUTHENTICATE;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen);
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
if (verbose) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
free(packet);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
status = resp.oldarg[0];
|
status = resp.oldarg[0];
|
||||||
|
@ -993,20 +1043,25 @@ static bool HF14B_other_reader(bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
||||||
PrintAndLogEx(SUCCESS, "Unknown tag type answered to a 0x0A command ans:");
|
PrintAndLogEx(SUCCESS, "Unknown tag type answered to a 0x0A command ans:");
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
free(packet);
|
||||||
return true;
|
return true;
|
||||||
} else if (status > 0) {
|
} else if (status > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
PrintAndLogEx(SUCCESS, "\n14443-3b tag found:");
|
||||||
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x0A command ans:");
|
PrintAndLogEx(SUCCESS, "unknown tag type answered to a 0x0A command ans:");
|
||||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp.data.asBytes, status));
|
PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp.data.asBytes, status));
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
free(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[0] = ISO14443B_RESET;
|
packet->raw[0] = ISO14443B_RESET;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen);
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
free(packet);
|
||||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
|
if (verbose) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
}
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1273,6 @@ static int CmdHF14BDump(const char *Cmd) {
|
||||||
|
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
char *fptr = filename;
|
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -1252,47 +1306,52 @@ static int CmdHF14BDump(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fnlen < 1) {
|
|
||||||
PrintAndLogEx(INFO, "using UID as filename");
|
|
||||||
fptr += sprintf(fptr, "hf-14b-");
|
|
||||||
FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t chipid = get_st_chipid(card.uid);
|
uint8_t chipid = get_st_chipid(card.uid);
|
||||||
PrintAndLogEx(SUCCESS, "found a " _GREEN_("%s") " tag", get_st_chip_model(chipid));
|
PrintAndLogEx(SUCCESS, "found a " _GREEN_("%s") " tag", get_st_chip_model(chipid));
|
||||||
|
|
||||||
// detect blocksize from card :)
|
// detect blocksize from card :)
|
||||||
PrintAndLogEx(INFO, "reading tag memory from UID " _GREEN_("%s"), sprint_hex_inrow(SwapEndian64(card.uid, card.uidlen, 8), card.uidlen));
|
PrintAndLogEx(INFO, "reading tag memory from UID " _GREEN_("%s"), sprint_hex_inrow(SwapEndian64(card.uid, card.uidlen, 8), card.uidlen));
|
||||||
|
|
||||||
uint8_t data[cardsize];
|
iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t*)calloc(1, sizeof(iso14b_raw_cmd_t) + 2);
|
||||||
memset(data, 0, sizeof(data));
|
if (packet == NULL) {
|
||||||
uint8_t *recv = NULL;
|
PrintAndLogEx(FAILED, "failed to allocate memory");
|
||||||
int status = 0;
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
packet->flags = (ISO14B_CONNECT | ISO14B_SELECT_SR);
|
||||||
|
packet->timeout = 0;
|
||||||
|
packet->rawlen = 0;
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
PacketResponseNG resp;
|
||||||
//select
|
|
||||||
|
// select
|
||||||
|
int status = 0;
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
||||||
status = resp.oldarg[0];
|
status = resp.oldarg[0];
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
PrintAndLogEx(FAILED, "failed to select arg0[%" PRId64 "] arg1 [%" PRId64 "]", resp.oldarg[0], resp.oldarg[1]);
|
PrintAndLogEx(FAILED, "failed to select arg0[%" PRId64 "]" , resp.oldarg[0]);
|
||||||
goto out;
|
free(packet);
|
||||||
|
return switch_off_field_14b();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "." NOLF);
|
PrintAndLogEx(INFO, "." NOLF);
|
||||||
|
|
||||||
uint8_t req[2] = {ISO14443B_READ_BLK};
|
uint8_t data[cardsize];
|
||||||
int blocknum = 0;
|
memset(data, 0, sizeof(data));
|
||||||
|
uint16_t blocknum = 0;
|
||||||
|
|
||||||
for (int retry = 0; retry < 5; retry++) {
|
for (int retry = 0; retry < 5; retry++) {
|
||||||
|
|
||||||
req[1] = blocknum;
|
// set up the read command
|
||||||
|
packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
|
||||||
|
packet->rawlen = 2;
|
||||||
|
packet->raw[0] = ISO14443B_READ_BLK;
|
||||||
|
packet->raw[1] = blocknum & 0xFF;
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req));
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t) + 2);
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
||||||
|
|
||||||
status = resp.oldarg[0];
|
status = resp.oldarg[0];
|
||||||
|
@ -1302,16 +1361,16 @@ static int CmdHF14BDump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t len = (resp.oldarg[1] & 0xFFFF);
|
uint16_t len = (resp.oldarg[1] & 0xFFFF);
|
||||||
recv = resp.data.asBytes;
|
uint8_t *recv = resp.data.asBytes;
|
||||||
|
|
||||||
if (check_crc(CRC_14443_B, recv, len) == false) {
|
if (check_crc(CRC_14443_B, recv, len) == false) {
|
||||||
PrintAndLogEx(FAILED, "crc fail, retrying one more time");
|
PrintAndLogEx(FAILED, "crc fail, retrying one more time");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data + (blocknum * 4), resp.data.asBytes, 4);
|
memcpy(data + (blocknum * 4), recv, 4);
|
||||||
|
|
||||||
// last read.
|
// last read
|
||||||
if (blocknum == 0xFF) {
|
if (blocknum == 0xFF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1327,11 +1386,13 @@ static int CmdHF14BDump(const char *Cmd) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(packet);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
if (blocknum != 0xFF) {
|
if (blocknum != 0xFF) {
|
||||||
PrintAndLogEx(FAILED, "dump failed");
|
PrintAndLogEx(FAILED, "dump failed");
|
||||||
goto out;
|
return switch_off_field_14b();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocknum * 4), 4));
|
PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocknum * 4), 4));
|
||||||
|
@ -1364,11 +1425,17 @@ static int CmdHF14BDump(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
// save to file
|
// save to file
|
||||||
|
if (fnlen < 1) {
|
||||||
|
PrintAndLogEx(INFO, "using UID as filename");
|
||||||
|
char *fptr = filename;
|
||||||
|
fptr += sprintf(fptr, "hf-14b-");
|
||||||
|
FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen);
|
||||||
|
}
|
||||||
|
|
||||||
size_t datalen = (blocks + 1) * 4;
|
size_t datalen = (blocks + 1) * 4;
|
||||||
saveFileEML(filename, data, datalen, 4);
|
saveFileEML(filename, data, datalen, 4);
|
||||||
saveFile(filename, ".bin", data, datalen);
|
saveFile(filename, ".bin", data, datalen);
|
||||||
// JSON?
|
// JSON?
|
||||||
out:
|
|
||||||
return switch_off_field_14b();
|
return switch_off_field_14b();
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1480,25 +1547,31 @@ static int srix4kValid(const char *Cmd) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card) {
|
static int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card) {
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
if (card)
|
if (card)
|
||||||
memset(card, 0, sizeof(iso14b_card_select_t));
|
memset(card, 0, sizeof(iso14b_card_select_t));
|
||||||
|
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
// Anticollision + SELECT STD card
|
// Anticollision + SELECT STD card
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD, 0, 0, NULL, 0);
|
PacketResponseNG resp;
|
||||||
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
PrintAndLogEx(INFO, "Trying 14B Select SRx");
|
PrintAndLogEx(INFO, "Trying 14B Select SRx");
|
||||||
|
|
||||||
// Anticollision + SELECT SR card
|
// Anticollision + SELECT SR card
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0, NULL, 0);
|
packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_SR);
|
||||||
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
PrintAndLogEx(INFO, "Trying 14B Select CTS");
|
PrintAndLogEx(INFO, "Trying 14B Select CTS");
|
||||||
|
|
||||||
// Anticollision + SELECT ASK C-Ticket card
|
// Anticollision + SELECT ASK C-Ticket card
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_CTS, 0, 0, NULL, 0);
|
packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_CTS);
|
||||||
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
PrintAndLogEx(ERR, "connection timeout");
|
PrintAndLogEx(ERR, "connection timeout");
|
||||||
switch_off_field_14b();
|
switch_off_field_14b();
|
||||||
|
@ -1543,78 +1616,83 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
|
||||||
return selres;
|
return selres;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t flags = 0;
|
iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t*)calloc(1, sizeof(iso14b_raw_cmd_t) + datainlen);
|
||||||
|
if (packet == NULL) {
|
||||||
|
PrintAndLogEx(FAILED, "APDU: failed to allocate memory");
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
packet->flags = (ISO14B_CONNECT | ISO14B_APDU);
|
||||||
|
packet->timeout = 0;
|
||||||
|
packet->rawlen = 0;
|
||||||
|
|
||||||
if (chainingin)
|
if (chainingin)
|
||||||
flags = ISO14B_SEND_CHAINING;
|
packet->flags = (ISO14B_SEND_CHAINING | ISO14B_APDU);
|
||||||
|
|
||||||
uint32_t time_wait = 0;
|
|
||||||
if (user_timeout > 0) {
|
if (user_timeout > 0) {
|
||||||
|
packet->flags |= ISO14B_SET_TIMEOUT;
|
||||||
flags |= ISO14B_SET_TIMEOUT;
|
|
||||||
if (user_timeout > MAX_14B_TIMEOUT) {
|
if (user_timeout > MAX_14B_TIMEOUT) {
|
||||||
user_timeout = MAX_14B_TIMEOUT;
|
user_timeout = MAX_14B_TIMEOUT;
|
||||||
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
|
PrintAndLogEx(INFO, "set timeout to 4.9 seconds. The max we can wait for response");
|
||||||
}
|
}
|
||||||
time_wait = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_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)
|
||||||
|
packet->timeout = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes
|
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes
|
||||||
// https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
|
// https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
|
||||||
// here length PM3_CMD_DATA_SIZE=512
|
// here length PM3_CMD_DATA_SIZE=512
|
||||||
if (datain)
|
if (datain) {
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, (datainlen & 0xFFFF), time_wait, datain, datainlen & 0xFFFF);
|
packet->rawlen = datainlen;
|
||||||
else
|
memcpy(packet->raw, datain, datainlen);
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, 0, time_wait, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen);
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, MAX(APDU_TIMEOUT, user_timeout))) {
|
|
||||||
uint8_t *recv = resp.data.asBytes;
|
|
||||||
int rlen = resp.oldarg[0];
|
|
||||||
uint8_t res = resp.oldarg[1];
|
|
||||||
|
|
||||||
int dlen = rlen - 2;
|
|
||||||
if (dlen < 0) {
|
|
||||||
dlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dataoutlen += dlen;
|
|
||||||
|
|
||||||
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
|
|
||||||
PrintAndLogEx(ERR, "APDU: Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// I-block ACK
|
|
||||||
if ((res & 0xf2) == 0xa2) {
|
|
||||||
*dataoutlen = 0;
|
|
||||||
*chainingout = true;
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rlen < 0) {
|
|
||||||
PrintAndLogEx(ERR, "APDU: No APDU response.");
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check apdu length
|
|
||||||
if (rlen == 0 || rlen == 1) {
|
|
||||||
PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", rlen);
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dataout, recv, dlen);
|
|
||||||
|
|
||||||
// chaining
|
|
||||||
if ((res & 0x10) != 0) {
|
|
||||||
*chainingout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, "APDU: Reply timeout.");
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
}
|
||||||
|
free(packet);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, MAX(APDU_TIMEOUT, user_timeout)) == false) {
|
||||||
|
PrintAndLogEx(ERR, "APDU: reply timeout");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rlen = resp.oldarg[0];
|
||||||
|
int dlen = rlen - 2;
|
||||||
|
if (dlen < 0) {
|
||||||
|
dlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dataoutlen += dlen;
|
||||||
|
|
||||||
|
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
|
||||||
|
PrintAndLogEx(ERR, "APDU: buffer too small(%d), needs %d bytes", *dataoutlen, maxdataoutlen);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I-block ACK
|
||||||
|
uint8_t res = resp.oldarg[1];
|
||||||
|
if ((res & 0xF2) == 0xA2) {
|
||||||
|
*dataoutlen = 0;
|
||||||
|
*chainingout = true;
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rlen < 0) {
|
||||||
|
PrintAndLogEx(ERR, "APDU: no APDU response");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check apdu length
|
||||||
|
if (rlen == 0 || rlen == 1) {
|
||||||
|
PrintAndLogEx(ERR, "APDU: small APDU response, len %d", rlen);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dataout, resp.data.asBytes, dlen);
|
||||||
|
|
||||||
|
// chaining
|
||||||
|
if ((res & 0x10) != 0) {
|
||||||
|
*chainingout = true;
|
||||||
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1952,16 +2030,16 @@ int infoHF14B(bool verbose, bool do_aid_search) {
|
||||||
|
|
||||||
// try std 14b (atqb)
|
// try std 14b (atqb)
|
||||||
if (HF14B_Std_Info(verbose, do_aid_search))
|
if (HF14B_Std_Info(verbose, do_aid_search))
|
||||||
return 1;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
// try ST 14b
|
// try ST 14b
|
||||||
if (HF14B_ST_Info(verbose, do_aid_search))
|
if (HF14B_ST_Info(verbose, do_aid_search))
|
||||||
return 1;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
// try unknown 14b read commands (to be identified later)
|
// try unknown 14b read commands (to be identified later)
|
||||||
// could be read of calypso, CEPAS, moneo, or pico pass.
|
// could be read of calypso, CEPAS, moneo, or pico pass.
|
||||||
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
|
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
|
||||||
return 0;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get and print general info about all known 14b chips
|
// get and print general info about all known 14b chips
|
||||||
|
|
|
@ -36,8 +36,13 @@ static void set_last_known_card(iso14b_card_select_t card) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int switch_off_field_cryptorf(void) {
|
static int switch_off_field_cryptorf(void) {
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = ISO14B_DISCONNECT,
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +53,8 @@ static int CmdHFCryptoRFList(const char *Cmd) {
|
||||||
static int CmdHFCryptoRFSim(const char *Cmd) {
|
static int CmdHFCryptoRFSim(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf cryptorf sim",
|
CLIParserInit(&ctx, "hf cryptorf sim",
|
||||||
"Simulate a CryptoRF tag",
|
"Simulate a CryptoRF tag\n"
|
||||||
|
_RED_("not implemented"),
|
||||||
"hf cryptorf sim");
|
"hf cryptorf sim");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -59,7 +65,7 @@ static int CmdHFCryptoRFSim(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_CRYPTORF_SIM, 0, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_CRYPTORF_SIM, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,21 +93,22 @@ static int CmdHFCryptoRFSniff(const char *Cmd) {
|
||||||
|
|
||||||
static bool get_14b_UID(iso14b_card_select_t *card) {
|
static bool get_14b_UID(iso14b_card_select_t *card) {
|
||||||
|
|
||||||
if (!card)
|
if (card == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int8_t retry = 3;
|
int8_t retry = 3;
|
||||||
PacketResponseNG resp;
|
|
||||||
|
|
||||||
// test
|
|
||||||
while (retry--) {
|
while (retry--) {
|
||||||
|
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||||
uint8_t status = resp.oldarg[0];
|
if (resp.oldarg[0] == 0) {
|
||||||
if (status == 0) {
|
|
||||||
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -109,23 +116,26 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
|
||||||
} // retry
|
} // retry
|
||||||
|
|
||||||
if (retry <= 0)
|
if (retry <= 0)
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(FAILED, "command execution timeout");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print extented information about tag.
|
// Print extented information about tag.
|
||||||
static int infoHFCryptoRF(bool verbose) {
|
static int infoHFCryptoRF(bool verbose) {
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
int res = PM3_ESOFT;
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (verbose) {
|
||||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
PrintAndLogEx(WARNING, "command execution timeout");
|
||||||
|
}
|
||||||
switch_off_field_cryptorf();
|
switch_off_field_cryptorf();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -141,8 +151,7 @@ static int infoHFCryptoRF(bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||||
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||||
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
||||||
res = PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
||||||
break;
|
break;
|
||||||
|
@ -153,8 +162,7 @@ static int infoHFCryptoRF(bool verbose) {
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select failed");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return PM3_ESOFT;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHFCryptoRFInfo(const char *Cmd) {
|
static int CmdHFCryptoRFInfo(const char *Cmd) {
|
||||||
|
@ -182,9 +190,14 @@ static int CmdHFCryptoRFInfo(const char *Cmd) {
|
||||||
int readHFCryptoRF(bool loop, bool verbose) {
|
int readHFCryptoRF(bool loop, bool verbose) {
|
||||||
|
|
||||||
int res = PM3_ESOFT;
|
int res = PM3_ESOFT;
|
||||||
do {
|
do {
|
||||||
|
iso14b_raw_cmd_t packet = {
|
||||||
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT),
|
||||||
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
|
|
||||||
|
@ -256,7 +269,6 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
char *fnameptr = filename;
|
|
||||||
|
|
||||||
bool m64 = arg_get_lit(ctx, 2);
|
bool m64 = arg_get_lit(ctx, 2);
|
||||||
bool m512 = arg_get_lit(ctx, 3);
|
bool m512 = arg_get_lit(ctx, 3);
|
||||||
|
@ -287,51 +299,67 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
|
||||||
// detect blocksize from card :)
|
// detect blocksize from card :)
|
||||||
PrintAndLogEx(INFO, "Reading memory from tag UID " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen));
|
PrintAndLogEx(INFO, "Reading memory from tag UID " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen));
|
||||||
|
|
||||||
uint8_t data[cardsize];
|
// select tag
|
||||||
memset(data, 0, sizeof(data));
|
iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t*)calloc(1, sizeof(iso14b_raw_cmd_t) + 2);
|
||||||
|
if (packet == NULL) {
|
||||||
|
PrintAndLogEx(FAILED, "failed to allocate memory");
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
packet->flags = (ISO14B_CONNECT | ISO14B_SELECT_SR);
|
||||||
|
packet->timeout = 0;
|
||||||
|
packet->rawlen = 0;
|
||||||
|
|
||||||
int blocknum = 0;
|
|
||||||
uint8_t *recv = NULL;
|
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0, NULL, 0);
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
|
||||||
//select
|
// select
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
int status = 0;
|
||||||
if (resp.oldarg[0]) {
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
||||||
PrintAndLogEx(ERR, "failed to select %" PRId64 " | %" PRId64, resp.oldarg[0], resp.oldarg[1]);
|
status = resp.oldarg[0];
|
||||||
goto out;
|
if (status < 0) {
|
||||||
|
PrintAndLogEx(FAILED, "failed to select %" PRId64 "]", resp.oldarg[0]);
|
||||||
|
free(packet);
|
||||||
|
return switch_off_field_cryptorf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t req[2] = {ISO14443B_READ_BLK};
|
PrintAndLogEx(INFO, "." NOLF);
|
||||||
|
|
||||||
|
uint8_t data[cardsize];
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
uint16_t blocknum = 0;
|
||||||
|
|
||||||
for (int retry = 0; retry < 5; retry++) {
|
for (int retry = 0; retry < 5; retry++) {
|
||||||
|
|
||||||
req[1] = blocknum;
|
// set up the read command
|
||||||
|
packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
|
||||||
|
packet->rawlen = 2;
|
||||||
|
packet->raw[0] = ISO14443B_READ_BLK;
|
||||||
|
packet->raw[1] = blocknum & 0xFF;
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandOLD(CMD_HF_ISO14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req));
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t) + 2);
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
status = resp.oldarg[0];
|
||||||
|
if (status < 0) {
|
||||||
uint8_t status = resp.oldarg[0] & 0xFF;
|
PrintAndLogEx(FAILED, "retrying one more time");
|
||||||
if (status > 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t len = (resp.oldarg[1] & 0xFFFF);
|
uint16_t len = (resp.oldarg[1] & 0xFFFF);
|
||||||
recv = resp.data.asBytes;
|
uint8_t *recv = resp.data.asBytes;
|
||||||
|
|
||||||
if (!check_crc(CRC_14443_B, recv, len)) {
|
if (check_crc(CRC_14443_B, recv, len) == false) {
|
||||||
PrintAndLogEx(FAILED, "crc fail, retrying one more time");
|
PrintAndLogEx(FAILED, "crc fail, retrying one more time");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data + (blocknum * 4), resp.data.asBytes, 4);
|
memcpy(data + (blocknum * 4), resp.data.asBytes, 4);
|
||||||
|
|
||||||
|
// last read
|
||||||
if (blocknum == 0xFF) {
|
if (blocknum == 0xFF) {
|
||||||
//last read.
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,17 +370,19 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
|
||||||
blocknum = 0xFF;
|
blocknum = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(".");
|
PrintAndLogEx(NORMAL, "." NOLF);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(packet);
|
||||||
|
|
||||||
if (blocknum != blocks) {
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(ERR, "\nDump failed");
|
|
||||||
goto out;
|
if (blocknum != 0xFF) {
|
||||||
|
PrintAndLogEx(FAILED, "dump failed");
|
||||||
|
return switch_off_field_cryptorf();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
|
||||||
PrintAndLogEx(INFO, "block# | data | ascii");
|
PrintAndLogEx(INFO, "block# | data | ascii");
|
||||||
PrintAndLogEx(INFO, "---------+--------------+----------");
|
PrintAndLogEx(INFO, "---------+--------------+----------");
|
||||||
|
|
||||||
|
@ -365,21 +395,21 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
|
||||||
sprint_ascii(data + (i * 4), 4)
|
sprint_ascii(data + (i * 4), 4)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
PrintAndLogEx(INFO, "---------+--------------+----------");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
size_t datalen = (blocks + 1) * 4;
|
size_t datalen = (blocks + 1) * 4;
|
||||||
|
|
||||||
if (fnlen < 1) {
|
if (fnlen < 1) {
|
||||||
PrintAndLogEx(INFO, "Using UID as filename");
|
PrintAndLogEx(INFO, "Using UID as filename");
|
||||||
fnameptr += sprintf(fnameptr, "hf-cryptorf-");
|
char *fptr = filename;
|
||||||
FillFileNameByUID(fnameptr, card.uid, "-dump", card.uidlen);
|
fptr += sprintf(fptr, "hf-cryptorf-");
|
||||||
|
FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFileEML(filename, data, datalen, 4);
|
saveFileEML(filename, data, datalen, 4);
|
||||||
saveFile(filename, ".bin", data, datalen);
|
saveFile(filename, ".bin", data, datalen);
|
||||||
//json
|
// json?
|
||||||
out:
|
|
||||||
return switch_off_field_cryptorf();
|
return switch_off_field_cryptorf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +465,7 @@ static int CmdHFCryptoRFELoad(const char *Cmd) {
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
}
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandOLD(CMD_HF_CRYPTORF_EML_MEMSET, bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet);
|
SendCommandMIX(CMD_HF_CRYPTORF_EML_MEMSET, bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet);
|
||||||
bytes_remaining -= bytes_in_packet;
|
bytes_remaining -= bytes_in_packet;
|
||||||
bytes_sent += bytes_in_packet;
|
bytes_sent += bytes_in_packet;
|
||||||
}
|
}
|
||||||
|
@ -464,21 +494,20 @@ static int CmdHFCryptoRFESave(const char *Cmd) {
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
char *fnameptr = filename;
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
size_t numofbytes = CRYPTORF_MEM_SIZE;
|
size_t numofbytes = CRYPTORF_MEM_SIZE;
|
||||||
|
|
||||||
// set up buffer
|
// set up buffer
|
||||||
uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
|
uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
|
||||||
if (!data) {
|
if (data == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
// download emulator memory
|
// download emulator memory
|
||||||
PrintAndLogEx(SUCCESS, "Reading emulator memory...");
|
PrintAndLogEx(SUCCESS, "Reading emulator memory...");
|
||||||
if (!GetFromDevice(BIG_BUF_EML, data, numofbytes, 0, NULL, 0, NULL, 2500, false)) {
|
if (GetFromDevice(BIG_BUF_EML, data, numofbytes, 0, NULL, 0, NULL, 2500, false) == false) {
|
||||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
|
@ -487,8 +516,9 @@ static int CmdHFCryptoRFESave(const char *Cmd) {
|
||||||
// user supplied filename?
|
// user supplied filename?
|
||||||
if (fnlen < 1) {
|
if (fnlen < 1) {
|
||||||
PrintAndLogEx(INFO, "Using UID as filename");
|
PrintAndLogEx(INFO, "Using UID as filename");
|
||||||
fnameptr += sprintf(fnameptr, "hf-cryptorf-");
|
char *fptr = filename;
|
||||||
FillFileNameByUID(fnameptr, data, "-dump", 4);
|
fptr += sprintf(fptr, "hf-cryptorf-");
|
||||||
|
FillFileNameByUID(fptr, data, "-dump", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveFile(filename, ".bin", data, numofbytes);
|
saveFile(filename, ".bin", data, numofbytes);
|
||||||
|
@ -496,6 +526,7 @@ static int CmdHFCryptoRFESave(const char *Cmd) {
|
||||||
saveFileEML(filename, data, numofbytes, 8);
|
saveFileEML(filename, data, numofbytes, 8);
|
||||||
//needs to change
|
//needs to change
|
||||||
saveFileJSON(filename, jsfRaw, data, numofbytes, NULL);
|
saveFileJSON(filename, jsfRaw, data, numofbytes, NULL);
|
||||||
|
free(data);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1013,16 +1013,22 @@ static bool emrtd_connect(bool *use_14b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed_14a || resp.oldarg[0] == 0) {
|
if (failed_14a || resp.oldarg[0] == 0) {
|
||||||
PrintAndLogEx(INFO, "No eMRTD spotted with 14a, trying 14b.");
|
PrintAndLogEx(INFO, "No eMRTD spotted with 14a, trying 14b");
|
||||||
// If not 14a, try to 14b
|
// If not 14a, try to 14b
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_STD, 0, 0, NULL, 0);
|
iso14b_raw_cmd_t packet = {
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2500)) {
|
.flags = (ISO14B_CONNECT | ISO14B_SELECT_STD),
|
||||||
PrintAndLogEx(INFO, "No eMRTD spotted with 14b, exiting.");
|
.timeout = 0,
|
||||||
|
.rawlen = 0,
|
||||||
|
};
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t*)&packet, sizeof(iso14b_raw_cmd_t));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2500) == false) {
|
||||||
|
PrintAndLogEx(INFO, "timeout, no eMRTD spotted with 14b, exiting");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.oldarg[0] != 0) {
|
if (resp.oldarg[0] != 0) {
|
||||||
PrintAndLogEx(INFO, "No eMRTD spotted with 14b, exiting.");
|
PrintAndLogEx(INFO, "No eMRTD spotted with 14b, exiting");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*use_14b = true;
|
*use_14b = true;
|
||||||
|
|
|
@ -41,4 +41,12 @@ typedef enum ISO14B_COMMAND {
|
||||||
ISO14B_CLEARTRACE = (1 << 11),
|
ISO14B_CLEARTRACE = (1 << 11),
|
||||||
} iso14b_command_t;
|
} iso14b_command_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t flags; // the ISO14B_COMMAND enum
|
||||||
|
uint32_t timeout;
|
||||||
|
size_t rawlen;
|
||||||
|
uint8_t raw[];
|
||||||
|
} PACKED iso14b_raw_cmd_t;
|
||||||
|
|
||||||
|
|
||||||
#endif // _ISO14B_H_
|
#endif // _ISO14B_H_
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue