From a127a38cb69b3e7f5e722c8155edc58e4f6bc12d Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 19 Jul 2024 18:27:36 +0800 Subject: [PATCH] Updated some as per iceman's comments Made multiple changes as per iceman's comments. Removed redundant/unused function i forgot into cmdhficlass.c Moved conversion functions in util.c for now but haven't yet check if it's possible to reuse the current fuctions already there. Will do that in a moment. --- armsrc/iclass.c | 55 ++++++++++------------------------------ armsrc/iclass.h | 5 +--- armsrc/util.c | 30 ++++++++++++++++++++++ armsrc/util.h | 4 +++ client/src/cmdhficlass.c | 19 ++------------ client/src/cmdhficlass.h | 2 -- 6 files changed, 50 insertions(+), 65 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 69ad6f951..cd28350bf 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -2153,7 +2153,7 @@ out: } } -void generate_single_key_block_inverted(const uint8_t startingKey[PICOPASS_BLOCK_SIZE], uint32_t index, uint8_t keyBlock[PICOPASS_BLOCK_SIZE]) { +void generate_single_key_block_inverted(const uint8_t *startingKey, uint32_t index, uint8_t *keyBlock) { uint32_t carry = index; memcpy(keyBlock, startingKey, PICOPASS_BLOCK_SIZE); @@ -2168,35 +2168,6 @@ void generate_single_key_block_inverted(const uint8_t startingKey[PICOPASS_BLOCK } } } -// Function to convert an unsigned int to binary string -void intToBinary(unsigned int num, char *binaryStr, int size) { - binaryStr[size] = '\0'; // Null-terminate the string - for (int i = size - 1; i >= 0; i--) { - binaryStr[i] = (num % 2) ? '1' : '0'; - num /= 2; - } -} - -// Function to convert a binary string to hexadecimal -uint8_t binaryToHex(char *binaryStr) { - return (uint8_t)strtoul(binaryStr, NULL, 2); -} - -// Function to convert an unsigned int to an array of hex values -void convertToHexArray(unsigned int num, uint8_t *partialKey) { - char binaryStr[25]; // 24 bits for binary representation + 1 for null terminator - - // Convert the number to binary string - intToBinary(num, binaryStr, 24); - - // Split the binary string into groups of 3 and convert to hex - for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) { - char group[4]; - strncpy(group, binaryStr + i * 3, 3); - group[3] = '\0'; // Null-terminate the group string - partialKey[i] = binaryToHex(group); - } -} void iClass_Recover(iclass_recover_req_t *msg) { @@ -2280,7 +2251,7 @@ void iClass_Recover(iclass_recover_req_t *msg) { //Step3 Calculate New Key uint8_t GenKeyBlock[PICOPASS_BLOCK_SIZE]; uint8_t GenKeyBlock_old[PICOPASS_BLOCK_SIZE]; - uint8_t XorKeyBlock[PICOPASS_BLOCK_SIZE]; + uint8_t xorkeyblock[PICOPASS_BLOCK_SIZE]; generate_single_key_block_inverted(zero_key, index, GenKeyBlock); //NOTE BEFORE UPDATING THE KEY WE NEED TO KEEP IN MIND KEYS ARE XORRED @@ -2288,10 +2259,10 @@ void iClass_Recover(iclass_recover_req_t *msg) { if(index != 0){ generate_single_key_block_inverted(zero_key, index - 1, GenKeyBlock_old); for (int i = 0; i < 8 ; i++) { - XorKeyBlock[i] = GenKeyBlock[i] ^ GenKeyBlock_old[i]; + xorkeyblock[i] = GenKeyBlock[i] ^ GenKeyBlock_old[i]; } }else{ - memcpy(XorKeyBlock, GenKeyBlock, PICOPASS_BLOCK_SIZE); + memcpy(xorkeyblock, GenKeyBlock, PICOPASS_BLOCK_SIZE); } //Step4 Calculate New Mac @@ -2300,13 +2271,13 @@ void iClass_Recover(iclass_recover_req_t *msg) { uint8_t wb[9] = {0}; blockno = 3; wb[0] = blockno; - memcpy(wb + 1, XorKeyBlock, 8); + memcpy(wb + 1, xorkeyblock, 8); doMAC_N(wb, sizeof(wb), div_key2, mac2); //Step5 Perform Write - if (iclass_writeblock_ext(blockno, XorKeyBlock, mac2, use_mac, shallow_mod)) { + if (iclass_writeblock_ext(blockno, xorkeyblock, mac2, use_mac, shallow_mod)) { Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), blockno, blockno); } else { Dbprintf("Write block [%3d/0x%02X] " _RED_("failed"), blockno, blockno); @@ -2332,15 +2303,15 @@ void iClass_Recover(iclass_recover_req_t *msg) { restore: ;//empty statement for compilation - uint8_t partialKey[PICOPASS_BLOCK_SIZE]; - convertToHexArray(bits_found, partialKey); + uint8_t partialkey[PICOPASS_BLOCK_SIZE]; + convertToHexArray(bits_found, partialkey); for (int i = 0; i < 8; i++){ - Dbprintf("Raw Key Partial Bytes: " _GREEN_("[%3d -> 0x%02X]"), i, partialKey); + Dbprintf("Raw Key Partial Bytes: " _GREEN_("[%3d -> 0x%02X]"), i, partialkey); } - uint8_t resetKey[PICOPASS_BLOCK_SIZE]; - convertToHexArray(index, resetKey); + uint8_t resetkey[PICOPASS_BLOCK_SIZE]; + convertToHexArray(index, resetkey); //Calculate reset Mac @@ -2348,10 +2319,10 @@ restore: uint8_t wb[9] = {0}; blockno = 3; wb[0] = blockno; - memcpy(wb + 1, resetKey, 8); + memcpy(wb + 1, resetkey, 8); doMAC_N(wb, sizeof(wb), div_key2, mac2); - if (iclass_writeblock_ext(blockno, resetKey, mac2, use_mac, shallow_mod)) { + if (iclass_writeblock_ext(blockno, resetkey, mac2, use_mac, shallow_mod)) { Dbprintf("Restore of Original Key [%3d/0x%02X] " _GREEN_("successful"), blockno, blockno); } else { Dbprintf("Restore of Original Key [%3d/0x%02X] " _RED_("failed"), blockno, blockno); diff --git a/armsrc/iclass.h b/armsrc/iclass.h index 56030acc0..1480ef56c 100644 --- a/armsrc/iclass.h +++ b/armsrc/iclass.h @@ -71,9 +71,6 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, ui uint8_t get_pagemap(const picopass_hdr_t *hdr); void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time, bool shallow_mod); -void generate_single_key_block_inverted(const uint8_t startingKey[PICOPASS_BLOCK_SIZE], uint32_t index, uint8_t keyBlock[PICOPASS_BLOCK_SIZE]); -void intToBinary(unsigned int num, char *binaryStr, int size); -uint8_t binaryToHex(char *binaryStr); -void convertToHexArray(unsigned int num, uint8_t *partialKey); +void generate_single_key_block_inverted(const uint8_t *startingKey, uint32_t index, uint8_t *keyBlock); void iClass_Recover(iclass_recover_req_t *msg); #endif diff --git a/armsrc/util.c b/armsrc/util.c index 89a5d598b..2c7f6bc49 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -395,3 +395,33 @@ uint32_t flash_size_from_cidr(uint32_t cidr) { uint32_t get_flash_size(void) { return flash_size_from_cidr(*AT91C_DBGU_CIDR); } + +// Function to convert an unsigned int to binary string +void intToBinary(uint8_t num, char *binaryStr, int size) { + binaryStr[size] = '\0'; // Null-terminate the string + for (int i = size - 1; i >= 0; i--) { + binaryStr[i] = (num % 2) ? '1' : '0'; + num /= 2; + } +} + +// Function to convert a binary string to hexadecimal +uint8_t binaryToHex(char *binaryStr) { + return (uint8_t)strtoul(binaryStr, NULL, 2); +} + +// Function to convert an unsigned int to an array of hex values +void convertToHexArray(uint8_t num, uint8_t *partialkey) { + char binaryStr[25]; // 24 bits for binary representation + 1 for null terminator + + // Convert the number to binary string + intToBinary(num, binaryStr, 24); + + // Split the binary string into groups of 3 and convert to hex + for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) { + char group[4]; + strncpy(group, binaryStr + i * 3, 3); + group[3] = '\0'; // Null-terminate the group string + partialkey[i] = binaryToHex(group); + } +} \ No newline at end of file diff --git a/armsrc/util.h b/armsrc/util.h index 8842b5d8d..709c11c3e 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -88,6 +88,10 @@ int hex2binarray(char *target, char *source); int hex2binarray_n(char *target, const char *source, int sourcelen); int binarray2hex(const uint8_t *bs, int bs_len, uint8_t *hex); +void intToBinary(uint8_t num, char *binaryStr, int size); +uint8_t binaryToHex(char *binaryStr); +void convertToHexArray(uint8_t num, uint8_t *partialKey); + void LED(int led, int ms); void LEDsoff(void); void SpinOff(uint32_t pause); diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ad6ea39f0..86580b01f 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3845,7 +3845,8 @@ void picopass_elite_nextKey(uint8_t* key) { static int CmdHFiClassRecover(uint8_t key[8]) { uint32_t payload_size = sizeof(iclass_recover_req_t); - uint8_t aa2_standard_key[PICOPASS_BLOCK_SIZE] = {0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90}; + uint8_t aa2_standard_key[PICOPASS_BLOCK_SIZE] = {0}; + memcpy(aa2_standard_key, iClass_Key_Table[1], PICOPASS_BLOCK_SIZE); iclass_recover_req_t *payload = calloc(1, payload_size); payload->req.use_raw = true; payload->req.use_elite = false; @@ -3920,22 +3921,6 @@ void *generate_key_blocks(void *arg) { return NULL; } -void generate_single_key_block_inverted(const uint8_t startingKey[PICOPASS_BLOCK_SIZE], uint32_t index, uint8_t keyBlock[PICOPASS_BLOCK_SIZE]) { - uint32_t carry = index; - memcpy(keyBlock, startingKey, PICOPASS_BLOCK_SIZE); - - for (int j = PICOPASS_BLOCK_SIZE - 1; j >= 0; j--) { - uint8_t increment_value = carry & 0x07; // Use only the last 3 bits of carry - keyBlock[j] = increment_value; // Set the last 3 bits, assuming first 5 bits are always 0 - - carry >>= 3; // Shift right by 3 bits for the next byte - if (carry == 0) { - // If no more carry, break early to avoid unnecessary loops - break; - } - } -} - static int CmdHFiClassLegRecLookUp(const char *Cmd) { //Standalone Command Start diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index 8bbab9216..5a4b20aec 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -42,7 +42,5 @@ void picopass_elite_reset(void); uint32_t picopass_elite_rng(void); uint32_t picopass_elite_lcg(void); uint8_t picopass_elite_nextByte(void); - void *generate_key_blocks(void *arg); -void generate_single_key_block_inverted(const uint8_t startingKey[PICOPASS_BLOCK_SIZE], uint32_t index, uint8_t keyBlock[PICOPASS_BLOCK_SIZE]); #endif