mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
remade ASK C-ticket select to deviceside
This commit is contained in:
parent
9956c5af31
commit
31f5502171
4 changed files with 149 additions and 82 deletions
|
@ -9,7 +9,7 @@
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
#include "mifare.h"
|
#include "iso18.h"
|
||||||
|
|
||||||
// FeliCa timings
|
// FeliCa timings
|
||||||
// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles
|
// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles
|
||||||
|
|
|
@ -902,7 +902,11 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we have still signal but no proper byte or EOF? this shouldn't happen
|
// we have still signal but no proper byte or EOF? this shouldn't happen
|
||||||
|
//Demod.posCount = 10 * 2;
|
||||||
|
Demod.bitCount = 0;
|
||||||
|
Demod.len = 0;
|
||||||
Demod.state = WAIT_FOR_RISING_EDGE_OF_SOF;
|
Demod.state = WAIT_FOR_RISING_EDGE_OF_SOF;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Demod.posCount = 0;
|
Demod.posCount = 0;
|
||||||
|
@ -1253,6 +1257,79 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, uint8
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASK CTS initialise.
|
||||||
|
*/
|
||||||
|
static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
||||||
|
// INITIATE command: wake up the tag using the INITIATE
|
||||||
|
uint8_t cmdINIT[] = {ASK_REQT, 0xF9, 0xE0};
|
||||||
|
uint8_t cmdMSBUID[] = {ASK_SELECT, 0xFF, 0xFF, 0x00, 0x00};
|
||||||
|
uint8_t cmdLSBUID[] = {0xC4, 0x00, 0x00};
|
||||||
|
|
||||||
|
AddCrc14B(cmdMSBUID, 3);
|
||||||
|
AddCrc14B(cmdLSBUID, 1);
|
||||||
|
|
||||||
|
uint8_t r[8];
|
||||||
|
|
||||||
|
uint32_t start_time = 0;
|
||||||
|
uint32_t eof_time = 0;
|
||||||
|
CodeAndTransmit14443bAsReader(cmdINIT, sizeof(cmdINIT), &start_time, &eof_time);
|
||||||
|
|
||||||
|
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
|
||||||
|
int retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
|
||||||
|
FpgaDisableTracing();
|
||||||
|
|
||||||
|
if (retlen != 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (card) {
|
||||||
|
// pc. fc Product code, Facility code
|
||||||
|
card->pc = r[0];
|
||||||
|
card->fc = r[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER;
|
||||||
|
CodeAndTransmit14443bAsReader(cmdMSBUID, sizeof(cmdMSBUID), &start_time, &eof_time);
|
||||||
|
|
||||||
|
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
|
||||||
|
retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
|
||||||
|
FpgaDisableTracing();
|
||||||
|
|
||||||
|
if (retlen != 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (card) {
|
||||||
|
memcpy(card->uid, r, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER;
|
||||||
|
CodeAndTransmit14443bAsReader(cmdLSBUID, sizeof(cmdLSBUID), &start_time, &eof_time);
|
||||||
|
|
||||||
|
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
|
||||||
|
retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
|
||||||
|
FpgaDisableTracing();
|
||||||
|
|
||||||
|
if (retlen != 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (check_crc(CRC_14443_B, r, retlen) == false) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (card) {
|
||||||
|
memcpy(card->uid + 2, r, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* SRx Initialise.
|
* SRx Initialise.
|
||||||
*/
|
*/
|
||||||
|
@ -1271,8 +1348,9 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||||
int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), ISO14443B_READER_TIMEOUT, &eof_time);
|
int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), ISO14443B_READER_TIMEOUT, &eof_time);
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
|
||||||
if (retlen <= 0)
|
if (retlen <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Randomly generated Chip ID
|
// Randomly generated Chip ID
|
||||||
if (card) {
|
if (card) {
|
||||||
|
@ -1295,8 +1373,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||||
if (retlen != 3) {
|
if (retlen != 3) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the CRC of the answer:
|
|
||||||
if (!check_crc(CRC_14443_B, r_select, retlen)) {
|
if (!check_crc(CRC_14443_B, r_select, retlen)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -1321,8 +1397,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||||
if (retlen != 10) {
|
if (retlen != 10) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The check the CRC of the answer
|
|
||||||
if (!check_crc(CRC_14443_B, r_papid, retlen)) {
|
if (!check_crc(CRC_14443_B, r_papid, retlen)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -1793,6 +1867,15 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
||||||
if (status > 0) goto out;
|
if (status > 0) goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((param & ISO14B_SELECT_CTS) == ISO14B_SELECT_CTS) {
|
||||||
|
iso14b_cts_card_select_t cts;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if ((param & ISO14B_APDU) == ISO14B_APDU) {
|
if ((param & ISO14B_APDU) == ISO14B_APDU) {
|
||||||
status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf));
|
status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf));
|
||||||
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
|
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "mifare.h"
|
#include "iso14b.h"
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#ifndef AddCrc14A
|
#ifndef AddCrc14A
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "cmdhf14b.h"
|
#include "cmdhf14b.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "iso14b.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
|
@ -43,10 +44,10 @@ static int usage_hf_14b_info(void) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_hf_14b_reader(void) {
|
static int usage_hf_14b_reader(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf 14b reader [h] [s]");
|
PrintAndLogEx(NORMAL, "Usage: hf 14b reader [h] [v]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h this help");
|
PrintAndLogEx(NORMAL, " h this help");
|
||||||
PrintAndLogEx(NORMAL, " s silently");
|
PrintAndLogEx(NORMAL, " v verbose");
|
||||||
PrintAndLogEx(NORMAL, "Example:");
|
PrintAndLogEx(NORMAL, "Example:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b reader"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b reader"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -632,6 +633,20 @@ static void print_st_general_info(uint8_t *data, uint8_t len) {
|
||||||
PrintAndLogEx(SUCCESS, "Chip: %02X, " _YELLOW_("%s"), chipid, get_ST_Chip_Model(chipid));
|
PrintAndLogEx(SUCCESS, "Chip: %02X, " _YELLOW_("%s"), chipid, get_ST_Chip_Model(chipid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print UID info from ASK CT chips
|
||||||
|
static void print_ct_general_info(void *vcard) {
|
||||||
|
iso14b_cts_card_select_t card;
|
||||||
|
memcpy(&card, (iso14b_cts_card_select_t *)vcard, sizeof(iso14b_cts_card_select_t));
|
||||||
|
|
||||||
|
uint32_t uid32 = (card.uid[0] |card.uid[1] << 8 |card.uid[2] << 16 | card.uid[3] << 24);
|
||||||
|
PrintAndLogEx(SUCCESS, "ASK C-Ticket");
|
||||||
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s") " ( " _YELLOW_("%u") " )", sprint_hex(card.uid, sizeof(card.uid)), uid32);
|
||||||
|
PrintAndLogEx(SUCCESS, " Product Code: %02X", card.pc);
|
||||||
|
PrintAndLogEx(SUCCESS, " Facility Code: %02X", card.fc);
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// iceman, some 14B APDU break down
|
// iceman, some 14B APDU break down
|
||||||
// 05 00 00 = find one tag in field
|
// 05 00 00 = find one tag in field
|
||||||
// 1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
|
// 1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
|
||||||
|
@ -726,7 +741,7 @@ static int CmdHF14Binfo(const char *Cmd) {
|
||||||
return infoHF14B(verbose);
|
return infoHF14B(verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HF14B_ST_Reader(bool verbose) {
|
static bool HF14B_st_reader(bool verbose) {
|
||||||
|
|
||||||
bool is_success = false;
|
bool is_success = false;
|
||||||
|
|
||||||
|
@ -751,22 +766,22 @@ static bool HF14B_ST_Reader(bool verbose) {
|
||||||
is_success = true;
|
is_success = true;
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST ATTRIB fail");
|
||||||
break;
|
break;
|
||||||
case -2:
|
case -2:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CRC fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST CRC fail");
|
||||||
break;
|
break;
|
||||||
case -3:
|
case -3:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 random chip id fail");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST random chip id fail");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select SRx failed");
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b ST card select SRx failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return is_success;
|
return is_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HF14B_Std_Reader(bool verbose) {
|
static bool HF14B_std_reader(bool verbose) {
|
||||||
|
|
||||||
bool is_success = false;
|
bool is_success = false;
|
||||||
|
|
||||||
|
@ -810,77 +825,45 @@ static bool HF14B_Std_Reader(bool verbose) {
|
||||||
return is_success;
|
return is_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HF14B_ask_ct_Reader(bool verbose) {
|
static bool HF14B_ask_ct_reader(bool verbose) {
|
||||||
uint8_t cmd1[] = {0x10};
|
|
||||||
uint8_t cmd2[] = {0x9F, 0xFF, 0xFF};
|
bool is_success = false;
|
||||||
uint8_t cmd3[] = {0xC4};
|
|
||||||
uint8_t uid[4];
|
|
||||||
uint8_t pc, fc;
|
|
||||||
|
|
||||||
// 14b get and print UID only (general info)
|
// 14b get and print UID only (general info)
|
||||||
uint32_t flags = ISO14B_CONNECT | ISO14B_RAW | ISO14B_APPEND_CRC;
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
int status;
|
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT, 0, 0, NULL, 0);
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT) == false) {
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, sizeof(cmd1), 0, cmd1, sizeof(cmd1));
|
|
||||||
|
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
|
||||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
||||||
switch_off_field_14b();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = resp.oldarg[0];
|
int status = resp.oldarg[0];
|
||||||
PrintAndLogEx(DEBUG, "status cmd1 %d", status);
|
|
||||||
if (status == 4) {
|
switch (status) {
|
||||||
pc = resp.data.asBytes[0];
|
case 0: {
|
||||||
fc = resp.data.asBytes[1];
|
print_ct_general_info(resp.data.asBytes);
|
||||||
} else {
|
is_success = true;
|
||||||
switch_off_field_14b();
|
break;
|
||||||
return false;
|
}
|
||||||
}
|
case -1: {
|
||||||
clearCommandBuffer();
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS wrong length");
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, sizeof(cmd2), 0, cmd2, sizeof(cmd2));
|
break;
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
}
|
||||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
case -2: {
|
||||||
switch_off_field_14b();
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS CRC fail");
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
status = resp.oldarg[0];
|
default: {
|
||||||
PrintAndLogEx(DEBUG, "status cmd2 %d", status);
|
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b CTS card select failed");
|
||||||
if (status == 4) {
|
break;
|
||||||
uid[0] = resp.data.asBytes[0];
|
}
|
||||||
uid[1] = resp.data.asBytes[1];
|
|
||||||
} else {
|
|
||||||
switch_off_field_14b();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, sizeof(cmd3), 0, cmd3, sizeof(cmd3));
|
|
||||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
|
||||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
|
||||||
switch_off_field_14b();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
status = resp.oldarg[0];
|
|
||||||
PrintAndLogEx(DEBUG, "status cmd3 %d", status);
|
|
||||||
if (status == 4) {
|
|
||||||
uid[2] = resp.data.asBytes[0];
|
|
||||||
uid[3] = resp.data.asBytes[1];
|
|
||||||
uint32_t uid32 = uid[0] + (uid[1] << 8) + (uid[2] << 16) + (uid[3] << 24);
|
|
||||||
PrintAndLogEx(SUCCESS, "\nASK CT - 14443-3b tag found:");
|
|
||||||
PrintAndLogEx(SUCCESS, "UID: %02X%02X%02X%02X (%u) Product code: %02X Fab code: %02X", uid[0], uid[1], uid[2], uid[3], uid32, pc, fc);
|
|
||||||
switch_off_field_14b();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
switch_off_field_14b();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return is_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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};
|
uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
|
||||||
uint8_t datalen = 4;
|
uint8_t datalen = 4;
|
||||||
|
@ -969,7 +952,7 @@ static bool HF14B_Other_Reader(bool verbose) {
|
||||||
static int CmdHF14BReader(const char *Cmd) {
|
static int CmdHF14BReader(const char *Cmd) {
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (cmdp == 'h') return usage_hf_14b_reader();
|
if (cmdp == 'h') return usage_hf_14b_reader();
|
||||||
bool verbose = !(cmdp == 's');
|
bool verbose = (cmdp == 'v');
|
||||||
return readHF14B(verbose);
|
return readHF14B(verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1806,19 +1789,20 @@ int infoHF14B(bool verbose) {
|
||||||
int readHF14B(bool verbose) {
|
int readHF14B(bool verbose) {
|
||||||
|
|
||||||
// try std 14b (atqb)
|
// try std 14b (atqb)
|
||||||
if (HF14B_Std_Reader(verbose))
|
if (HF14B_std_reader(verbose))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// try ST Microelectronics 14b
|
// try ST Microelectronics 14b
|
||||||
if (HF14B_ST_Reader(verbose))
|
if (HF14B_st_reader(verbose))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// try ASK CT 14b
|
||||||
|
if (HF14B_ask_ct_reader(verbose))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// 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 (HF14B_Other_Reader(verbose))
|
if (HF14B_other_reader(verbose))
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (HF14B_ask_ct_Reader(verbose))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
|
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue