diff --git a/CHANGELOG.md b/CHANGELOG.md index 717908287..a2ec5c1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Changed `lf search` - to identify hitag2/s/82xx in chipset detection to preserve their EM4100 or other outputs (@iceman1001) +- Added `lf hitag hts reader` - to act as a HitagS / 82xx reader (@iceman1001) +- Changed `lf hitag hts write` -> ´lf hitag hts wdbl` to fit rest of client command names (@iceman1001) +- Changed `lf hitag hts read` -> ´lf hitag hts rdbl` to fit rest of client command names (@iceman1001) - Changed `hf mf info` - Better handling when printing ATS (@iceman1001) - Changed to also try the MFC_B key when extracting memory (@iceman1001) - Fix parallel `make -j check` Thanks @elboulangero (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 64c39aff6..6d57c5a1e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1165,21 +1165,25 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content - SimulateHitagSTag((bool)packet->oldarg[0], packet->data.asBytes, true); + hts_simulate((bool)packet->oldarg[0], packet->data.asBytes, true); break; } case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file - Hitag_check_challenges(packet->data.asBytes, packet->length, true); + hts_check_challenges(packet->data.asBytes, packet->length, true); break; } case CMD_LF_HITAGS_READ: { // Reader for only Hitag S tags, args = key or challenge lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes; - ReadHitagS(payload, true); + hts_read(payload, true); break; } case CMD_LF_HITAGS_WRITE: { lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes; - WritePageHitagS(payload, true); + hts_write_page(payload, true); + break; + } + case CMD_LF_HITAGS_UID: { + hts_read_uid(NULL, false, true); break; } case CMD_LF_HITAG2_WRITE: { diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index d25c8ee08..460277568 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -2585,7 +2585,6 @@ bool ht2_packbits(uint8_t *nrz_samples, size_t nrzs, uint8_t *rx, size_t *rxlen) } return true; } - int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_field_up) { g_logging = false; @@ -2595,6 +2594,7 @@ int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_fiel clear_trace(); } + // hitag 2 state machine? hitag2_init(); diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 3a7b52e4b..3327e34fe 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -347,7 +347,7 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool LOW(GPIO_SSC_DOUT); } -static void hitagS_init_clock(void) { +static void hts_init_clock(void) { // Enable Peripheral Clock for // Timer Counter 0, used to measure exact timing before answering @@ -390,7 +390,7 @@ static void hitagS_init_clock(void) { // Dbprintf("TC0_CV0:%i TC0_CV:%i TC1_CV:%i", cv0, AT91C_BASE_TC0->TC_CV, AT91C_BASE_TC1->TC_CV); } -static void hitagS_stop_clock(void) { +static void hts_stop_clock(void) { AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; } @@ -421,7 +421,7 @@ static int check_select(const uint8_t *rx, uint32_t uid) { return 0; } -static void hitagS_set_frame_modulation(void) { +static void hts_set_frame_modulation(void) { switch (tag.mode) { case HT_STANDARD: { sof_bits = 1; @@ -447,8 +447,8 @@ static void hitagS_set_frame_modulation(void) { /* * handles all commands from a reader */ -static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, - uint8_t *tx, size_t *txlen) { +static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen, + uint8_t *tx, size_t *txlen) { uint8_t rx_air[HITAG_FRAME_LEN]; uint64_t state; unsigned char crc; @@ -463,14 +463,16 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, switch (rxlen) { case 5: { //UID request with a selected response protocol mode - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("UID request: length: %i first byte: %02x", rxlen, rx[0]); + } tag.pstate = HT_READY; tag.tstate = HT_NO_OP; if ((rx[0] & 0xf0) == HITAGS_UID_REQ_STD) { - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("HT_STANDARD"); + } tag.mode = HT_STANDARD; sof_bits = 1; @@ -478,16 +480,18 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } if ((rx[0] & 0xf0) == HITAGS_UID_REQ_ADV) { tag.mode = HT_ADVANCED; - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("HT_ADVANCED"); + } sof_bits = 3; m = AC2K; } if ((rx[0] & 0xf0) == HITAGS_UID_REQ_FADV) { - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("HT_FAST_ADVANCED"); + } tag.mode = HT_FAST_ADVANCED; sof_bits = 3; @@ -513,7 +517,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //if the right tag was selected *txlen = 32; - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); //send configuration for (int i = 0; i < 4; i++) { @@ -541,6 +545,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, Dbprintf("Challenge for UID: %X", temp_uid); temp2++; *txlen = 32; + // init crypt engine state = ht2_hitag2_init(REV64(tag.key), REV32((tag.pages[0][3] << 24) + (tag.pages[0][2] << 16) + (tag.pages[0][1] << 8) + tag.pages[0][0]), REV32((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0]) @@ -550,7 +555,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, rx[4], rx[5], rx[6], rx[7] ); - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); for (int i = 0; i < 4; i++) { ht2_hitag2_byte(&state); @@ -593,8 +598,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, break; } case 40: { - if (g_dbglevel >= DBG_EXTENDED) + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("WRITE DATA"); + } + //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; @@ -606,7 +613,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, *txlen = 2; tx[0] = 0x40; page_to_be_written = 0; - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { tag.pages[page_to_be_written][0] = rx[0]; @@ -616,7 +623,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //send ack *txlen = 2; tx[0] = 0x40; - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); page_to_be_written++; block_data_left--; @@ -642,7 +649,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, tx[3] = 0xFF; } - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -673,7 +680,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, tx[3 + i * 4] = tag.pages[page + 3 + i * 4][3]; } - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -709,7 +716,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } else if ((rx[0] & 0xf0) == HITAGS_WRITE_BLOCK) { //write block uint8_t page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); - hitagS_set_frame_modulation(); + hts_set_frame_modulation(); if (page % 4 != 0 || page == 0) { //deny @@ -737,7 +744,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, /* * Emulates a Hitag S Tag with the given data from the .hts file */ -void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { +void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { StopTicks(); @@ -961,7 +968,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Process the incoming frame (rx) and prepare the outgoing frame (tx) - hitagS_handle_reader_command(rx, rxlen, tx, &txlen); + hts_handle_reader_command(rx, rxlen, tx, &txlen); // Wait for HITAG_T_WAIT_RESP carrier periods after the last reader bit, // not that since the clock counts since the rising edge, but T_Wait1 is @@ -1003,7 +1010,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr DbpString("Sim Stopped"); } -static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol) { +static void hts_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol) { // Reset values for receiving frames memset(rx, 0x00, sizeofrx); @@ -1102,13 +1109,14 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui } } } + if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("RX0 %i:%02X.. err:%i resptime:%i h2:%i h3:%i h4:%i edges:", *rxlen, rx[0], errorCount, *resptime, h2, h3, h4); Dbhexdump(ra_i, edges, false); } } -static void sendReceiveHitagS(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) { +static void hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) { LogTraceBits(tx, txlen, HITAG_T_WAIT_SC, HITAG_T_WAIT_SC, true); @@ -1131,7 +1139,7 @@ static void sendReceiveHitagS(const uint8_t *tx, size_t txlen, uint8_t *rx, size uint32_t resptime = 0; size_t rxlen = 0; - hitagS_receive_frame(rx, sizeofrx, &rxlen, &resptime, ledcontrol); + hts_receive_frame(rx, sizeofrx, &rxlen, &resptime, ledcontrol); int k = 0; // Check if frame was captured and store it @@ -1216,7 +1224,7 @@ static size_t concatbits(uint8_t *dst, size_t dstskip, const uint8_t *src, size_ return dstskip + srclen; } -static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeoftx, uint8_t *rx, size_t sizeofrx, int t_wait, bool ledcontrol) { +static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeoftx, uint8_t *rx, size_t sizeofrx, int t_wait, bool ledcontrol) { StopTicks(); @@ -1228,7 +1236,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo if (ledcontrol) LED_D_ON(); - hitagS_init_clock(); + hts_init_clock(); // Set fpga in edge detect with reader field, we can modulate as reader now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); @@ -1251,7 +1259,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo size_t rxlen = 0; uint8_t cmd = HITAGS_UID_REQ_ADV; txlen = concatbits(tx, txlen, &cmd, 0, 5); - sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, true); + hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, true); if (rxlen != 32) { DbpString("UID Request failed!"); @@ -1264,7 +1272,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo Dbprintf("UID: %02X %02X %02X %02X", rx[0], rx[1], rx[2], rx[3]); } - //select uid + // select uid txlen = 0; cmd = HITAGS_SELECT; txlen = concatbits(tx, txlen, &cmd, 0, 5); @@ -1272,7 +1280,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo uint8_t crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if (rxlen != 40) { Dbprintf("Select UID failed! %i", rxlen); @@ -1315,14 +1323,16 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo } if (tag.auth == 1) { + uint64_t key = 0; - //if the tag is in authentication mode try the key or challenge + // if the tag is in authentication mode try the key or challenge if (packet->cmd == RHTSF_KEY || packet->cmd == WHTSF_KEY) { if (g_dbglevel >= DBG_EXTENDED) { DbpString("Authenticating using key:"); Dbhexdump(6, packet->key, false); } + key = ((uint64_t)packet->key[0]) << 0 | ((uint64_t)packet->key[1]) << 8 | ((uint64_t)packet->key[2]) << 16 | @@ -1375,7 +1385,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo } else if (packet->cmd == RHTSF_82xx || packet->cmd == WHTSF_82xx) { // 8268/8310 Authentication by writing password to block 64 - //send write page request + // send write page request txlen = 0; cmd = HITAGS_WRITE_PAGE; txlen = concatbits(tx, txlen, &cmd, 0, 4); @@ -1386,7 +1396,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) { Dbprintf("no write access on page " _YELLOW_("64") ". not 82xx?"); @@ -1398,7 +1408,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) { Dbprintf("write to page " _YELLOW_("64") " failed! wrong password?"); @@ -1414,7 +1424,7 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo return -1; } - sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if (rxlen != 40) { Dbprintf("Authenticate failed! " _RED_("%i"), rxlen); @@ -1458,14 +1468,13 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo * If the key was given the password will be decrypted. * Reads every page of a hitag S transpoder. */ -void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { +void hts_read(const lf_hitag_data_t *payload, bool ledcontrol) { + + uint8_t rx[HITAG_FRAME_LEN] = { 0x00 }; + uint8_t tx[HITAG_FRAME_LEN] = { 0x00 }; + int status = PM3_SUCCESS; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - - uint8_t tx[HITAG_FRAME_LEN]; - - if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) { + if (hts_select_tag(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) { status = PM3_ERFTRANS; goto read_end; } @@ -1476,6 +1485,8 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { WDT_HIT(); + size_t rxlen = 0; + //send read request size_t txlen = 0; uint8_t cmd = HITAGS_READ_PAGE; @@ -1485,7 +1496,7 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { uint8_t crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if (rxlen != 40) { Dbprintf("Read page failed!"); @@ -1537,13 +1548,14 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { // since page 2+3 are not accessible when LKP == 1 and AUT == 1 fastforward to next readable page pageNum = 4; } + if (pageNum >= tag.max_page) { break; } } read_end: - hitagS_stop_clock(); + hts_stop_clock(); set_tracing(false); lf_finalize(ledcontrol); reply_ng(CMD_LF_HITAGS_READ, status, (uint8_t *)tag.pages, sizeof(tag.pages)); @@ -1553,7 +1565,7 @@ read_end: * Authenticates to the Tag with the given Key or Challenge. * Writes the given 32Bit data into page_ */ -void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { +void hts_write_page(const lf_hitag_data_t *payload, bool ledcontrol) { //check for valid input if (payload->page == 0) { @@ -1570,7 +1582,7 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { int res = PM3_ESOFT; - if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) { + if (hts_select_tag(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) { res = PM3_ERFTRANS; goto write_end; } @@ -1594,7 +1606,7 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { uint8_t crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) { Dbprintf("no write access on page " _YELLOW_("%d"), payload->page); @@ -1624,7 +1636,7 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { crc = CRC8Hitag1Bits(tx, txlen); txlen = concatbits(tx, txlen, &crc, 0, 8); - sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); + hts_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) { res = PM3_ESOFT; // write failed @@ -1633,12 +1645,73 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { } write_end: - hitagS_stop_clock(); + hts_stop_clock(); set_tracing(false); lf_finalize(ledcontrol); reply_ng(CMD_LF_HITAGS_WRITE, res, NULL, 0); } +int hts_read_uid(uint32_t *uid, bool ledcontrol, bool send_answer) { + + StopTicks(); + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); + + if (ledcontrol) LED_D_ON(); + + hts_init_clock(); + + // Set fpga in edge detect with reader field, we can modulate as reader now + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Configure output and enable pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; + + // Disable modulation at default, which means enable the field + LOW(GPIO_SSC_DOUT); + + // UID request standard 00110 + // UID request Advanced 1100x + // UID request FAdvanced 11010 + uint8_t cmd = HITAGS_UID_REQ_ADV; + + size_t rxlen = 0; + uint8_t rx[HITAG_FRAME_LEN] = { 0x00 }; + + size_t txlen = 0; + uint8_t tx[HITAG_FRAME_LEN] = { 0x00 }; + + txlen = concatbits(tx, txlen, &cmd, 0, 5); + + hts_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_FIRST, ledcontrol, true); + + int status = PM3_SUCCESS; + if (rxlen == 32) { + + tag.uid = (rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]); + if (uid) { + *uid = tag.uid; + } + + } else { + DbpString("UID Request failed!"); + status = PM3_ERFTRANS; + } + + hts_stop_clock(); + set_tracing(false); + lf_finalize(ledcontrol); + reply_ng(CMD_LF_HITAGS_UID, status, (uint8_t *)tag.pages, sizeof(tag.pages)); + return status; +} + /* * Tries to authenticate to a Hitag S Transponder with the given challenges from a .cc file. * Displays all Challenges that failed. @@ -1646,7 +1719,7 @@ write_end: * is not received correctly due to Antenna problems. This function * detects these challenges. */ -void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol) { +void hts_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol) { //check for valid input if (datalen < 8) { @@ -1669,7 +1742,7 @@ void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontr memcpy(payload.NrAr, data + dataoffset, 8); - int res = selectHitagS(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol); + int res = hts_select_tag(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol); Dbprintf("Challenge %s: %02X %02X %02X %02X %02X %02X %02X %02X", res == -1 ? "failed " : "success", payload.NrAr[0], payload.NrAr[1], @@ -1682,7 +1755,7 @@ void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontr // Need to do a dummy UID select that will fail FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(2); - selectHitagS(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol); + hts_select_tag(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol); } dataoffset += 8; @@ -1696,9 +1769,9 @@ void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontr SpinDelay(2); } - hitagS_stop_clock(); + hts_stop_clock(); set_tracing(false); lf_finalize(ledcontrol); - reply_ng(CMD_ACK, PM3_SUCCESS, NULL, 0); + reply_ng(CMD_LF_HITAGS_TEST_TRACES, PM3_SUCCESS, NULL, 0); return; } diff --git a/armsrc/hitagS.h b/armsrc/hitagS.h index 6278b1b18..8c49439dc 100644 --- a/armsrc/hitagS.h +++ b/armsrc/hitagS.h @@ -24,8 +24,9 @@ #include "common.h" #include "hitag.h" -void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol); -void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol); -void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol); -void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol); +void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol); +void hts_read(const lf_hitag_data_t *payload, bool ledcontrol); +void hts_write_page(const lf_hitag_data_t *payload, bool ledcontrol); +void hts_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol); +int hts_read_uid(uint32_t *uid, bool ledcontrol, bool send_answer); #endif diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 0db5cd416..7d4dcf983 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -413,7 +413,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align parity bits Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it return true; - } + } if (Uart.len & 0x0007) { // there are some parity bits to store Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align remaining parity bits @@ -812,12 +812,12 @@ void RAMFUNC SniffIso14443a(uint8_t param) { Uart.endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, Uart.parity, true)) { - break; - } + break; + } } // ready to receive another command Uart14aReset(); - // reset the demod code, which might have been + // reset the demod code, which might have been // false-triggered by the commands from the reader Demod14aReset(); LED_B_OFF(); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 413aef3e9..6f7c9cdfa 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4130,7 +4130,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandNG(CMD_HF_ISO14443A_GET_CONFIG, NULL, 0); if (!WaitForResponseTimeout(CMD_HF_ISO14443A_GET_CONFIG, &resp, 2000)) { PrintAndLogEx(WARNING, "command execution time out"); - return PM3_ETIMEOUT; + return PM3_ETIMEOUT; } memcpy(&config, resp.data.asBytes, sizeof(hf14a_config)); int8_t oldconfig_bcc = config.forcebcc; diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 5edb4a1dc..5943e6319 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -40,6 +40,7 @@ #include "cmdlfem4x70.h" // for em4x70 #include "cmdlfhid.h" // for hid menu #include "cmdlfhitag.h" // for hitag menu +#include "cmdlfhitaghts.h" // for hitag S sub commands #include "cmdlfidteck.h" // for idteck menu #include "cmdlfio.h" // for ioprox menu #include "cmdlfcotag.h" // for COTAG menu @@ -1555,7 +1556,9 @@ static bool check_chiptype(bool getDeviceData) { bool retval = false; - if (!getDeviceData) return retval; + if (getDeviceData == false) { + return retval; + } //Save the state of the Graph and Demod Buffers buffer_savestate_t saveState_gb = save_bufferS32(g_GraphBuffer, g_GraphTraceLen); @@ -1566,7 +1569,7 @@ static bool check_chiptype(bool getDeviceData) { //check for em4x05/em4x69 chips first uint32_t word = 0; - if (IfPm3EM4x50() && em4x05_isblock0(&word)) { + if (em4x05_isblock0(&word)) { PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05 / EM4x69")); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05`") " commands"); retval = true; @@ -1581,6 +1584,27 @@ static bool check_chiptype(bool getDeviceData) { goto out; } + + if (IfPm3Hitag()) { + + // Hitag 2 + if (ht2_read_uid() == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("Hitag 2")); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hitag`") " commands"); + retval = true; + goto out; + } + + // Hitag S + if (read_hts_uid() == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("Hitag S / 82xx")); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hitag hts`") " commands"); + retval = true; + goto out; + } + } + + #if !defined ICOPYX // check for em4x50 chips if (IfPm3EM4x50() && detect_4x50_block()) { @@ -1675,8 +1699,9 @@ int CmdLFfind(const char *Cmd) { CLIParserFree(ctx); int found = 0; bool is_online = (g_session.pm3_present && (use_gb == false)); - if (is_online) + if (is_online) { lf_read(false, 30000); + } size_t min_length = 2000; if (g_GraphTraceLen < min_length) { @@ -1697,17 +1722,6 @@ int CmdLFfind(const char *Cmd) { // only run these tests if device is online if (is_online) { - if (IfPm3Hitag()) { - if (readHitagUid() == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); - if (search_cont) { - found++; - } else { - return PM3_SUCCESS; - } - } - } - #if !defined ICOPYX if (IfPm3EM4x50()) { if (read_em4x50_uid() == PM3_SUCCESS) { diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 24b2c3fa4..ad94b1efe 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -794,7 +794,7 @@ static const char *identify_transponder_hitag2(uint32_t uid) { return ""; } -static bool getHitag2Uid(uint32_t *uid) { +static bool ht2_get_uid(uint32_t *uid) { lf_hitag_data_t packet; memset(&packet, 0, sizeof(packet)); @@ -835,7 +835,7 @@ static int CmdLFHitagInfo(const char *Cmd) { // read UID uint32_t uid = 0; - if (getHitag2Uid(&uid) == false) { + if (ht2_get_uid(&uid) == false) { return PM3_ESOFT; } // how to determine Hitag types? @@ -886,7 +886,7 @@ static int CmdLFHitagReader(const char *Cmd) { do { // read UID uint32_t uid = 0; - if (getHitag2Uid(&uid)) { + if (ht2_get_uid(&uid)) { PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); } } while (cm && kbd_enter_pressed() == false); @@ -2475,6 +2475,17 @@ static int CmdLFHitag2Selftest(const char *Cmd) { return PM3_SUCCESS; } +int ht2_read_uid(void) { + uint32_t uid = 0; + if (ht2_get_uid(&uid) == false) { + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); + PrintAndLogEx(SUCCESS, "TYPE... " _GREEN_("%s"), getHitagTypeStr(uid)); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"list", CmdLFHitagList, AlwaysAvailable, "List Hitag trace history"}, @@ -2515,14 +2526,4 @@ int CmdLFHitag(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -int readHitagUid(void) { - uint32_t uid = 0; - if (getHitag2Uid(&uid) == false) { - return PM3_ESOFT; - } - - PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); - PrintAndLogEx(SUCCESS, "TYPE... " _GREEN_("%s"), getHitagTypeStr(uid)); - return PM3_SUCCESS; -} diff --git a/client/src/cmdlfhitag.h b/client/src/cmdlfhitag.h index b50cc632c..08d141aa3 100644 --- a/client/src/cmdlfhitag.h +++ b/client/src/cmdlfhitag.h @@ -27,7 +27,7 @@ int CmdLFHitag(const char *Cmd); -int readHitagUid(void); +int ht2_read_uid(void); void annotateHitag1(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response); void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, uint8_t bits, bool is_response, const uint64_t *keys, uint32_t keycount, bool isdecrypted); void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response); diff --git a/client/src/cmdlfhitaghts.c b/client/src/cmdlfhitaghts.c index 2fe40238b..a686560a0 100644 --- a/client/src/cmdlfhitaghts.c +++ b/client/src/cmdlfhitaghts.c @@ -36,27 +36,84 @@ static int CmdHelp(const char *Cmd); +static const char *hts_get_type_str(uint32_t uid) { + //uid s/n ******** + uint8_t type = (uid >> 4) & 0xF; + switch (type) { + case 1: + return "PCF 7936"; + case 2: + return "PCF 7946"; + case 3: + return "PCF 7947"; + case 4: + return "PCF 7942/44"; + case 5: + return "PCF 7943"; + case 6: + return "PCF 7941"; + case 7: + return "PCF 7952"; + case 9: + return "PCF 7945"; + default: + return ""; + } +} + +static bool hts_get_uid(uint32_t *uid) { + clearCommandBuffer(); + SendCommandNG(CMD_LF_HITAGS_UID, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_LF_HITAGS_UID, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return false; + } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - failed getting UID"); + PrintAndLogEx(WARNING, "got false"); + return false; + } + + if (uid) { + *uid = bytes_to_num(resp.data.asBytes, HITAG_UID_SIZE); + } + return true; +} + +int read_hts_uid(void) { + uint32_t uid = 0; + if (hts_get_uid(&uid) == false) { + PrintAndLogEx(WARNING, "got false"); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); + PrintAndLogEx(SUCCESS, "TYPE... " _GREEN_("%s"), hts_get_type_str(uid)); + return PM3_SUCCESS; +} static int CmdLFHitagSRead(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "lf hitag hts read", + CLIParserInit(&ctx, "lf hitag hts rdbl", "Read Hitag S memory.\n\n" " Crypto mode: \n" " - key format ISK high + ISK low\n" " - default key 4F4E4D494B52 (ONMIKR)\n\n" " 8268/8310 password mode: \n" " - default password BBDD3399\n", - " lf hitag hts read -> Hitag S/8211, plain mode\n" - " lf hitag hts read --8 -k BBDD3399 -> 8268/8310, password mode\n" - " lf hitag hts read --nrar 0102030411223344 -> Hitag S, challenge mode\n" - " lf hitag hts read --crypto -> Hitag S, crypto mode, def key\n" - " lf hitag hts read -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" + " lf hitag hts rdbl -> Hitag S/8211, plain mode\n" + " lf hitag hts rdbl --8 -k BBDD3399 -> 8268/8310, password mode\n" + " lf hitag hts rdbl --nrar 0102030411223344 -> Hitag S, challenge mode\n" + " lf hitag hts rdbl --crypto -> Hitag S, crypto mode, def key\n" + " lf hitag hts rdbl -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" ); void *argtable[] = { arg_param_begin, arg_str0(NULL, "nrar", "", "nonce / answer writer, 8 hex bytes"), - arg_lit0(NULL, "8", "8268/8310 mode"), + arg_lit0("8", "82xx", "8268/8310 mode"), arg_lit0(NULL, "crypto", "crypto mode"), arg_str0("k", "key", "", "pwd or key, 4 or 6 hex bytes"), arg_param_end @@ -103,13 +160,16 @@ static int CmdLFHitagSRead(const char *Cmd) { if (key_len == 4) { use_82xx = true; } + if (key_len == 6) { use_crypto = true; } + if ((key_len == 0) && use_82xx) { - memcpy(key, (uint8_t[]) {0xBB, 0xDD, 0x33, 0x99}, 4); + memcpy(key, "\xBB\xDD\x33\x99", 4); key_len = 4; } + if ((key_len == 0) && use_crypto) { memcpy(key, "ONMIKR", 6); key_len = 6; @@ -120,7 +180,9 @@ static int CmdLFHitagSRead(const char *Cmd) { if (auth_methods > 1) { PrintAndLogEx(WARNING, "Specify only one authentication mode"); return PM3_EINVARG; - } else if (auth_methods == 0) { + } + + if (auth_methods == 0) { use_plain = true; } @@ -176,7 +238,8 @@ static int CmdLFHitagSRead(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Data") " ----------------------------------"); - uint32_t size = (const int[]) {4, 32, 256, 0}[config.memory_type]; + const int hts_mem_sizes[] = {4, 32, 256, 0}; + uint32_t size = hts_mem_sizes[config.memory_type]; print_hex_break(data, size, HITAGS_PAGE_SIZE); @@ -185,18 +248,18 @@ static int CmdLFHitagSRead(const char *Cmd) { static int CmdLFHitagSWrite(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "lf hitag hts write", + CLIParserInit(&ctx, "lf hitag hts wrbl", "Write a page in Hitag S memory.\n" " Crypto mode: \n" " - key format ISK high + ISK low\n" " - default key 4F4E4D494B52 (ONMIKR)\n\n" " 8268/8310 password mode: \n" " - default password BBDD3399\n", - " lf hitag hts write -p 6 -d 01020304 -> Hitag S/8211, plain mode\n" - " lf hitag hts write -p 6 -d 01020304 --8 -k BBDD3399 -> 8268/8310, password mode\n" - " lf hitag hts write -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n" - " lf hitag hts write -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n" - " lf hitag hts write -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" + " lf hitag hts wrbl -p 6 -d 01020304 -> Hitag S/8211, plain mode\n" + " lf hitag hts wrbl -p 6 -d 01020304 --8 -k BBDD3399 -> 8268/8310, password mode\n" + " lf hitag hts wrbl -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n" + " lf hitag hts wrbl -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n" + " lf hitag hts wrbl -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" ); void *argtable[] = { @@ -327,28 +390,40 @@ static int CmdLFHitagSWrite(const char *Cmd) { return PM3_SUCCESS; } -static int CmdLFHitagSList(const char *Cmd) { - return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags"); -} +static int CmdLFHitagSReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf hitag hts reader", + "Act as a Hitag S reader. Look for Hitag S tags until Enter or the pm3 button is pressed\n", + "lf hitag hts reader\n" + "lf hitag hts reader -@ -> Continuous mode" + ); -static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"}, - {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"}, - {"read", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S memory"}, - {"write", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"}, - {NULL, NULL, 0, NULL} -}; + void *argtable[] = { + arg_param_begin, + arg_lit0("@", NULL, "continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool cm = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + do { + // read UID + uint32_t uid = 0; + if (hts_get_uid(&uid)) { + PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); + } + } while (cm && kbd_enter_pressed() == false); -static int CmdHelp(const char *Cmd) { - (void) Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); return PM3_SUCCESS; } -int CmdLFHitagS(const char *Cmd) { - clearCommandBuffer(); - return CmdsParse(CommandTable, Cmd); +static int CmdLFHitagSList(const char *Cmd) { + return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags"); } hitags_config_t hitags_config_unpack(const uint8_t *config_bytes) { @@ -391,3 +466,26 @@ void hitags_config_print(hitags_config_t config) { PrintAndLogEx(INFO, " Config locked.... %s", config.lock_config ? _RED_("Yes") : _GREEN_("No")); PrintAndLogEx(INFO, " Key/PWD locked... %s", config.lock_key ? _RED_("Yes") : _GREEN_("No")); } + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"}, + {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"}, + {"reader", CmdLFHitagSReader, IfPm3Hitag, "Act like a Hitag S reader"}, + {"rdbl", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S memory"}, + {"wrbl", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"}, + {NULL, NULL, 0, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void) Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFHitagS(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + + diff --git a/client/src/cmdlfhitaghts.h b/client/src/cmdlfhitaghts.h index 7849d5f85..298abe9ae 100644 --- a/client/src/cmdlfhitaghts.h +++ b/client/src/cmdlfhitaghts.h @@ -56,10 +56,9 @@ typedef struct { int CmdLFHitagS(const char *Cmd); +int read_hts_uid(void); hitags_config_t hitags_config_unpack(const uint8_t *config_bytes); - void hitags_config_pack(hitags_config_t config, uint8_t *out); - void hitags_config_print(hitags_config_t config); #endif //CMDLFHITAGS_H__ diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 063cc9a58..ebe119a78 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -210,7 +210,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key) { if (key) { - *key = -1; + *key = -1; } clearCommandBuffer(); uint8_t data[PM3_CMD_DATA_SIZE] = {0}; diff --git a/client/src/pm3line_vocabulary.h b/client/src/pm3line_vocabulary.h index 7407dc76a..a610475b1 100644 --- a/client/src/pm3line_vocabulary.h +++ b/client/src/pm3line_vocabulary.h @@ -273,6 +273,7 @@ const static vocabulary_t vocabulary[] = { { 0, "hf iclass reader" }, { 0, "hf iclass restore" }, { 0, "hf iclass sniff" }, + { 0, "hf iclass spoof" }, { 1, "hf iclass view" }, { 0, "hf iclass wrbl" }, { 0, "hf iclass creditepurse" }, @@ -671,8 +672,9 @@ const static vocabulary_t vocabulary[] = { { 0, "lf hitag ta" }, { 1, "lf hitag hts help" }, { 1, "lf hitag hts list" }, - { 0, "lf hitag hts read" }, - { 0, "lf hitag hts write" }, + { 0, "lf hitag hts reader" }, + { 0, "lf hitag hts rdbl" }, + { 0, "lf hitag hts wrbl" }, { 1, "lf idteck help" }, { 1, "lf idteck demod" }, { 0, "lf idteck reader" }, diff --git a/doc/commands.json b/doc/commands.json index 5fc774ada..f85dc4d3f 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -865,13 +865,13 @@ "-j, --jload Load transaction parameters from `emv_defparams.json` file", "--force Force search AID. Search AID instead of execute PPSE", "By default: Transaction type - MSD", - "-v, --qvsdc Transaction type - qVSDC or M/Chip", + "--qvsdc Transaction type - qVSDC or M/Chip", "-c, --qvsdccda Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)", "-x, --vsdc Transaction type - VSDC. For test only. Not a standard behavior", "-g, --acgpo VISA. generate AC from GPO", "-w, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], - "usage": "emv exec [-hsatjvcxgw] [--force] By default:" + "usage": "emv exec [-hsatjcxgw] [--force] By default: [--qvsdc]" }, "emv genac": { "command": "emv genac", @@ -1046,7 +1046,7 @@ "-e, --extract Extract TLV elements and fill Application Data", "-j, --jload Load transaction parameters from `emv_defparams.json` file", "By default: Transaction type - MSD", - "-v, --qvsdc Transaction type - qVSDC or M/Chip", + "--qvsdc Transaction type - qVSDC or M/Chip", "-c, --qvsdccda Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)", "-x, --vsdc Transaction type - VSDC. For test only. Not a standard behavior", "-g, --acgpo VISA. generate AC from GPO", @@ -1054,7 +1054,7 @@ "-w, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " JSON output file name" ], - "usage": "emv scan [-hatejvcxgmw] By default: " + "usage": "emv scan [-hatejcxgmw] By default: [--qvsdc] " }, "emv search": { "command": "emv search", @@ -3617,6 +3617,19 @@ ], "usage": "hf iclass sniff [-hj]" }, + "hf iclass spoof": { + "command": "hf iclass spoof", + "description": "Watch 'nd Spoof, activates reader Waits until a Picopass tag gets presented then Proxmark3 tries to dump it and then starts simulating", + "notes": [ + "hf iclass spoof" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose Verbose output" + ], + "usage": "hf iclass spoof [-hv]" + }, "hf iclass view": { "command": "hf iclass view", "description": "Print a iCLASS tag dump file (bin/eml/json)", @@ -8552,12 +8565,12 @@ }, "lf em 410x clone": { "command": "lf em 410x clone", - "description": "clone a EM410x ID to a T55x7, Q5/T5555, EM4305/4469 or Hitag S/8211 tag.", + "description": "clone a EM410x ID to a T55x7, Q5/T5555, EM4305/4469 or Hitag S/8211/8268/8310 tag.", "notes": [ "lf em 410x clone --id 0F0368568B -> encode for T55x7 tag", "lf em 410x clone --id 0F0368568B --q5 -> encode for Q5/T5555 tag", "lf em 410x clone --id 0F0368568B --em -> encode for EM4305/4469", - "lf em 410x clone --id 0F0368568B --hs -> encode for Hitag S/8211" + "lf em 410x clone --id 0F0368568B --hts -> encode for Hitag S/8211/8268/8310" ], "offline": false, "options": [ @@ -8566,10 +8579,10 @@ "--id EM Tag ID number (5 hex bytes)", "--q5 optional - specify writing to Q5/T5555 tag", "--em optional - specify writing to EM4305/4469 tag", - "--hs optional - specify writing to Hitag S/8211 tag", + "--hts optional - specify writing to Hitag S/8211/8268/8310 tag", "--electra optional - add Electra blocks to tag" ], - "usage": "lf em 410x clone [-h] [--clk ] --id [--q5] [--em] [--hs] [--electra]" + "usage": "lf em 410x clone [-h] [--clk ] --id [--q5] [--em] [--hts] [--electra]" }, "lf em 410x reader": { "command": "lf em 410x reader", @@ -9726,43 +9739,61 @@ ], "usage": "lf hitag hts list [-h1crux] [--frame] [-f ]" }, - "lf hitag hts read": { - "command": "lf hitag hts read", - "description": "Read Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)", + "lf hitag hts rdbl": { + "command": "lf hitag hts rdbl", + "description": "Read Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR) 8268/8310 password mode: - default password BBDD3399", "notes": [ - "lf hitag hts read -> Hitag S, plain mode", - "lf hitag hts read --nrar 0102030411223344 -> Hitag S, challenge mode", - "lf hitag hts read --crypto -> Hitag S, crypto mode, def key", - "lf hitag hts read -k 4F4E4D494B52 -> Hitag S, crypto mode" + "lf hitag hts rdbl -> Hitag S/8211, plain mode", + "lf hitag hts rdbl --8 -k BBDD3399 -> 8268/8310, password mode", + "lf hitag hts rdbl --nrar 0102030411223344 -> Hitag S, challenge mode", + "lf hitag hts rdbl --crypto -> Hitag S, crypto mode, def key", + "lf hitag hts rdbl -k 4F4E4D494B52 -> Hitag S, crypto mode" ], "offline": false, "options": [ "-h, --help This help", "--nrar nonce / answer writer, 8 hex bytes", + "-8, --82xx 8268/8310 mode", "--crypto crypto mode", - "-k, --key key, 4 or 6 hex bytes" + "-k, --key pwd or key, 4 or 6 hex bytes" ], - "usage": "lf hitag hts read [-h] [--nrar ] [--crypto] [-k ]" + "usage": "lf hitag hts rdbl [-h8] [--nrar ] [--crypto] [-k ]" }, - "lf hitag hts write": { - "command": "lf hitag hts write", - "description": "Write a page in Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)", + "lf hitag hts reader": { + "command": "lf hitag hts reader", + "description": "Act as a Hitag S reader. Look for Hitag S tags until Enter or the pm3 button is pressed", "notes": [ - "lf hitag hts write -p 6 -d 01020304 -> Hitag S, plain mode", - "lf hitag hts write -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode", - "lf hitag hts write -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key", - "lf hitag hts write -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode" + "lf hitag hts reader", + "lf hitag hts reader -@ -> Continuous mode" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-@ continuous reader mode" + ], + "usage": "lf hitag hts reader [-h@]" + }, + "lf hitag hts wrbl": { + "command": "lf hitag hts wrbl", + "description": "Write a page in Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR) 8268/8310 password mode: - default password BBDD3399", + "notes": [ + "lf hitag hts wrbl -p 6 -d 01020304 -> Hitag S/8211, plain mode", + "lf hitag hts wrbl -p 6 -d 01020304 --8 -k BBDD3399 -> 8268/8310, password mode", + "lf hitag hts wrbl -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode", + "lf hitag hts wrbl -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key", + "lf hitag hts wrbl -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode" ], "offline": false, "options": [ "-h, --help This help", "--nrar nonce / answer writer, 8 hex bytes", + "--8 8268/8310 mode", "--crypto crypto mode", - "-k, --key key, 6 hex bytes", + "-k, --key pwd or key, 4 or 6 hex bytes", "-p, --page page address to write to", "-d, --data data, 4 hex bytes" ], - "usage": "lf hitag hts write [-h] [--nrar ] [--crypto] [-k ] -p -d " + "usage": "lf hitag hts wrbl [-h] [--nrar ] [--8] [--crypto] [-k ] -p -d " }, "lf hitag info": { "command": "lf hitag info", @@ -12669,9 +12700,9 @@ "", "trace list -t des -> interpret as MIFARE DESFire", "trace list -t felica -> interpret as ISO18092 / FeliCa", - "trace list -t hitag1 -> interpret as Hitag1", - "trace list -t hitag2 -> interpret as Hitag2", - "trace list -t hitags -> interpret as HitagS", + "trace list -t hitag1 -> interpret as Hitag 1", + "trace list -t hitag2 -> interpret as Hitag 2", + "trace list -t hitags -> interpret as Hitag S", "trace list -t iclass -> interpret as iCLASS", "trace list -t legic -> interpret as LEGIC", "trace list -t lto -> interpret as LTO-CM", @@ -12884,8 +12915,8 @@ } }, "metadata": { - "commands_extracted": 743, + "commands_extracted": 745, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2024-09-10T12:26:03" + "extracted_on": "2024-09-14T18:53:04" } } diff --git a/doc/commands.md b/doc/commands.md index a31c55984..51ec01a7f 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -396,6 +396,7 @@ Check column "offline" for their availability. |`hf iclass reader `|N |`Act like a Picopass / iCLASS reader` |`hf iclass restore `|N |`Restore a dump file onto a Picopass / iCLASS tag` |`hf iclass sniff `|N |`Eavesdrop Picopass / iCLASS communication` +|`hf iclass spoof `|N |`Watches for Picopass and replays them` |`hf iclass view `|Y |`Display content from tag dump file` |`hf iclass wrbl `|N |`Write Picopass / iCLASS block` |`hf iclass creditepurse `|N |`Credit epurse value` @@ -1075,8 +1076,9 @@ Check column "offline" for their availability. |------- |------- |----------- |`lf hitag hts help `|Y |`This help` |`lf hitag hts list `|Y |`List Hitag S trace history` -|`lf hitag hts read `|N |`Read Hitag S memory` -|`lf hitag hts write `|N |`Write Hitag S page` +|`lf hitag hts reader `|N |`Act like a Hitag S reader` +|`lf hitag hts rdbl `|N |`Read Hitag S memory` +|`lf hitag hts wrbl `|N |`Write Hitag S page` ### lf idteck diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index a8c5988f9..068898937 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -595,6 +595,7 @@ typedef struct { #define CMD_LF_HITAGS_SIMULATE 0x0368 #define CMD_LF_HITAGS_READ 0x0373 #define CMD_LF_HITAGS_WRITE 0x0375 +#define CMD_LF_HITAGS_UID 0x037A #define CMD_LF_HITAG_ELOAD 0x0376