diff --git a/CHANGELOG.md b/CHANGELOG.md index c58352779..c300c2d17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Changed split PacketResponseNG status into status and reason(@douniwan5788) +- add a helper script to decode JEDEC data `script run spi_flash_decode` (@ANTodorov) +- show SPI flash JEDEC Manufacturer ID and Device ID in `hw status` output (@ANTodorov) +- Improved `hf iclass configcards` to support generating config cards using a different key than the default k0 as the card's key (@antiklesys) - Added maur keys (@iceman1001) - Fixed `hf mfu pwdgen` for the 7 byte UID (@ANTodorov) - Added `hf iclass unhash` command to reverse an iclass diversified key to hash0 pre-images (@antiklesys) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1748522d4..1fba4a381 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2593,13 +2593,13 @@ static void SendForward(uint8_t fwd_bit_count, bool fast) { // 32FC * 8us == 256us / 21.3 == 12.018 steps. ok // 16FC * 8us == 128us / 21.3 == 6.009 steps. ok #ifndef EM_START_GAP -#define EM_START_GAP 55*8 +#define EM_START_GAP (55 * 8) #endif fwd_write_ptr = forwardLink_data; fwd_bit_sz = fwd_bit_count; - if (! fast) { + if (fast == false) { // Set up FPGA, 125kHz or 95 divisor LFSetupFPGAForADC(LF_DIVISOR_125, true); } @@ -2639,16 +2639,21 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitMS(20); if (ledcontrol) LED_A_ON(); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + uint32_t candidates_found = 0; for (uint32_t pwd = start_pwd; pwd < 0xFFFFFFFF; pwd++) { + if (((pwd - start_pwd) & 0x3F) == 0x00) { + WDT_HIT(); if (BUTTON_PRESS() || data_available()) { Dbprintf("EM4x05 Bruteforce Interrupted"); break; } } + // Report progress every 256 attempts if (((pwd - start_pwd) & 0xFF) == 0x00) { Dbprintf("Trying: %06Xxx", pwd >> 8); @@ -2662,7 +2667,9 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) { WaitUS(400); DoPartialAcquisition(0, false, 350, 1000, ledcontrol); + uint8_t *mem = BigBuf_get_addr(); + if (mem[334] < 128) { candidates_found++; Dbprintf("Password candidate: " _GREEN_("%08X"), pwd); @@ -2671,6 +2678,7 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) { break; } } + // Beware: if smaller, tag might not have time to be back in listening state yet WaitMS(1); } @@ -2719,7 +2727,9 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd, bool ledcontrol) { * 0000 1010 ok * 0000 0001 fail **/ - if (usepwd) EM4xLoginEx(pwd); + if (usepwd) { + EM4xLoginEx(pwd); + } forward_ptr = forwardLink_data; uint8_t len = Prepare_Cmd(FWD_CMD_READ); @@ -2754,7 +2764,9 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd, bo * 0000 1010 ok. * 0000 0001 fail **/ - if (usepwd) EM4xLoginEx(pwd); + if (usepwd) { + EM4xLoginEx(pwd); + } forward_ptr = forwardLink_data; uint8_t len = Prepare_Cmd(FWD_CMD_WRITE); @@ -2797,7 +2809,9 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd, bool ledcontro * 0000 1010 ok. * 0000 0001 fail **/ - if (usepwd) EM4xLoginEx(pwd); + if (usepwd) { + EM4xLoginEx(pwd); + } forward_ptr = forwardLink_data; uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT); diff --git a/client/pyscripts/spi_flash_decode.py b/client/pyscripts/spi_flash_decode.py new file mode 100644 index 000000000..3a8648b8f --- /dev/null +++ b/client/pyscripts/spi_flash_decode.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import re +import pm3 +# optional color support +try: + # pip install ansicolors + from colors import color +except ModuleNotFoundError: + def color(s, fg=None): + _ = fg + return str(s) + +spi = { + 0x85:{ + "manufacturer": "Puya", + 0x60: { + 0x15: { + "part": "P25Q16H", + "size": "16mbits", + "sizeB": "2MB", + }, + }, + }, + 0xEF:{ + "manufacturer": "Winbond", + 0x30: { + 0x11: { + "part": "W25X10BV", + "size": "1mbits", + "sizeB": "128KB", + }, + 0x12: { + "part": "W25X20BV", + "size": "2mbits", + "sizeB": "256KB", + }, + 0x13: { + "part": "W25X40BV", + "size": "4mbits", + "sizeB": "512KB", + }, + }, + 0x70: { + 0x22: { + "part": "W25Q02JV-IM", + "size": "2mbits", + "sizeB": "256KB", + }, + }, + }, + } + +p = pm3.pm3() + +p.console("hw status") + +rex = re.compile("...\s([0-9a-fA-F]{2})\s/\s([0-9a-fA-F]{4})") +for line in p.grabbed_output.split('\n'): + # [#] JEDEC Mfr ID / Dev ID... 85 / 6015 + if " JEDEC " not in line: + continue + match = re.findall(rex, line) + mid = int(match[0][0], 16) + did = int(match[0][1], 16) + did_h = did >> 8 + did_l = did & 0xff + t = None + if mid in spi: + mfr = spi[mid]['manufacturer'] + if did_h in spi[mid]: + if did_l in spi[mid][did_h]: + t = spi[mid][did_h][did_l] + print("\n Manufacturer... " + color(f"{mfr}", fg="green") + + "\n Device......... " + color(f"{t['part']}", fg="green") + + "\n Size........... " + color(f"{t['size']} ({t['sizeB']})", fg="yellow") + ) + else: + print("\n Manufacturer... " + color(f"{mfr}", fg="green") + + "\n Device ID...... " + color(f"{did:04X}h (unknown)", fg="red")) + else: + print("\n Manufacturer... " + color(f"{mfr}", fg="green") + + "\n Device ID...... " + color(f"{did:04X}h (unknown)", fg="red")) + else: + print("\n Manufacturer... " + color(f"{mid:02X}h (unknown)", fg="red") + + "\n Device ID...... " + color(f"{did:04X}h (unknown)", fg="red")) diff --git a/client/src/cmdflashmemspiffs.c b/client/src/cmdflashmemspiffs.c index 8fbb9b2de..fef35bb4d 100644 --- a/client/src/cmdflashmemspiffs.c +++ b/client/src/cmdflashmemspiffs.c @@ -262,9 +262,9 @@ static int CmdFlashMemSpiFFSRemove(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_REMOVE, (uint8_t *)&payload, sizeof(payload)); WaitForResponse(CMD_SPIFFS_REMOVE, &resp); - if (resp.status == PM3_SUCCESS) + if (resp.status == PM3_SUCCESS) { PrintAndLogEx(INFO, "Done!"); - + } return PM3_SUCCESS; } @@ -310,8 +310,9 @@ static int CmdFlashMemSpiFFSRename(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_RENAME, (uint8_t *)&payload, sizeof(payload)); WaitForResponse(CMD_SPIFFS_RENAME, &resp); - if (resp.status == PM3_SUCCESS) + if (resp.status == PM3_SUCCESS) { PrintAndLogEx(INFO, "Done!"); + } PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify"); return PM3_SUCCESS; @@ -358,8 +359,9 @@ static int CmdFlashMemSpiFFSCopy(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_COPY, (uint8_t *)&payload, sizeof(payload)); WaitForResponse(CMD_SPIFFS_COPY, &resp); - if (resp.status == PM3_SUCCESS) + if (resp.status == PM3_SUCCESS) { PrintAndLogEx(INFO, "Done!"); + } PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify"); return PM3_SUCCESS; @@ -474,8 +476,9 @@ static int CmdFlashMemSpiFFSWipe(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_WIPE, NULL, 0); WaitForResponse(CMD_SPIFFS_WIPE, &resp); - if (resp.status == PM3_SUCCESS) + if (resp.status == PM3_SUCCESS) { PrintAndLogEx(INFO, "Done!"); + } PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify"); return PM3_SUCCESS; diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 9414f1be7..c38e6da03 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -516,7 +516,7 @@ int CmdHFSniff(const char *Cmd) { } } } - PrintAndLogEx(INFO, "Done."); + PrintAndLogEx(INFO, "Done!"); return PM3_SUCCESS; } diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 0ca1e6894..686fb5067 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -457,23 +457,27 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) { SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + memcpy(card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision if (select_status == 0) { - PrintAndLogEx(ERR, "E->iso14443a card select failed"); + PrintAndLogEx(ERR, "iso14443a card select failed"); return PM3_EFAILED; } if (select_status == 2) { - PrintAndLogEx(ERR, "E->Card doesn't support iso14443-4 mode"); + PrintAndLogEx(ERR, "Card doesn't support iso14443-4 mode"); return PM3_EFAILED; } if (select_status == 3) { - PrintAndLogEx(INFO, "E->Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); // identify TOPAZ if (card->atqa[1] == 0x0C && card->atqa[0] == 0x00) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`")); @@ -489,7 +493,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes if (card->ats_len < 3) { - PrintAndLogEx(INFO, "E-> Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len)); + PrintAndLogEx(INFO, "Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len)); return PM3_ECARDEXCHANGE; } @@ -754,9 +758,12 @@ static int CmdHF14ACUIDs(const char *Cmd) { // execute anticollision procedure SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); - PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } iso14a_card_select_t *card = (iso14a_card_select_t *) resp.data.asBytes; @@ -773,7 +780,7 @@ static int CmdHF14ACUIDs(const char *Cmd) { } } PrintAndLogEx(SUCCESS, "end: %" PRIu64 " seconds", (msclock() - t1) / 1000); - return 1; + return PM3_SUCCESS; } // ## simulate iso14443a tag @@ -1051,7 +1058,7 @@ int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); } - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } @@ -2217,7 +2224,11 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { // reconnect for further tests clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + DropField(); + return PM3_ETIMEOUT; + } memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); @@ -2273,7 +2284,10 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats)); - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } memcpy(card.ats, resp.data.asBytes, resp.oldarg[0]); card.ats_len = resp.oldarg[0]; // note: ats_len includes CRC Bytes diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 7dd35ef64..b5d886382 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1179,7 +1179,9 @@ static void hf15EmlClear(void) { clearCommandBuffer(); SendCommandNG(CMD_HF_ISO15693_EML_CLEAR, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_HF_ISO15693_EML_CLEAR, &resp); + if (WaitForResponseTimeout(CMD_HF_ISO15693_EML_CLEAR, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + } } static int hf15EmlSetMem(const uint8_t *data, uint16_t count, size_t offset) { diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index f6714c5a2..3f6e76ec2 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -647,6 +647,17 @@ static int CmdHFCipurseReadFile(const char *Cmd) { PrintAndLogEx(INFO, "File id " _YELLOW_("%x") " offset " _YELLOW_("%zu") " key id " _YELLOW_("%d") " key " _YELLOW_("%s"), fileId, offset, keyId, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)); } + res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); + if (res != 0 || sw != ISO7816_OK) { + if (verbose == false) + PrintAndLogEx(ERR, "File select ( " _RED_("error") " ). Card returns 0x%04x", sw); + DropField(); + return PM3_ESOFT; + } + + if (verbose) + PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); + if (noAuth == false) { bool bres = CIPURSEChannelAuthenticate(keyId, key, verbose); if (bres == false) { @@ -660,17 +671,6 @@ static int CmdHFCipurseReadFile(const char *Cmd) { CIPURSECSetActChannelSecurityLevels(sreq, sresp); } - res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != ISO7816_OK) { - if (verbose == false) - PrintAndLogEx(ERR, "File select ( " _RED_("error") " ). Card returns 0x%04x", sw); - DropField(); - return PM3_ESOFT; - } - - if (verbose) - PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); - res = CIPURSEReadBinary(offset, buf, sizeof(buf), &len, &sw); if (res != 0 || sw != ISO7816_OK) { if (verbose == false) @@ -776,6 +776,17 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { PrintAndLogEx(INFO, "Data [%d]: %s", hdatalen, sprint_hex(hdata, hdatalen)); } + res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); + if (res != 0 || sw != ISO7816_OK) { + if (verbose == false) + PrintAndLogEx(ERR, "File select " _RED_("ERROR") ". Card returns 0x%04x", sw); + DropField(); + return PM3_ESOFT; + } + + if (verbose) + PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); + if (noAuth == false) { bool bres = CIPURSEChannelAuthenticate(keyId, key, verbose); if (bres == false) { @@ -789,17 +800,6 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { CIPURSECSetActChannelSecurityLevels(sreq, sresp); } - res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != ISO7816_OK) { - if (verbose == false) - PrintAndLogEx(ERR, "File select " _RED_("ERROR") ". Card returns 0x%04x", sw); - DropField(); - return PM3_ESOFT; - } - - if (verbose) - PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); - res = CIPURSEUpdateBinary(offset, hdata, hdatalen, buf, sizeof(buf), &len, &sw); if (res != 0 || sw != ISO7816_OK) { if (verbose == false) diff --git a/client/src/cmdhfepa.c b/client/src/cmdhfepa.c index 4c6c67f72..6332130ad 100644 --- a/client/src/cmdhfepa.c +++ b/client/src/cmdhfepa.c @@ -73,7 +73,6 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); SendCommandNG(CMD_HF_EPA_COLLECT_NONCE, (uint8_t *)&payload, sizeof(payload)); - WaitForResponse(CMD_HF_EPA_COLLECT_NONCE, &resp); // check if command failed @@ -241,7 +240,6 @@ static int CmdHFEPAPACESimulate(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_EPA_PACE_SIMULATE, 0, 0, 0, pwd, plen); - PacketResponseNG resp; WaitForResponse(CMD_ACK, &resp); diff --git a/client/src/cmdhfgallagher.c b/client/src/cmdhfgallagher.c index 7f70e3245..b83bfd455 100644 --- a/client/src/cmdhfgallagher.c +++ b/client/src/cmdhfgallagher.c @@ -1088,7 +1088,7 @@ static int CmdGallagherClone(const char *cmd) { PM3_RET_IF_ERR_WITH_MSG(res, "Failed creating Gallagher credential file"); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf gallagher reader`") " to verify"); return PM3_SUCCESS; } @@ -1169,7 +1169,7 @@ static int CmdGallagherDelete(const char *cmd) { PM3_RET_IF_ERR_WITH_MSG(res, "Failed deleting Gallagher application"); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf gallagher reader`") " to verify"); return PM3_SUCCESS; } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 7aea1f506..02802a6de 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -283,7 +283,7 @@ static void iclass_encrypt_block_data(uint8_t *blk_data, uint8_t *key) { mbedtls_des3_free(&ctx); } -static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *key, bool got_kr) { +static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *key, bool got_kr, uint8_t *card_key, bool got_krki, bool use_elite) { if (check_config_card(o) == false) { return PM3_EINVARG; } @@ -294,8 +294,13 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke memcpy(configcard.csn, "\x41\x87\x66\x00\xFB\xFF\x12\xE0", 8); memcpy(&configcard.conf, "\xFF\xFF\xFF\xFF\xF9\xFF\xFF\xBC", 8); memcpy(&configcard.epurse, "\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8); - // defaulting to known AA1 key - HFiClassCalcDivKey(configcard.csn, iClass_Key_Table[0], configcard.key_d, false); + + if (got_krki) { + HFiClassCalcDivKey(configcard.csn, card_key, configcard.key_d, use_elite); + } else { + // defaulting to AA1 ki 0 + HFiClassCalcDivKey(configcard.csn, iClass_Key_Table[0], configcard.key_d, use_elite); + } // reference picopass_hdr_t *cc = &configcard; @@ -306,7 +311,12 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke if (res == PM3_SUCCESS) { cc = &iclass_last_known_card; // calc diversified key for selected card - HFiClassCalcDivKey(cc->csn, iClass_Key_Table[0], cc->key_d, false); + if (got_krki) { + HFiClassCalcDivKey(cc->csn, card_key, cc->key_d, use_elite); + } else { + // defaulting to AA1 ki 0 + HFiClassCalcDivKey(cc->csn, iClass_Key_Table[0], cc->key_d, use_elite); + } } else { PrintAndLogEx(FAILED, "failed to read a card"); PrintAndLogEx(INFO, "falling back to default config card"); @@ -3890,7 +3900,6 @@ static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, u PacketResponseNG resp; clearCommandBuffer(); SendCommandNG(CMD_HF_ICLASS_RECOVER, (uint8_t *)payload, payload_size); - WaitForResponse(CMD_HF_ICLASS_RECOVER, &resp); if (resp.status == PM3_SUCCESS) { @@ -4146,13 +4155,14 @@ static int CmdHFiClassUnhash(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass unhash", - "Reverses the hash0 function used generate iclass diversified keys after DES encryption, returning the DES crypted CSN.", - "hf iclass unhash --divkey B4F12AADC5301A2D" + "Reverses the hash0 function used generate iclass diversified keys after DES encryption,\n" + "Function returns the DES crypted CSN. Next step bruteforcing.", + "hf iclass unhash -k B4F12AADC5301A2D" ); void *argtable[] = { arg_param_begin, - arg_str1(NULL, "divkey", "", "The card's Diversified Key value"), + arg_str1("k", "divkey", "", "Card diversified key"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -4164,14 +4174,17 @@ static int CmdHFiClassUnhash(const char *Cmd) { CLIParserFree(ctx); if (dk_len && dk_len != PICOPASS_BLOCK_SIZE) { - PrintAndLogEx(ERR, "Diversified Key is incorrect length"); + PrintAndLogEx(ERR, "Diversified key is incorrect length"); return PM3_EINVARG; } - PrintAndLogEx(INFO, _YELLOW_("Div Key: ")"%s", sprint_hex(div_key, sizeof(div_key))); + PrintAndLogEx(INFO, "Diversified key... %s", sprint_hex_inrow(div_key, sizeof(div_key))); invert_hash0(div_key); + PrintAndLogEx(SUCCESS, "You can now retrieve the master key by cracking DES with hashcat!"); + PrintAndLogEx(SUCCESS, "hashcat.exe -a 3 -m 14000 preimage:csn -1 charsets/DES_full.hcchr --hex-charset ?1?1?1?1?1?1?1?1"); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -4907,7 +4920,9 @@ static int CmdHFiClassConfigCard(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int0(NULL, "ci", "", "use config slot at index"), - arg_int0(NULL, "ki", "", "Key index to select key from memory 'hf iclass managekeys'"), + arg_int0(NULL, "ki", "", "Card Key - index to select key from memory 'hf iclass managekeys'"), + arg_int0(NULL, "krki", "", "Elite Keyroll Key - index to select key from memory 'hf iclass managekeys'"), + arg_lit0(NULL, "elite", "Use elite key for the the Card Key ki"), arg_lit0("g", NULL, "generate card dump file"), arg_lit0("l", NULL, "load available cards"), arg_lit0("p", NULL, "print available cards"), @@ -4916,19 +4931,34 @@ static int CmdHFiClassConfigCard(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, false); int ccidx = arg_get_int_def(ctx, 1, -1); - int kidx = arg_get_int_def(ctx, 2, -1); - bool do_generate = arg_get_lit(ctx, 3); - bool do_load = arg_get_lit(ctx, 4); - bool do_print = arg_get_lit(ctx, 5); + int card_kidx = arg_get_int_def(ctx, 2, -1); + int kidx = arg_get_int_def(ctx, 3, -1); + bool elite = arg_get_lit(ctx, 4); + bool do_generate = arg_get_lit(ctx, 5); + bool do_load = arg_get_lit(ctx, 6); + bool do_print = arg_get_lit(ctx, 7); CLIParserFree(ctx); + bool got_krki = false; + uint8_t card_key[8] = {0}; + if (card_kidx >= 0) { + if (card_kidx < ICLASS_KEYS_MAX) { + got_krki = true; + memcpy(card_key, iClass_Key_Table[card_kidx], 8); + PrintAndLogEx(SUCCESS, "Using card key[%d] " _GREEN_("%s"), card_kidx, sprint_hex(iClass_Key_Table[card_kidx], 8)); + } else { + PrintAndLogEx(ERR, "--krki number is invalid"); + return PM3_EINVARG; + } + } + bool got_kr = false; - uint8_t key[8] = {0}; + uint8_t keyroll_key[8] = {0}; if (kidx >= 0) { if (kidx < ICLASS_KEYS_MAX) { got_kr = true; - memcpy(key, iClass_Key_Table[kidx], 8); - PrintAndLogEx(SUCCESS, "Using key[%d] " _GREEN_("%s"), kidx, sprint_hex(iClass_Key_Table[kidx], 8)); + memcpy(keyroll_key, iClass_Key_Table[kidx], 8); + PrintAndLogEx(SUCCESS, "Using keyroll key[%d] " _GREEN_("%s"), kidx, sprint_hex(iClass_Key_Table[kidx], 8)); } else { PrintAndLogEx(ERR, "--ki number is invalid"); return PM3_EINVARG; @@ -4960,7 +4990,7 @@ static int CmdHFiClassConfigCard(const char *Cmd) { return PM3_EINVARG; } } - generate_config_card(item, key, got_kr); + generate_config_card(item, keyroll_key, got_kr, card_key, got_krki, elite); } return PM3_SUCCESS; diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 1bc929459..dc5caa94b 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1465,9 +1465,11 @@ static int CmdHF14aDesChk(const char *Cmd) { DropField(); // MIFARE DESFire info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); - PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); @@ -2173,7 +2175,7 @@ static int CmdHF14ADesBruteApps(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, _GREEN_("Done")); + PrintAndLogEx(SUCCESS, _GREEN_("Done!")); DropField(); return PM3_SUCCESS; } @@ -2923,7 +2925,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(SUCCESS, "Desfire format: " _GREEN_("done")); + PrintAndLogEx(SUCCESS, "Desfire format: " _GREEN_("done!")); DropField(); return PM3_SUCCESS; diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 5b02d7c9f..d25bcf37e 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -260,7 +260,7 @@ static void init_bitflip_bitarrays(void) { #endif uint64_t init_bitflip_bitarrays_starttime = msclock(); - char state_file_name[MAX(strlen(STATE_FILE_TEMPLATE_RAW), MAX(strlen(STATE_FILE_TEMPLATE_LZ4), strlen(STATE_FILE_TEMPLATE_BZ2))) + 1]; + char state_file_name[MAX(sizeof(STATE_FILE_TEMPLATE_RAW), MAX(sizeof(STATE_FILE_TEMPLATE_LZ4), sizeof(STATE_FILE_TEMPLATE_BZ2)))]; char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + sizeof(state_file_name)]; uint16_t nraw = 0, nlz4 = 0, nbz2 = 0; for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 11f1ce899..e6fcf55f9 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -317,7 +317,11 @@ static int CmdHFMFPInfo(const char *Cmd) { // Mifare Plus info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { + PrintAndLogEx(DEBUG, "iso14443a card select timeout"); + DropField(); + return false; + } iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); @@ -1673,7 +1677,10 @@ static int CmdHFMFPChk(const char *Cmd) { SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 1586d8bda..154146c12 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -307,7 +307,10 @@ int ul_read_uid(uint8_t *uid) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); @@ -356,7 +359,7 @@ static bool ul_select(iso14a_card_select_t *card) { ul_switch_on_field(); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { PrintAndLogEx(DEBUG, "iso14443a card select timeout"); DropField(); return false; @@ -4213,7 +4216,11 @@ static int CmdHF14AMfUKeyGen(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 6b7ac6843..8f7355e11 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1673,21 +1673,21 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, " native BT support......... " _YELLOW_("absent")); #endif #ifdef HAVE_PYTHON - PrintAndLogEx(NORMAL, " Python script support..... " _GREEN_("present") " (" _YELLOW_(PY_VERSION) ")"); + PrintAndLogEx(NORMAL, " Python script support..... " _GREEN_("present") " ( " _YELLOW_(PY_VERSION) " )"); #else PrintAndLogEx(NORMAL, " Python script support..... " _YELLOW_("absent")); #endif -#ifdef HAVE_LUA_SWIG - PrintAndLogEx(NORMAL, " Lua SWIG support.......... " _GREEN_("present")); -#else - PrintAndLogEx(NORMAL, " Lua SWIG support.......... " _YELLOW_("absent")); -#endif - PrintAndLogEx(NORMAL, " Lua runtime version....... " _GREEN_(LUA_RELEASE)); #ifdef HAVE_PYTHON_SWIG PrintAndLogEx(NORMAL, " Python SWIG support....... " _GREEN_("present")); #else PrintAndLogEx(NORMAL, " Python SWIG support....... " _YELLOW_("absent")); #endif + PrintAndLogEx(NORMAL, " Lua script support........ " _GREEN_("present") " ( " _YELLOW_("%s.%s.%s") " )", LUA_VERSION_MAJOR, LUA_VERSION_MINOR, LUA_VERSION_RELEASE); +#ifdef HAVE_LUA_SWIG + PrintAndLogEx(NORMAL, " Lua SWIG support.......... " _GREEN_("present")); +#else + PrintAndLogEx(NORMAL, " Lua SWIG support.......... " _YELLOW_("absent")); +#endif if (g_session.pm3_present) { PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Proxmark3") " ]"); diff --git a/client/src/cmdlfawid.c b/client/src/cmdlfawid.c index 51a0eea11..07504195a 100644 --- a/client/src/cmdlfawid.c +++ b/client/src/cmdlfawid.c @@ -433,7 +433,7 @@ static int CmdAWIDClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid reader`") " to verify"); return res; } diff --git a/client/src/cmdlfdestron.c b/client/src/cmdlfdestron.c index 52a0b736b..b5e1b10d9 100644 --- a/client/src/cmdlfdestron.c +++ b/client/src/cmdlfdestron.c @@ -212,7 +212,7 @@ static int CmdDestronClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf destron reader`") " to verify"); return res; } diff --git a/client/src/cmdlfem410x.c b/client/src/cmdlfem410x.c index 1c20254da..8b051ade9 100644 --- a/client/src/cmdlfem410x.c +++ b/client/src/cmdlfem410x.c @@ -799,12 +799,15 @@ static int CmdEM410xClone(const char *Cmd) { payload.low = (uint32_t)id; SendCommandNG(CMD_LF_EM410X_CLONE, (uint8_t *)&payload, sizeof(payload)); - WaitForResponse(CMD_LF_EM410X_CLONE, &resp); + if (WaitForResponseTimeout(CMD_LF_EM410X_CLONE, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } } switch (resp.status) { case PM3_SUCCESS: { - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 410x reader`") " to verify"); break; } diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index bb9b1d162..34ffa1bdc 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -340,7 +340,10 @@ static int CmdEM4x50Login(const char *Cmd) { clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_LF_EM4X50_LOGIN, (uint8_t *)&password, sizeof(password)); - WaitForResponse(CMD_LF_EM4X50_LOGIN, &resp); + if (WaitForResponseTimeout(CMD_LF_EM4X50_LOGIN, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } // print response if (resp.status == PM3_SUCCESS) diff --git a/client/src/cmdlffdxb.c b/client/src/cmdlffdxb.c index a7478e43b..f7b6742c6 100644 --- a/client/src/cmdlffdxb.c +++ b/client/src/cmdlffdxb.c @@ -802,7 +802,7 @@ static int CmdFdxBClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdxb reader`") " to verify"); return res; } diff --git a/client/src/cmdlfgallagher.c b/client/src/cmdlfgallagher.c index f2bd45af3..5617d90a8 100644 --- a/client/src/cmdlfgallagher.c +++ b/client/src/cmdlfgallagher.c @@ -276,7 +276,7 @@ static int CmdGallagherClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher reader`") " to verify"); return res; } diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index fcf1f2c6c..ea567499a 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -331,7 +331,7 @@ static int CmdGuardClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gproxii reader`") " to verify"); return res; } diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index ab41f3798..204505972 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -58,8 +58,9 @@ static int sendPing(void) { SendCommandNG(CMD_PING, NULL, 0); clearCommandBuffer(); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_PING, &resp, 1000)) + if (WaitForResponseTimeout(CMD_PING, &resp, 1000) == false) { return PM3_ETIMEOUT; + } return PM3_SUCCESS; } static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, bool verbose) { @@ -470,15 +471,17 @@ static int CmdHIDClone(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_HID_CLONE, (uint8_t *)&payload, sizeof(payload)); - PacketResponseNG resp; - WaitForResponse(CMD_LF_HID_CLONE, &resp); + if (WaitForResponseTimeout(CMD_LF_HID_CLONE, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + if (resp.status == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid reader`") " to verify"); - PrintAndLogEx(INFO, "Done!"); } else { PrintAndLogEx(FAILED, "cloning ( " _RED_("fail") " )"); - } return resp.status; } diff --git a/client/src/cmdlfidteck.c b/client/src/cmdlfidteck.c index 6ac9c0695..0fb4242fc 100644 --- a/client/src/cmdlfidteck.c +++ b/client/src/cmdlfidteck.c @@ -226,7 +226,7 @@ static int CmdIdteckClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf idteck reader`") " to verify"); return res; } diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 89922c0ac..80a7b5fbb 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -945,7 +945,7 @@ static int CmdIndalaClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala reader`") " to verify"); return res; } diff --git a/client/src/cmdlfio.c b/client/src/cmdlfio.c index ad4517732..6e92ce362 100644 --- a/client/src/cmdlfio.c +++ b/client/src/cmdlfio.c @@ -358,7 +358,7 @@ static int CmdIOProxClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io reader`") " to verify"); return res; } diff --git a/client/src/cmdlfjablotron.c b/client/src/cmdlfjablotron.c index 2651ebe51..b584d8187 100644 --- a/client/src/cmdlfjablotron.c +++ b/client/src/cmdlfjablotron.c @@ -240,7 +240,7 @@ static int CmdJablotronClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf jablotron reader`") " to verify"); return res; } diff --git a/client/src/cmdlfkeri.c b/client/src/cmdlfkeri.c index 1a390fa45..16f7d07c9 100644 --- a/client/src/cmdlfkeri.c +++ b/client/src/cmdlfkeri.c @@ -309,7 +309,7 @@ static int CmdKeriClone(const char *Cmd) { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf keri read`") " to verify"); return res; } diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index 52c70c832..00f22cad3 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -253,7 +253,7 @@ static int CmdMotorolaClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf motorola reader`") " to verify"); return res; } diff --git a/client/src/cmdlfnedap.c b/client/src/cmdlfnedap.c index 4d51116e8..e5f857a03 100644 --- a/client/src/cmdlfnedap.c +++ b/client/src/cmdlfnedap.c @@ -472,7 +472,7 @@ static int CmdLFNedapClone(const char *Cmd) { } else { PrintAndLogEx(NORMAL, ""); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap reader`") " to verify"); return res; } diff --git a/client/src/cmdlfnexwatch.c b/client/src/cmdlfnexwatch.c index 06a1dce44..6977f5593 100644 --- a/client/src/cmdlfnexwatch.c +++ b/client/src/cmdlfnexwatch.c @@ -447,7 +447,7 @@ static int CmdNexWatchClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nexwatch reader`") " to verify"); return res; } diff --git a/client/src/cmdlfnoralsy.c b/client/src/cmdlfnoralsy.c index 562cca539..7eaf22f7d 100644 --- a/client/src/cmdlfnoralsy.c +++ b/client/src/cmdlfnoralsy.c @@ -220,7 +220,7 @@ static int CmdNoralsyClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf noralsy reader`") " to verify"); return res; } diff --git a/client/src/cmdlfpac.c b/client/src/cmdlfpac.c index c1f6247f7..0ba92534b 100644 --- a/client/src/cmdlfpac.c +++ b/client/src/cmdlfpac.c @@ -304,7 +304,7 @@ static int CmdPacClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pac reader`") " to verify"); return res; } diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index 70906b58d..8c5e0cf8e 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -383,7 +383,7 @@ static int CmdParadoxClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf paradox read`") " to verify"); return res; } diff --git a/client/src/cmdlfpcf7931.c b/client/src/cmdlfpcf7931.c index 067fecde2..53bc19f03 100644 --- a/client/src/cmdlfpcf7931.c +++ b/client/src/cmdlfpcf7931.c @@ -193,7 +193,7 @@ static int CmdLFPCF7931Write(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_LF_PCF7931_WRITE, block, idx, data[0], buf, sizeof(buf)); - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 reader`") " to verify"); return PM3_SUCCESS; } diff --git a/client/src/cmdlfpresco.c b/client/src/cmdlfpresco.c index 2fd78c724..c566c9c4b 100644 --- a/client/src/cmdlfpresco.c +++ b/client/src/cmdlfpresco.c @@ -264,7 +264,7 @@ static int CmdPrescoClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf presco reader`") " to verify"); return res; } diff --git a/client/src/cmdlfpyramid.c b/client/src/cmdlfpyramid.c index 470d0e697..dcc87e1fa 100644 --- a/client/src/cmdlfpyramid.c +++ b/client/src/cmdlfpyramid.c @@ -355,7 +355,7 @@ static int CmdPyramidClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pyramid reader`") " to verify"); return res; } diff --git a/client/src/cmdlfsecurakey.c b/client/src/cmdlfsecurakey.c index e20968a5e..3d61887e5 100644 --- a/client/src/cmdlfsecurakey.c +++ b/client/src/cmdlfsecurakey.c @@ -232,7 +232,7 @@ static int CmdSecurakeyClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf securakey reader`") " to verify"); return res; } diff --git a/client/src/cmdlfti.c b/client/src/cmdlfti.c index 4a5dcc18a..2c28bab8b 100644 --- a/client/src/cmdlfti.c +++ b/client/src/cmdlfti.c @@ -369,7 +369,7 @@ static int CmdTIWrite(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_TI_WRITE, (uint8_t *)&payload, sizeof(payload)); - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti reader`") " to verify"); return PM3_SUCCESS; } diff --git a/client/src/cmdlfverichip_disabled.c b/client/src/cmdlfverichip_disabled.c index 3a69b3a92..fe9dc438f 100644 --- a/client/src/cmdlfverichip_disabled.c +++ b/client/src/cmdlfverichip_disabled.c @@ -137,7 +137,7 @@ static int CmdVerichipClone(const char *Cmd) { print_blocks(blocks, ARRAYLEN(blocks)); int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf verichip read`") " to verify"); return res; } diff --git a/client/src/cmdlfviking.c b/client/src/cmdlfviking.c index 3ed4c83fb..d2f3b4e39 100644 --- a/client/src/cmdlfviking.c +++ b/client/src/cmdlfviking.c @@ -176,7 +176,7 @@ static int CmdVikingClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf viking reader`") " to verify"); return resp.status; } diff --git a/client/src/cmdlfvisa2000.c b/client/src/cmdlfvisa2000.c index 5e473fcf3..c7b9c8393 100644 --- a/client/src/cmdlfvisa2000.c +++ b/client/src/cmdlfvisa2000.c @@ -244,7 +244,7 @@ static int CmdVisa2kClone(const char *Cmd) { } else { res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); } - PrintAndLogEx(SUCCESS, "Done"); + PrintAndLogEx(SUCCESS, "Done!"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf visa2000 reader`") " to verify"); return res; } diff --git a/client/src/loclass/ikeys.c b/client/src/loclass/ikeys.c index cfbf9b8f1..9458f13ce 100644 --- a/client/src/loclass/ikeys.c +++ b/client/src/loclass/ikeys.c @@ -424,21 +424,25 @@ void invert_hash0(uint8_t k[8]) { for (int i = 0; i < 8; i++) { y |= ((k[i] & 0x80) >> (7 - i)); // Recover the bit of y from the leftmost bit of k[i] pushbackSixBitByte(&zTilde, (k[i] & 0x7E) >> 1, i); // Recover the six bits of zTilde from the middle of k[i] - if (g_debugMode > 0)printState("z~", zTilde); + + if (g_debugMode > 0) printState("z~", zTilde); + p |= ((k[i] & 0x01) << i); } - if (g_debugMode > 0)PrintAndLogEx(INFO, " y : %02x", y); //value of y (recovered 1 byte of the pre-image) - //check if p is part of the array pi, if not invert it - if (g_debugMode > 0)PrintAndLogEx(INFO, " p : %02x", p); //value of p (at some point in the original hash0) + + if (g_debugMode > 0) PrintAndLogEx(INFO, " y : %02x", y); // value of y (recovered 1 byte of the pre-image) + // check if p is part of the array pi, if not invert it + if (g_debugMode > 0) PrintAndLogEx(INFO, " p : %02x", p); // value of p (at some point in the original hash0) + int remainder = find_p_in_pi(p); if (remainder < 0) { p = ~p; remainder = find_p_in_pi(p); } - if (g_debugMode > 0)PrintAndLogEx(INFO, " p or ~p : %02x", p); //value of p (at some point in the original hash0) + if (g_debugMode > 0) PrintAndLogEx(INFO, " p or ~p : %02x", p); // value of p (at some point in the original hash0) - //find possible values of x that can return the same remainder + // find possible values of x that can return the same remainder uint8_t x_count = 0; uint8_t x_array[8]; for (int x = 0x00; x <= 0xFF; x++) { @@ -450,24 +454,31 @@ void invert_hash0(uint8_t k[8]) { uint8_t pre_image_base[8] = {0}; pre_image_base[1] = y; - //calculate pre-images based on the potential values of x (should we use pre-flip p and post flip p just in case?) - uint64_t zTil_img[8] = {0}; //8 is the max size it'll have as per max number of X pre-images - for (int img = 0; img < x_count; img++) { //for each potential value of x calculate a pre-image + + // calculate pre-images based on the potential values of x. Sshould we use pre-flip p and post flip p just in case? + uint64_t zTil_img[8] = {0}; // 8 is the max size it'll have as per max number of X pre-images + + for (int img = 0; img < x_count; img++) { // for each potential value of x calculate a pre-image + zTil_img[img] = zTilde; pre_image_base[0] = x_array[img]; - uint8_t pc = p; //redefine and reassociate it here or it'll keep changing through the loops - if (x_array[img] & 1) { //Check if potential x7 is 1, if it is then invert p + + uint8_t pc = p; // redefine and reassociate it here or it'll keep changing through the loops + if (x_array[img] & 1) { // Check if potential x7 is 1, if it is then invert p pc = ~p; } - //calculate zTilde for the x preimage + + // calculate zTilde for the x preimage for (int i = 0; i < 8; i++) { - uint8_t p_i = (pc >> i) & 0x1; //this is correct! + + uint8_t p_i = (pc >> i) & 0x1; // this is correct! uint8_t zTilde_i = getSixBitByte(zTilde, i) << 1; - if (k[i] & 0x80) { //this checks the value of the first bit of the byte (value of y_i) + + if (k[i] & 0x80) { // this checks the value of the first bit of the byte (value of y_i) if (p_i) { zTilde_i--; } - zTilde_i = ~zTilde_i; //flip the 6 bit string + zTilde_i = ~zTilde_i; // flip the 6 bit string } else { zTilde_i |= p_i & 0x1; } @@ -478,18 +489,19 @@ void invert_hash0(uint8_t k[8]) { if (g_debugMode > 0) { PrintAndLogEx(INFO, _YELLOW_("Testing Pre-Image Base: %s"), sprint_hex(pre_image_base, sizeof(pre_image_base))); PrintAndLogEx(DEBUG, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); - printState("0|0|z~", zTil_img[img]); //we retrieve the values of z~ - PrintAndLogEx(INFO, " p or ~p : %02x", pc); //value of p (at some point in the original hash0) + printState("0|0|z~", zTil_img[img]); // we retrieve the values of z~ + PrintAndLogEx(INFO, " p or ~p : %02x", pc); // value of p (at some point in the original hash0) } - //reverse permute + + // reverse permute BitstreamIn_t p_in = { &pc, 8, 0 }; uint8_t outbuffer_1[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t outbuffer_2[] = {0, 0, 0, 0, 0, 0, 0, 0}; BitstreamOut_t out_1 = {outbuffer_1, 0, 0}; BitstreamOut_t out_2 = {outbuffer_2, 0, 0}; - reverse_permute(&p_in, zTil_img[img], 0, &out_1, &out_2, false); //sort the bits + reverse_permute(&p_in, zTil_img[img], 0, &out_1, &out_2, false); // sort the bits - //Shift z-values down onto the lower segment + // Shift z-values down onto the lower segment uint64_t zCaret_1 = x_bytes_to_num(outbuffer_1, sizeof(outbuffer_1)); zCaret_1 >>= 16; uint64_t zCaret_2 = x_bytes_to_num(outbuffer_2, sizeof(outbuffer_2)); @@ -497,16 +509,16 @@ void invert_hash0(uint8_t k[8]) { uint64_t zCaret = zCaret_1 | zCaret_2; if (g_debugMode > 0) printState("0|0|z^", zCaret); - //fix the bits values - uint8_t p_fix = 0x0F; //fix bits mask as the bits will be in 11110000 order + // fix the bits values + uint8_t p_fix = 0x0F; // fix bits mask as the bits will be in 11110000 order BitstreamIn_t p_in_f = { &p_fix, 8, 0 }; uint8_t outbuffer_f1[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t outbuffer_f2[] = {0, 0, 0, 0, 0, 0, 0, 0}; BitstreamOut_t out_f1 = {outbuffer_f1, 0, 0}; BitstreamOut_t out_f2 = {outbuffer_f2, 0, 0}; - reverse_permute(&p_in_f, zCaret, 0, &out_f1, &out_f2, true); //fixes the bits accordingly + reverse_permute(&p_in_f, zCaret, 0, &out_f1, &out_f2, true); // fixes the bits accordingly - //Shift z-values down onto the lower segment + // Shift z-values down onto the lower segment uint64_t zCaret_fixed1 = x_bytes_to_num(outbuffer_f1, sizeof(outbuffer_f1)); zCaret_fixed1 >>= 16; uint64_t zCaret_fixed2 = x_bytes_to_num(outbuffer_f2, sizeof(outbuffer_f2)); @@ -518,7 +530,7 @@ void invert_hash0(uint8_t k[8]) { uint64_t zP = reverse_check(zCaret_fixed); if (g_debugMode > 0) printState("0|0|z'", zP); - //reverse the modulo transformation in the hash0 function for the six-bit chunks + // reverse the modulo transformation in the hash0 function for the six-bit chunks uint64_t c = 0; @@ -533,39 +545,48 @@ void invert_hash0(uint8_t k[8]) { pushbackSixBitByte(&c, zn4, n + 4); } - //The Hydra: depending on their positions, values 0x00, 0x01, 0x02, 0x03, 0x3c, 0x3d, 0x3e, 0x3f can lead to additional pre-images. - //When these values are present we need to generate additional pre-images if they have the same modulo as other values + // The Hydra: depending on their positions, values 0x00, 0x01, 0x02, 0x03, 0x3c, 0x3d, 0x3e, 0x3f can lead to additional pre-images. + // When these values are present we need to generate additional pre-images if they have the same modulo as other values // Initialize an array of pointers to uint64_t (start with one value, initialized to 0) - uint64_t *hydra_heads = (uint64_t *)malloc(sizeof(uint64_t)); // Start with one uint64_t + uint64_t *hydra_heads = (uint64_t *)calloc(sizeof(uint64_t), 1); // Start with one uint64_t hydra_heads[0] = 0; // Initialize first value to 0 int heads_count = 1; // Track number of forks // Iterate 4 times as per the original loop for (int n = 0; n < 8; n++) { + uint8_t hydra_head = getSixBitByte(c, n); + if (hydra_head <= (n % 4) || hydra_head >= 63 - (n % 4)) { + // Create new forks by duplicating existing uint64_t values int new_head = heads_count * 2; hydra_heads = (uint64_t *)realloc(hydra_heads, new_head * sizeof(uint64_t)); + // Duplicate all current values and add the value to both original and new ones for (int i = 0; i < heads_count; i++) { + // Duplicate current value hydra_heads[heads_count + i] = hydra_heads[i]; uint8_t small_hydra_head = 0; uint8_t big_hydra_head = 0; uint8_t hydra_lil_spawns[4] = {0x00, 0x01, 0x02, 0x03}; uint8_t hydra_big_spawns[4] = {0x3f, 0x3e, 0x3d, 0x3c}; - if (hydra_head <= n % 4) { //check if is in the lower range - //replace with big spawn in one hydra and keep small in another + + if (hydra_head <= n % 4) { // check if is in the lower range + + // replace with big spawn in one hydra and keep small in another small_hydra_head = hydra_head; for (int fh = 0; fh < 4; fh++) { if (hydra_lil_spawns[fh] == hydra_head) { big_hydra_head = hydra_big_spawns[fh]; } } - } else if (hydra_head >= 63 - (n % 4)) { //or the higher range - //replace with small in one hydra and keep big in another + + } else if (hydra_head >= 63 - (n % 4)) { // or the higher range + + // replace with small in one hydra and keep big in another big_hydra_head = hydra_head; for (int fh = 0; fh < 4; fh++) { if (hydra_big_spawns[fh] == hydra_head) { @@ -579,7 +600,8 @@ void invert_hash0(uint8_t k[8]) { } // Update the count of total values heads_count = new_head; - } else { //no hydra head spawns + } else { + // no hydra head spawns for (int i = 0; i < heads_count; i++) { pushbackSixBitByte(&hydra_heads[i], hydra_head, n);; } @@ -587,14 +609,16 @@ void invert_hash0(uint8_t k[8]) { } for (int i = 0; i < heads_count; i++) { - //restore the two most significant bytes (x and y) + + // restore the two most significant bytes (x and y) hydra_heads[i] |= ((uint64_t)x_array[img] << 56); hydra_heads[i] |= ((uint64_t)y << 48); + if (g_debugMode > 0) { PrintAndLogEx(DEBUG, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); printState("origin_r1", hydra_heads[i]); } - //reverse the swapZbalues function to get the original six-bit byte order + // reverse the swapZbalues function to get the original six-bit byte order uint64_t original_z = swapZvalues(hydra_heads[i]); if (g_debugMode > 0) { @@ -602,24 +626,31 @@ void invert_hash0(uint8_t k[8]) { printState("origin_r2", original_z); PrintAndLogEx(INFO, "--------------------------"); } - //run pre-image through hash0 + // run pre-image through hash0 uint8_t img_div_key[8] = {0}; - hash0(original_z, img_div_key); //commented to avoid log spam + hash0(original_z, img_div_key); // commented to avoid log spam - //verify result, if it matches add it to the list as a valid pre-image + // verify result, if it matches add it to the list as a valid pre-image bool image_match = true; for (int v = 0; v < 8; v++) { - if (img_div_key[v] != k[v]) { //compare against input key k + + // compare against input key k + if (img_div_key[v] != k[v]) { image_match = false; } + } + uint8_t des_pre_image[8] = {0}; x_num_to_bytes(original_z, sizeof(original_z), des_pre_image); if (image_match) { - PrintAndLogEx(INFO, _GREEN_("Valid pre-image: ")_YELLOW_("%s"), sprint_hex(des_pre_image, sizeof(des_pre_image))); - } else if (!image_match && g_debugMode > 0) { - PrintAndLogEx(INFO, _RED_("Invalid pre-image: %s"), sprint_hex(des_pre_image, sizeof(des_pre_image))); + PrintAndLogEx(INFO, "Pre-image......... " _YELLOW_("%s") " ( "_GREEN_("valid") " )", sprint_hex_inrow(des_pre_image, sizeof(des_pre_image))); + } else { + + if (g_debugMode > 0) { + PrintAndLogEx(INFO, "Pre-image......... " _YELLOW_("%s") " ( "_RED_("invalid") " )", sprint_hex_inrow(des_pre_image, sizeof(des_pre_image))); + } } } // Free allocated memory diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 1376fce57..7bf692184 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -3052,7 +3052,10 @@ int DesfireGetCardUID(DesfireContext_t *ctx) { SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); uint64_t select_status = resp.oldarg[0]; diff --git a/client/src/util.c b/client/src/util.c index 904846e94..d89962698 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -529,7 +529,7 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len) { while (i < max_len) { unsigned char c = (unsigned char)data[i]; - tmp[pos + i] = isprint(c) ? c : '.'; + tmp[pos + i] = (isprint(c) && c != 0xff) ? c : '.'; ++i; } out: @@ -546,7 +546,7 @@ char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_st while (i < max_len) { unsigned char c = (unsigned char)data[i]; - tmp[i] = isprint(c) ? c : '.'; + tmp[i] = (isprint(c) && c != 0xff) ? c : '.'; ++i; } diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index 2cb54ed39..85a4c8f6d 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -49,18 +49,28 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate) { } // read ID out -bool Flash_ReadID_90(flash_device_type_90_t *result) { +bool Flash_ReadID(flash_device_type_t *result, bool read_jedec) { if (Flash_CheckBusy(BUSY_TIMEOUT)) return false; - // Manufacture ID / device ID - FlashSendByte(ID); - FlashSendByte(0x00); - FlashSendByte(0x00); - FlashSendByte(0x00); - result->manufacturer_id = FlashSendByte(0xFF); - result->device_id = FlashSendLastByte(0xFF); + if (read_jedec) { + // 0x9F JEDEC + FlashSendByte(JEDECID); + + result->manufacturer_id = FlashSendByte(0xFF); + result->device_id = FlashSendByte(0xFF); + result->device_id2 = FlashSendLastByte(0xFF); + } else { + // 0x90 Manufacture ID / device ID + FlashSendByte(ID); + FlashSendByte(0x00); + FlashSendByte(0x00); + FlashSendByte(0x00); + + result->manufacturer_id = FlashSendByte(0xFF); + result->device_id = FlashSendLastByte(0xFF); + } return true; } @@ -346,8 +356,8 @@ void Flashmem_print_status(void) { // NOTE: It would likely be more useful to use JDEC ID command 9F, // as it provides a third byte indicative of capacity. - flash_device_type_90_t device_type = {0}; - if (!Flash_ReadID_90(&device_type)) { + flash_device_type_t device_type = {0}; + if (!Flash_ReadID(&device_type, false)) { DbpString(" Device ID............... " _RED_(" --> Not Found <--")); } else { if (device_type.manufacturer_id == WINBOND_MANID) { @@ -370,6 +380,13 @@ void Flashmem_print_status(void) { device_type.device_id ); } + if (Flash_ReadID(&device_type, true)) { + Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %02X%02X"), + device_type.manufacturer_id, + device_type.device_id, + device_type.device_id2 + ); + } } uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index f23a2786d..f79de4a58 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -129,8 +129,9 @@ bool Flash_Erase64k(uint8_t block); typedef struct { uint8_t manufacturer_id; uint8_t device_id; -} flash_device_type_90_t; // to differentiate from JDEC ID via cmd 9F -bool Flash_ReadID_90(flash_device_type_90_t *result); + uint8_t device_id2; +} flash_device_type_t; // extra device_id used for the JEDEC ID read via cmd 9F +bool Flash_ReadID(flash_device_type_t *result, bool read_jedec); uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); diff --git a/doc/commands.json b/doc/commands.json index 7fa514bc2..7641f4e04 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3656,16 +3656,16 @@ }, "hf iclass unhash": { "command": "hf iclass unhash", - "description": "Reverses the hash0 function used generate iclass diversified keys after DES encryption, returning the DES crypted CSN.", + "description": "Reverses the hash0 function used generate iclass diversified keys after DES encryption, Function returns the DES crypted CSN. Next step bruteforcing.", "notes": [ - "hf iclass unhash --divkey B4F12AADC5301A2D" + "hf iclass unhash -k B4F12AADC5301A2D" ], "offline": true, "options": [ "-h, --help This help", - "--divkey The card's Diversified Key value" + "-k, --divkey Card diversified key" ], - "usage": "hf iclass unhash [-h] --divkey " + "usage": "hf iclass unhash [-h] -k " }, "hf iclass view": { "command": "hf iclass view", @@ -12956,6 +12956,6 @@ "metadata": { "commands_extracted": 747, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2024-09-30T08:35:18" + "extracted_on": "2024-10-04T07:43:15" } }