mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
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.
This commit is contained in:
parent
c7541790f8
commit
a127a38cb6
6 changed files with 50 additions and 65 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue