From 31f5502171d2a5b59861d3d46d5c009a8d8e9790 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 2 Oct 2020 14:31:52 +0200 Subject: [PATCH] remade ASK C-ticket select to deviceside --- armsrc/felica.c | 2 +- armsrc/iso14443b.c | 93 +++++++++++++++++++++++++++-- armsrc/iso14443b.h | 2 +- client/src/cmdhf14b.c | 134 +++++++++++++++++++----------------------- 4 files changed, 149 insertions(+), 82 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 53f78d17b..aafdae5d8 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -9,7 +9,7 @@ #include "commonutil.h" #include "dbprint.h" #include "ticks.h" -#include "mifare.h" +#include "iso18.h" // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index be8b820e0..e4fe67a64 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -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 + //Demod.posCount = 10 * 2; + Demod.bitCount = 0; + Demod.len = 0; Demod.state = WAIT_FOR_RISING_EDGE_OF_SOF; + break; } } Demod.posCount = 0; @@ -1253,6 +1257,79 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, uint8 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. */ @@ -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); FpgaDisableTracing(); - if (retlen <= 0) + if (retlen <= 0) { return -1; + } // Randomly generated Chip ID if (card) { @@ -1295,8 +1373,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { if (retlen != 3) { return -1; } - - // Check the CRC of the answer: if (!check_crc(CRC_14443_B, r_select, retlen)) { return -2; } @@ -1321,8 +1397,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { if (retlen != 10) { return -1; } - - // The check the CRC of the answer if (!check_crc(CRC_14443_B, r_papid, retlen)) { return -2; } @@ -1793,6 +1867,15 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) { 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) { status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf)); sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE); diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 84c264c92..3fde4ffe0 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -15,7 +15,7 @@ #include "common.h" -#include "mifare.h" +#include "iso14b.h" #include "pm3_cmd.h" #ifndef AddCrc14A diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 9bdeb8c91..fe496919e 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -11,6 +11,7 @@ #include "cmdhf14b.h" #include +#include "iso14b.h" #include "fileutils.h" #include "cmdparser.h" // command_t #include "commonutil.h" // ARRAYLEN @@ -43,10 +44,10 @@ static int usage_hf_14b_info(void) { return PM3_SUCCESS; } 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, " h this help"); - PrintAndLogEx(NORMAL, " s silently"); + PrintAndLogEx(NORMAL, " v verbose"); PrintAndLogEx(NORMAL, "Example:"); PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b reader")); 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)); } +// 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 // 05 00 00 = find one tag in field // 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); } -static bool HF14B_ST_Reader(bool verbose) { +static bool HF14B_st_reader(bool verbose) { bool is_success = false; @@ -751,22 +766,22 @@ static bool HF14B_ST_Reader(bool verbose) { is_success = true; break; case -1: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST ATTRIB fail"); break; case -2: - if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CRC fail"); + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ST CRC fail"); break; 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; 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; } return is_success; } -static bool HF14B_Std_Reader(bool verbose) { +static bool HF14B_std_reader(bool verbose) { bool is_success = false; @@ -810,77 +825,45 @@ static bool HF14B_Std_Reader(bool verbose) { return is_success; } -static bool HF14B_ask_ct_Reader(bool verbose) { - uint8_t cmd1[] = {0x10}; - uint8_t cmd2[] = {0x9F, 0xFF, 0xFF}; - uint8_t cmd3[] = {0xC4}; - uint8_t uid[4]; - uint8_t pc, fc; +static bool HF14B_ask_ct_reader(bool verbose) { + + bool is_success = false; // 14b get and print UID only (general info) - uint32_t flags = ISO14B_CONNECT | ISO14B_RAW | ISO14B_APPEND_CRC; + clearCommandBuffer(); PacketResponseNG resp; - int status; - - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, sizeof(cmd1), 0, cmd1, sizeof(cmd1)); - - if (!WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { + 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) { if (verbose) PrintAndLogEx(WARNING, "command execution timeout"); - switch_off_field_14b(); return false; } - status = resp.oldarg[0]; - PrintAndLogEx(DEBUG, "status cmd1 %d", status); - if (status == 4) { - pc = resp.data.asBytes[0]; - fc = resp.data.asBytes[1]; - } else { - switch_off_field_14b(); - return false; - } - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, sizeof(cmd2), 0, cmd2, sizeof(cmd2)); - 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 cmd2 %d", status); - if (status == 4) { - 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; + int status = resp.oldarg[0]; + + switch (status) { + case 0: { + print_ct_general_info(resp.data.asBytes); + is_success = true; + break; + } + case -1: { + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS wrong length"); + break; + } + case -2: { + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CTS CRC fail"); + break; + } + default: { + if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b CTS card select failed"); + break; + } } + return is_success; } // 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 datalen = 4; @@ -969,7 +952,7 @@ static bool HF14B_Other_Reader(bool verbose) { static int CmdHF14BReader(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_14b_reader(); - bool verbose = !(cmdp == 's'); + bool verbose = (cmdp == 'v'); return readHF14B(verbose); } @@ -1806,19 +1789,20 @@ int infoHF14B(bool verbose) { int readHF14B(bool verbose) { // try std 14b (atqb) - if (HF14B_Std_Reader(verbose)) + if (HF14B_std_reader(verbose)) return 1; // 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; // try unknown 14b read commands (to be identified later) // could be read of calypso, CEPAS, moneo, or pico pass. - if (HF14B_Other_Reader(verbose)) - return 1; - - if (HF14B_ask_ct_Reader(verbose)) + if (HF14B_other_reader(verbose)) return 1; if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");