diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 97c7544ce..4d7f74c8c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -34,6 +34,7 @@ #include "iclass_cmd.h" #include "hfops.h" #include "iso14443a.h" +#include "secc.h" #include "iso14443b.h" #include "iso15693.h" #include "thinfilm.h" @@ -1837,6 +1838,11 @@ static void PacketReceived(PacketCommandNG *packet) { reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0); break; } + case CMD_HF_HIDCONFIG_SNIFF: { + SniffHIDConfigCard(packet->data.asBytes[0]); + reply_ng(CMD_HF_HIDCONFIG_SNIFF, PM3_SUCCESS, NULL, 0); + break; + } case CMD_HF_ISO14443A_READER: { ReaderIso14443a(packet); break; @@ -1898,6 +1904,10 @@ static void PacketReceived(PacketCommandNG *packet) { payload->getdata_response, payload->getdata_response_len); break; } + case CMD_HF_HIDCONFIG_SIM: { + SimulateHIDConfigCard((const hid_sim_payload_t *) packet->data.asBytes); + break; + } case CMD_HF_ISO14443A_ANTIFUZZ: { struct p { uint8_t flag; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f06dbd100..7fd193f2e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -38,8 +38,6 @@ #include "mifare.h" // for iso14a_polling_frame_t structure #include "cmac_calc.h" -#define MAX_ISO14A_TIMEOUT 524288 -// this timeout is in MS static uint32_t iso14a_timeout; static uint8_t colpos = 0; @@ -47,6 +45,10 @@ static uint8_t colpos = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; +// optional ATQA/SAK overrides for SimulateIso14443aInit (set via iso14a_set_atqa_sak_override) +static uint16_t s_atqa_override = 0; +static uint8_t s_sak_override = 0; + // // ISO14443 timing: // @@ -106,7 +108,7 @@ static uint16_t FpgaSendQueueDelay; // 8 ticks on average until the data is stored in to_arm. // + the delays in transferring data - which is the same for // sniffing reader and tag data and therefore not relevant -#define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) +// Delay defined in iso14443a.h as DELAY_READER_AIR2ARM_AS_SNIFFER //variables used for timing purposes: //these are in ssp_clk cycles: @@ -1233,8 +1235,22 @@ static void Simulate_read_ulaes_key0(uint8_t *ulaes_key0) { reverse_array(ulaes_key0 + 12, 4); } +void iso14a_set_atqa_sak_override(uint16_t atqa, uint8_t sak) { + s_atqa_override = atqa; + s_sak_override = sak; +} + +uint8_t iso14a_get_pcb_blocknum(void) { + return iso14_pcb_blocknum; +} + +void iso14a_toggle_pcb_blocknum(void) { + iso14_pcb_blocknum ^= 1; +} + bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, - uint8_t *ats, size_t ats_len, tag_response_info_t **responses, + uint8_t *ats, size_t ats_len, + tag_response_info_t **responses, uint32_t *cuid, uint8_t *pages, uint8_t *ulc_key) { uint8_t sak = 0; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@ -1472,6 +1488,11 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, } } + // Apply SAK override before it is encoded into rSAKc1/2/3. + if ( (flags & FLAG_SAK_IN_DATA) == FLAG_SAK_IN_DATA) { + sak = s_sak_override; + } + // if uid not supplied then get from emulator memory if ((memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10) == 0) || IS_FLAG_UID_IN_EMUL(flags)) { if (tagType == 2 || tagType == 7 || tagType == 13 || tagType == 14) { @@ -1565,6 +1586,12 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, return false; } + // Apply ATQA override after all UID-size bits have been set. + if ((flags & FLAG_ATQA_IN_DATA) == FLAG_ATQA_IN_DATA) { + rATQA[0] = (uint8_t)(s_atqa_override >> 8); + rATQA[1] = (uint8_t)(s_atqa_override & 0xFF); + } + AddCrc14A(rATS, rATS_len - 2); AddCrc14A(rPPS, sizeof(rPPS) - 2); @@ -1702,9 +1729,9 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u .modulation_n = 0 }; - if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len - , &responses, &cuid, &pages - , ulc_key) == false) { + if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, + &responses, &cuid, &pages, + ulc_key) == false) { BigBuf_free_keep_EM(); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); return; @@ -2417,8 +2444,8 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u } if (dynamic_response_info.response_n > 0) { - // Copy the CID from the reader query - if (tagType != 10) + // Copy the CID from the reader query (only when CID bit is set in PCB). + if (tagType != 10 && (receivedCmd[0] & 0x08)) dynamic_response_info.response[1] = receivedCmd[1]; // Add CRC bytes, always used in ISO 14443A-4 compliant cards diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index f00f686f8..b1e01c5e8 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -154,8 +154,12 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid, uint8_t *selectaid_response, size_t selectaid_response_len, uint8_t *getdata_response, size_t getdata_response_len); +void iso14a_set_atqa_sak_override(uint16_t atqa, uint8_t sak); +uint8_t iso14a_get_pcb_blocknum(void); +void iso14a_toggle_pcb_blocknum(void); bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, - uint8_t *ats, size_t ats_len, tag_response_info_t **responses, + uint8_t *ats, size_t ats_len, + tag_response_info_t **responses, uint32_t *cuid, uint8_t *pages, uint8_t *ulc_key); @@ -202,4 +206,20 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t rec_ extern iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS; extern iso14a_polling_parameters_t REQA_POLLING_PARAMETERS; +// Sniffer timing delays (carrier clock cycles), for use by external sniff loops. +#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) + +// When the PM acts as sniffer and is receiving reader data, it takes +// 2 ticks delay in analogue RF receiver (for the falling edge of the +// start bit, which marks the start of the communication) +// 3 ticks A/D conversion +// 8 ticks on average until the data is stored in to_arm. +// + the delays in transferring data - which is the same for +// sniffing reader and tag data and therefore not relevant +#define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) + +// Maximum ISO 14443A protocol timeout in field cycles (1/13.56 MHz). +#define MAX_ISO14A_TIMEOUT 524288 +// this timeout is in MS + #endif /* __ISO14443A_H */ diff --git a/armsrc/secc.c b/armsrc/secc.c index 04e5fbae7..c65e4bf34 100644 --- a/armsrc/secc.c +++ b/armsrc/secc.c @@ -28,7 +28,7 @@ #include "fpgaloader.h" // FpgaWriteConfWord, FpgaSetupSscDma #include "desfire_crypto.h" // tdes_nxp_send #include "mbedtls/des.h" // mbedtls_des_*, mbedtls_des3_* -#include "iso14443a.h" // ReaderTransmit, ReaderReceive, iso14a_get/set_timeout, iso14_pcb_blocknum, MAX_ISO14A_TIMEOUT +#include "iso14443a.h" // ReaderTransmit, ReaderReceive, iso14a_get/set_timeout, iso14a_get/toggle_pcb_blocknum, MAX_ISO14A_TIMEOUT #include "appmain.h" // tearoff_hook, send_wtx #include "util.h" // data_available, BUTTON_PRESS #include "cmd.h" // reply_ng @@ -251,12 +251,12 @@ int hid_config_card_iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chainin real_cmd[0] = 0x0A; // I-block, CID present (bit 3), block number in bit 0 if (send_chaining) real_cmd[0] |= 0x10; - real_cmd[0] |= iso14_pcb_blocknum; + real_cmd[0] |= iso14a_get_pcb_blocknum(); real_cmd[1] = 0x00; // CID = 0 (as negotiated in RATS) memcpy(real_cmd + 2, cmd, cmd_len); } else { real_cmd[0] = 0xAA; // R-block ACK + CID present - real_cmd[0] |= iso14_pcb_blocknum; + real_cmd[0] |= iso14a_get_pcb_blocknum(); real_cmd[1] = 0x00; // CID = 0 } AddCrc14A(real_cmd, cmd_len + 2); // PCB + CID + APDU @@ -297,8 +297,8 @@ int hid_config_card_iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chainin // Toggle block number on valid I-block or R(ACK) if (len >= 3 && ((data_bytes[0] & 0xC0) == 0 || (data_bytes[0] & 0xD0) == 0x80) - && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) { - iso14_pcb_blocknum ^= 1; + && (data_bytes[0] & 0x01) == iso14a_get_pcb_blocknum()) { + iso14a_toggle_pcb_blocknum(); } if (res) @@ -355,9 +355,8 @@ void SimulateHIDConfigCard(const hid_sim_payload_t *payload) { uint8_t uid[10]; memcpy(uid, payload->uid, sizeof(uid)); - // ATQA override: stored big-endian in payload, SimulateIso14443aInit takes uint16 uint16_t atqa_val = ((uint16_t)payload->atqa[0] << 8) | payload->atqa[1]; - uint8_t sak_val = payload->sak; + iso14a_set_atqa_sak_override(atqa_val, payload->sak); tag_response_info_t *responses; uint32_t cuid; @@ -365,7 +364,6 @@ void SimulateHIDConfigCard(const hid_sim_payload_t *payload) { if (SimulateIso14443aInit(4, flags, uid, (uint8_t *)payload->ats, payload->ats_len, - atqa_val, sak_val, &responses, &cuid, &pages, NULL) == false) { BigBuf_free_keep_EM(); reply_ng(CMD_HF_HIDCONFIG_SIM, PM3_EINIT, NULL, 0); diff --git a/client/resources/hidconfig_sample.json b/client/resources/hidconfig_sample.json index f990a1f12..7d0a526cd 100644 --- a/client/resources/hidconfig_sample.json +++ b/client/resources/hidconfig_sample.json @@ -1,5 +1,5 @@ { - "UID": "8F042795", + "UID": "00000000", "AID": "A0000003820013000101", "SCP02Key": "404142434445464748494A4B4C4D4E4F", "ATS": "1478F7B10280590180415254454346477300011B", diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index ad37bdf59..3569126a1 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -32,6 +32,7 @@ #include "cmdhfemrtd.h" // eMRTD #include "cmdhffelica.h" // ISO18092 / FeliCa #include "cmdhffido.h" // FIDO authenticators +#include "cmdhfsecc.h" // iClass SE Config Card #include "cmdhffudan.h" // Fudan cards #include "cmdhfgallagher.h" // Gallagher DESFire cards #include "cmdhfgst.h" // Google Smart Tap @@ -588,6 +589,7 @@ static command_t CommandTable[] = { {"fudan", CmdHFFudan, AlwaysAvailable, "{ Fudan RFIDs... }"}, {"gallagher", CmdHFGallagher, AlwaysAvailable, "{ Gallagher DESFire RFIDs... }"}, {"gst", CmdHFGST, AlwaysAvailable, "{ Google Smart Tap passes... }"}, + {"secc", CmdHFHIDConfig, AlwaysAvailable, "{ iClass SE Config Card Emulator... }"}, {"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"}, {"ict", CmdHFICT, AlwaysAvailable, "{ ICT MFC/DESfire RFIDs... }"}, {"jooki", CmdHF_Jooki, AlwaysAvailable, "{ Jooki RFIDs... }"},