diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 7cb290038..e85e6b1f2 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1795,7 +1795,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, return true; } -static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, bool shallow_mod, uint32_t *start_time, uint32_t *eof_time) { +static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, bool shallow_mod, uint32_t *start_time, uint32_t *eof_time, bool short_delay) { // write command: cmd, 1 blockno, 8 data, 4 mac uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, blockno }; @@ -1804,7 +1804,12 @@ static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, b memcpy(write + 10, mac, 4); uint8_t resp[10] = {0}; - bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, start_time, ICLASS_READER_TIMEOUT_UPDATE, eof_time, shallow_mod); + bool isOK = false; + if(short_delay){ + isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, start_time, ICLASS_READER_TIMEOUT_UPDATE_FAST, eof_time, shallow_mod); + }else{ + isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, start_time, ICLASS_READER_TIMEOUT_UPDATE, eof_time, shallow_mod); + } if (isOK == false) { return false; } @@ -2642,6 +2647,7 @@ void iClass_Recover(iclass_recover_req_t *msg) { uint8_t fast_previous_key[PICOPASS_BLOCK_SIZE] = {0}; uint8_t fast_current_key[PICOPASS_BLOCK_SIZE] = {0}; uint32_t index = msg->index; + bool short_delay = msg->short_delay; int bits_found = -1; bool recovered = false; bool completed = false; @@ -2841,7 +2847,7 @@ void iClass_Recover(iclass_recover_req_t *msg) { bool write_error = false; while (written == false && write_error == false) { //Step5 Perform Write - if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time)) { + if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time, short_delay)) { status_message = 4; //wrote new key on the card - unverified } if(!msg->fast){ //if we're going slow we check at every write that the write actually happened @@ -2905,7 +2911,7 @@ void iClass_Recover(iclass_recover_req_t *msg) { start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod); start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time)) { + if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time, short_delay)) { status_message = 6; //restore of original key successful but unverified } //Do a readcheck first to reset the cypher state @@ -2991,7 +2997,7 @@ fast_restore: memcpy(wb + 1, fast_restore_key, 8); doMAC_N(wb, sizeof(wb), div_key2, mac2); start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - if (iclass_writeblock_sp(blockno, fast_restore_key, mac2, shallow_mod, &start_time, &eof_time)) { + if (iclass_writeblock_sp(blockno, fast_restore_key, mac2, shallow_mod, &start_time, &eof_time, short_delay)) { status_message = 6; //restore of original key successful but unverified } //Do a readcheck first to reset the cypher state diff --git a/armsrc/iclass.h b/armsrc/iclass.h index 4e242b254..2d2bf8c42 100644 --- a/armsrc/iclass.h +++ b/armsrc/iclass.h @@ -34,6 +34,7 @@ // times in samples @ 212kHz when acting as reader #define ICLASS_READER_TIMEOUT_ACTALL 330 // 1558us, nominal 330us + 7slots*160us = 1450us #define ICLASS_READER_TIMEOUT_UPDATE 3390 // 16000us, nominal 4-15ms +#define ICLASS_READER_TIMEOUT_UPDATE_FAST 1500 // A copy of ICLASS_READER_TIMEOUT_UPDATE with reduced timeout values #define ICLASS_READER_TIMEOUT_OTHERS 80 // 380us, nominal 330us // The length of a received command will in most cases be no more than 18 bytes. diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index c4a7af66f..aeaf7f514 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -4524,7 +4524,7 @@ void picopass_elite_nextKey(uint8_t *key) { memcpy(key, key_state, 8); } -static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, uint8_t no_first_auth[8], bool debug, bool test, bool fast, bool allnight) { +static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, uint8_t no_first_auth[8], bool debug, bool test, bool fast, bool short_delay, bool allnight) { int runs = 1; int cycle = 1; @@ -4557,6 +4557,7 @@ static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, u payload->debug = debug; payload->test = test; payload->fast = fast; + payload->short_delay = short_delay; memcpy(payload->nfa, no_first_auth, PICOPASS_BLOCK_SIZE); memcpy(payload->req.key, key, PICOPASS_BLOCK_SIZE); memcpy(payload->req2.key, aa2_standard_key, PICOPASS_BLOCK_SIZE); @@ -4859,9 +4860,11 @@ static int CmdHFiClassLegacyRecSim(void) { bits_found = index; PrintAndLogEx(SUCCESS, "Original Key: " _GREEN_("%s"), sprint_hex(original_key, sizeof(original_key))); PrintAndLogEx(SUCCESS, "Weak Key: " _GREEN_("%s"), sprint_hex(key, sizeof(key))); - PrintAndLogEx(SUCCESS, "Key Updates Required to Weak Key :" _GREEN_("%d"), index); + PrintAndLogEx(SUCCESS, "Key Updates Required to Weak Key: " _GREEN_("%d"), index); PrintAndLogEx(SUCCESS, "Estimated Time (default mode) : ~" _GREEN_("%d")" hours", index / 17800); + PrintAndLogEx(SUCCESS, "Estimated Time (default + --sl) : ~" _GREEN_("%d")" hours", index / 19450); PrintAndLogEx(SUCCESS, "Estimated Time (--fast mode) : ~" _GREEN_("%d")" hours", index / 26860); + PrintAndLogEx(SUCCESS, "Estimated Time (--fast + --sl) : ~" _GREEN_("%d")" hours", index / 29750); } index++; @@ -4890,6 +4893,7 @@ static int CmdHFiClassLegacyRecover(const char *Cmd) { arg_lit0(NULL, "notest", "Perform real writes on the card!"), arg_lit0(NULL, "allnight", "Loops the loop for 10 times, recommended loop value of 5000."), arg_lit0(NULL, "fast", "Increases the speed (4.6->7.4 key updates/second), higher risk to brick the card."), + arg_lit0(NULL, "sl", "Lower card comms delay times, further speeds increases, may cause more errors."), arg_lit0(NULL, "est", "Estimates the key updates based on the card's CSN assuming standard key."), arg_param_end }; @@ -4906,7 +4910,8 @@ static int CmdHFiClassLegacyRecover(const char *Cmd) { bool no_test = arg_get_lit(ctx, 5); bool allnight = arg_get_lit(ctx, 6); bool fast = arg_get_lit(ctx, 7); - bool sim = arg_get_lit(ctx, 8); + bool short_delay = arg_get_lit(ctx, 8); + bool sim = arg_get_lit(ctx, 9); if (sim) { CmdHFiClassLegacyRecSim(); @@ -4948,8 +4953,8 @@ static int CmdHFiClassLegacyRecover(const char *Cmd) { PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to abort"); PrintAndLogEx(INFO, "--------------- " _CYAN_("start") " -----------------\n"); - iclass_recover(macs, index, loop, no_first_auth, debug, test, fast, allnight); + iclass_recover(macs, index, loop, no_first_auth, debug, test, fast, short_delay, allnight); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, _YELLOW_("If the process completed successfully, you can now run 'hf iclass legbrute' with the partial key found.")); diff --git a/include/iclass_cmd.h b/include/iclass_cmd.h index 2dc658ed9..dcab87809 100644 --- a/include/iclass_cmd.h +++ b/include/iclass_cmd.h @@ -125,6 +125,7 @@ typedef struct { bool debug; bool test; bool fast; + bool short_delay; } PACKED iclass_recover_req_t; typedef struct iclass_premac {