Merge branch 'master' into dev_4x50_standalone

solved merge conflicts
This commit is contained in:
tharexde 2021-01-30 00:29:18 +01:00
commit b57a457254
67 changed files with 943 additions and 683 deletions

View file

@ -4,7 +4,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased] ## [unreleased][unreleased]
- Added `LF_THAREXDE` standalone mode which simulates and reads EM4x50 cards (@tharexde) - Added `LF_THAREXDE` standalone mode which simulates and reads EM4x50 cards (@tharexde)
- Changed `wiegand encode` - format param is now optional, w/o it will try encode all formats (@iceman1001)
- Fix cppchecker warnings (@iceman1001)
- Added `trace list -t mf` - now can use external dictionary keys file
- Added support for bidirectional communication for `lf em 4x50 sim` (@tharexde) - Added support for bidirectional communication for `lf em 4x50 sim` (@tharexde)
- Change `PLATFORM=PM3OTHER` to `PLATFORM=PM3GENERIC` (@iceman1001)
- Added `tools/hitag2crack/crack5opencl`, an optimized version of `crack5gpu` (@matrix) - Added `tools/hitag2crack/crack5opencl`, an optimized version of `crack5gpu` (@matrix)
- Fixed Makefile to account for changes when running on Apple Silicon (@tcprst) - Fixed Makefile to account for changes when running on Apple Silicon (@tcprst)
- Added support for debugging ARM with JTAG & VSCode (@Gator96100) - Added support for debugging ARM with JTAG & VSCode (@Gator96100)

View file

@ -170,12 +170,9 @@ static void save_to_flash(uint8_t *data, uint16_t datalen, char *filename) {
data[4], data[5], data[6], data[7] data[4], data[5], data[6], data[7]
); );
} else { } else {
int name_len = SPIFFS_OBJ_NAME_LEN; int fnlen = MIN(strlen(filename), SPIFFS_OBJ_NAME_LEN);
int filename_len = strlen(filename);
// if the given name len longer than buffer allows, cut it down to size // if the given name len longer than buffer allows, cut it down to size
name_len = (name_len >= SPIFFS_OBJ_NAME_LEN) ? SPIFFS_OBJ_NAME_LEN : filename_len; memcpy(fn, filename, fnlen);
memcpy(fn, filename, name_len);
} }
int res; int res;

View file

@ -248,11 +248,9 @@ void RunMod(void) {
dynamic_response_info.response[0] = receivedCmd[0]; dynamic_response_info.response[0] = receivedCmd[0];
if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) { if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
memcpy(dynamic_response_info.response + 1, ndef, 31); memcpy(dynamic_response_info.response + 1, ndef, 31);
dynamic_response_info.response_n = 32; dynamic_response_info.response_n = 32;
} else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) { } else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x63; dynamic_response_info.response[1] = 0x63;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
@ -260,14 +258,12 @@ void RunMod(void) {
memcpy(verify_pwd + 5, receivedCmd + 6, 16); memcpy(verify_pwd + 5, receivedCmd + 6, 16);
DbpString("Reader sent password: "); DbpString("Reader sent password: ");
Dbhexdump(16, verify_pwd + 5, 0); Dbhexdump(16, verify_pwd + 5, 0);
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90; dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
gotkey = true; gotkey = true;
state = STATE_DUMP; state = STATE_DUMP;
} else { } else {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90; dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
@ -321,7 +317,7 @@ void RunMod(void) {
LED_B_ON(); LED_B_ON();
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL); uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
if (apdulen > 0) { if (apdulen > 2) {
DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]")); DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]"));
Dbhexdump(apdusLen[i], apdus[i], false); Dbhexdump(apdusLen[i], apdus[i], false);
DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]")); DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]"));
@ -429,11 +425,9 @@ void RunMod(void) {
dynamic_response_info.response[0] = receivedCmd[0]; dynamic_response_info.response[0] = receivedCmd[0];
if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) { if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
memcpy(dynamic_response_info.response + 1, ndef, 31); memcpy(dynamic_response_info.response + 1, ndef, 31);
dynamic_response_info.response_n = 32; dynamic_response_info.response_n = 32;
} else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) { } else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x63; dynamic_response_info.response[1] = 0x63;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
@ -441,12 +435,10 @@ void RunMod(void) {
memcpy(verify_pwd + 5, receivedCmd + 6, 16); memcpy(verify_pwd + 5, receivedCmd + 6, 16);
DbpString("Reader sent password: "); DbpString("Reader sent password: ");
Dbhexdump(16, verify_pwd + 5, 0); Dbhexdump(16, verify_pwd + 5, 0);
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90; dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
} else { } else {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90; dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;

View file

@ -21,19 +21,19 @@
#include "commonutil.h" #include "commonutil.h"
#define MAX_IND 16 // 4 LEDs - 2^4 combinations #define MAX_IND 16 // 4 LEDs - 2^4 combinations
#define CLOCK 64 //for 125kHz #define LF_CLOCK 64 // for 125kHz
// low & high - array for storage IDs. Its length must be equal. // low & high - array for storage IDs. Its length must be equal.
// Predefined IDs must be stored in low[]. // Predefined IDs must be stored in low[].
static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF}; static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
static uint8_t *bba, slots_count; static uint8_t slots_count;
static int buflen; static int buflen;
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF EM4100 simulator standalone mode"); DbpString(" LF EM4100 simulator standalone mode");
} }
static uint64_t ReversQuads(uint64_t bits) { static uint64_t rev_quads(uint64_t bits) {
uint64_t result = 0; uint64_t result = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -41,32 +41,40 @@ static uint64_t ReversQuads(uint64_t bits) {
return result >> 24; return result >> 24;
} }
static void FillBuff(uint8_t bit) { static void fill_buff(uint8_t bit) {
memset(bba + buflen, bit, CLOCK / 2); uint8_t *bba = BigBuf_get_addr();
buflen += (CLOCK / 2); memset(bba + buflen, bit, LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, CLOCK / 2); buflen += (LF_CLOCK / 2);
buflen += (CLOCK / 2); memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
} }
static void ConstructEM410xEmulBuf(uint64_t id) { static void construct_EM410x_emul(uint64_t id) {
int i, j, binary[4], parity[4]; int i, j;
int binary[4] = {0,0,0,0};
int parity[4] = {0,0,0,0};
buflen = 0; buflen = 0;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
FillBuff(1); fill_buff(1);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2) for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2; binary[j] = id % 2;
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
FillBuff(binary[j]); fill_buff(binary[j]);
FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
parity[j] ^= binary[j]; parity[j] ^= binary[j];
} }
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
FillBuff(parity[j]); fill_buff(parity[j]);
FillBuff(0);
fill_buff(0);
} }
static void LED_Slot(int i) { static void LED_Slot(int i) {
@ -85,14 +93,14 @@ void RunMod(void) {
int selected = 0; //selected slot after start int selected = 0; //selected slot after start
slots_count = ARRAYLEN(low); slots_count = ARRAYLEN(low);
bba = BigBuf_get_addr();
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
if (data_available()) break; if (data_available()) break;
SpinDelay(100); SpinDelay(100);
SpinUp(100); SpinUp(100);
LED_Slot(selected); LED_Slot(selected);
ConstructEM410xEmulBuf(ReversQuads(low[selected])); construct_EM410x_emul(rev_quads(low[selected]));
SimulateTagLowFrequency(buflen, 0, true); SimulateTagLowFrequency(buflen, 0, true);
selected = (selected + 1) % slots_count; selected = (selected + 1) % slots_count;
} }

View file

@ -76,14 +76,13 @@ static int bruteforceSpeed[] = {10, 12, 14, 16};
// In high[] must be nulls // In high[] must be nulls
static uint64_t low[] = {0, 0, 0, 0}; static uint64_t low[] = {0, 0, 0, 0};
static uint32_t high[] = {0, 0, 0, 0}; static uint32_t high[] = {0, 0, 0, 0};
static uint8_t *bba;
static int buflen; static int buflen;
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF EM4100 read/sim/write/brute mode"); DbpString(" LF EM4100 read/sim/write/brute mode");
} }
static uint64_t ReversQuads(uint64_t bits) { static uint64_t rev_quads(uint64_t bits) {
uint64_t result = 0; uint64_t result = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -91,33 +90,39 @@ static uint64_t ReversQuads(uint64_t bits) {
return result >> 24; return result >> 24;
} }
static void FillBuff(uint8_t bit) { static void fill_buff(uint8_t bit) {
uint8_t *bba = BigBuf_get_addr();
memset(bba + buflen, bit, LF_CLOCK / 2); memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2); buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2); memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2); buflen += (LF_CLOCK / 2);
} }
static void ConstructEM410xEmulBuf(uint64_t id) { static void construct_EM410x_emul(uint64_t id) {
bba = BigBuf_get_addr(); int i, j;
int binary[4] = {0,0,0,0};
int i, j, binary[4], parity[4]; int parity[4] = {0,0,0,0};
buflen = 0; buflen = 0;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
FillBuff(1); fill_buff(1);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2) for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2; binary[j] = id % 2;
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
FillBuff(binary[j]); fill_buff(binary[j]);
FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
parity[j] ^= binary[j]; parity[j] ^= binary[j];
} }
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
FillBuff(parity[j]); fill_buff(parity[j]);
FillBuff(0);
fill_buff(0);
} }
static void LED_Update(int mode, int slot) { static void LED_Update(int mode, int slot) {
@ -197,7 +202,6 @@ static uint64_t PackEmID(uint64_t original, int newCardNum) {
return buf; return buf;
} }
static void PrintFcAndCardNum(uint64_t lowData) { static void PrintFcAndCardNum(uint64_t lowData) {
// Calculate Facility Code and Card Number from high and low // Calculate Facility Code and Card Number from high and low
uint32_t fc = (lowData >> 17) & 0xFF; uint32_t fc = (lowData >> 17) & 0xFF;
@ -222,7 +226,7 @@ static int BruteEMTag(uint64_t originalCard, int slot) {
cardnum = cardnum + direction; cardnum = cardnum + direction;
uint64_t currentCard = PackEmID(originalCard, cardnum); uint64_t currentCard = PackEmID(originalCard, cardnum);
Dbprintf("[=] >> Simulating card id %"PRIx64" <<", currentCard); Dbprintf("[=] >> Simulating card id %"PRIx64" <<", currentCard);
ConstructEM410xEmulBuf(ReversQuads(currentCard)); construct_EM410x_emul(rev_quads(currentCard));
SimulateTagLowFrequencyEx(buflen, 0, 1, bruteforceSpeed[bruteforceSpeedCurrent] * 10000); SimulateTagLowFrequencyEx(buflen, 0, 1, bruteforceSpeed[bruteforceSpeedCurrent] * 10000);
int button_pressed = BUTTON_CLICKED(1000); int button_pressed = BUTTON_CLICKED(1000);
@ -267,7 +271,7 @@ static int ExecuteMode(int mode, int slot) {
return LF_RWSB_UNKNOWN_RESULT; return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_SIM: case LF_RWSB_MODE_SIM:
Dbprintf("[=] >> Sim mode started <<"); Dbprintf("[=] >> Sim mode started <<");
ConstructEM410xEmulBuf(ReversQuads(low[slot])); construct_EM410x_emul(rev_quads(low[slot]));
SimulateTagLowFrequency(buflen, 0, 1); SimulateTagLowFrequency(buflen, 0, 1);
return LF_RWSB_UNKNOWN_RESULT; return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_WRITE: case LF_RWSB_MODE_WRITE:
@ -310,7 +314,6 @@ void RunMod() {
int slot = 0; int slot = 0;
mode = SwitchMode(mode, slot); mode = SwitchMode(mode, slot);
bba = BigBuf_get_addr();
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
if (data_available()) break; if (data_available()) break;

View file

@ -41,7 +41,7 @@
// In high[] must be nulls // In high[] must be nulls
static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static uint8_t *bba, slots_count; static uint8_t slots_count;
static int buflen; static int buflen;
void ModInfo(void) { void ModInfo(void) {
@ -56,7 +56,8 @@ static uint64_t rev_quads(uint64_t bits) {
return result >> 24; return result >> 24;
} }
static void fillbuff(uint8_t bit) { static void fill_buff(uint8_t bit) {
uint8_t *bba = BigBuf_get_addr();
memset(bba + buflen, bit, LF_CLOCK / 2); memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2); buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2); memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
@ -66,29 +67,29 @@ static void fillbuff(uint8_t bit) {
static void construct_EM410x_emul(uint64_t id) { static void construct_EM410x_emul(uint64_t id) {
int i, j; int i, j;
int binary[4] = {0}; int binary[4] = {0,0,0,0};
int parity[4] = {0}; int parity[4] = {0,0,0,0};
buflen = 0; buflen = 0;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
fillbuff(1); fill_buff(1);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2) for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2; binary[j] = id % 2;
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
fillbuff(binary[j]); fill_buff(binary[j]);
fillbuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
parity[j] ^= binary[j]; parity[j] ^= binary[j];
} }
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
fillbuff(parity[j]); fill_buff(parity[j]);
fillbuff(0); fill_buff(0);
} }
static void led_slot(int i) { static void led_slot(int i) {
@ -138,7 +139,6 @@ void RunMod(void) {
// 3 - write to T5555 tag // 3 - write to T5555 tag
uint8_t state = 0; uint8_t state = 0;
slots_count = ARRAYLEN(low); slots_count = ARRAYLEN(low);
bba = BigBuf_get_addr();
led_slot(selected); led_slot(selected);
for (;;) { for (;;) {

View file

@ -1666,10 +1666,6 @@ static void PacketReceived(PacketCommandNG *packet) {
iClass_ReadBlock(packet->data.asBytes); iClass_ReadBlock(packet->data.asBytes);
break; break;
} }
case CMD_HF_ICLASS_AUTH: { //check
iClass_Authentication(packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_CHKKEYS: { case CMD_HF_ICLASS_CHKKEYS: {
iClass_Authentication_fast(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); iClass_Authentication_fast(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
break; break;

View file

@ -676,7 +676,7 @@ static bool brute(uint32_t start, uint32_t stop, uint32_t *pwd) {
void em4x50_login(uint32_t *password) { void em4x50_login(uint32_t *password) {
em4x50_setup_read(); em4x50_setup_read();
uint8_t status = PM3_EFAILED; int status = PM3_EFAILED;
LED_C_ON(); LED_C_ON();
if (get_signalproperties() && find_em4x50_tag()) { if (get_signalproperties() && find_em4x50_tag()) {
LED_C_OFF(); LED_C_OFF();
@ -1232,7 +1232,7 @@ static int em4x50_sim_read_bit(void) {
if (timeout <= 0) { if (timeout <= 0) {
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; // timeout = EM4X50_T_SIMULATION_TIMEOUT_READ;
// now we have a reference "position", from here it will take // now we have a reference "position", from here it will take
// slightly less than 32 cycles until the end of the bit period // slightly less than 32 cycles until the end of the bit period
@ -1432,7 +1432,7 @@ static int em4x50_sim_handle_standard_read_command(uint32_t *tag) {
WDT_HIT(); WDT_HIT();
command = em4x50_sim_send_listen_window(tag); int command = em4x50_sim_send_listen_window(tag);
if (command != PM3_SUCCESS) { if (command != PM3_SUCCESS) {
return command; return command;
} }
@ -1488,7 +1488,7 @@ static int em4x50_sim_handle_selective_read_command(uint32_t *tag) {
WDT_HIT(); WDT_HIT();
command = em4x50_sim_send_listen_window(tag); int command = em4x50_sim_send_listen_window(tag);
if (command != PM3_SUCCESS) { if (command != PM3_SUCCESS) {
return command; return command;
} }

View file

@ -662,10 +662,11 @@ void em4x70_write(em4x70_data_t *etd) {
if (status) { if (status) {
// Read Tag after writing // Read Tag after writing
em4x70_read_id(); if (em4x70_read_id()) {
em4x70_read_um1(); em4x70_read_um1();
em4x70_read_um2(); em4x70_read_um2();
} }
}
} }

View file

@ -408,9 +408,9 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
// Tag CSN // Tag CSN
uint8_t *modulated_response = NULL; uint8_t *modulated_response = NULL;
int modulated_response_size = 0; int modulated_response_size;
uint8_t *trace_data = NULL; uint8_t *trace_data = NULL;
int trace_data_size = 0; int trace_data_size;
// Respond SOF -- takes 1 bytes // Respond SOF -- takes 1 bytes
uint8_t *resp_sof = BigBuf_malloc(1); uint8_t *resp_sof = BigBuf_malloc(1);
@ -498,10 +498,9 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
bool button_pressed = false; bool button_pressed = false;
uint8_t cmd, options, block; uint8_t cmd, options, block;
int len = 0; int len, kc_attempt = 0;
bool exit_loop = false; bool exit_loop = false;
bool using_kc = false; bool using_kc = false;
int kc_attempt = 0;
while (exit_loop == false) { while (exit_loop == false) {
WDT_HIT(); WDT_HIT();
@ -1364,6 +1363,8 @@ static bool select_iclass_tag_ex(picopass_hdr *hdr, bool use_credit_key, uint32_
return false; return false;
memcpy(hdr->epurse, resp, sizeof(hdr->epurse)); memcpy(hdr->epurse, resp, sizeof(hdr->epurse));
if (status)
*status |= FLAG_ICLASS_CC; *status |= FLAG_ICLASS_CC;
} else { } else {
@ -1469,16 +1470,9 @@ void ReaderIClass(uint8_t flags) {
switch_off(); switch_off();
} }
// used with function select_and_auth (cmdhficlass.c)
// which needs to authenticate before doing more things like read/write
// selects and authenticate to a card, sends back div_key and mac to client.
void iClass_Authentication(uint8_t *msg) {
}
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out) { bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out) {
uint8_t cmd_check[9] = { ICLASS_CMD_CHECK }; uint8_t cmd_check[9] = { ICLASS_CMD_CHECK };
uint8_t div_key[8] = {0};
uint8_t mac[4] = {0}; uint8_t mac[4] = {0};
uint8_t resp_auth[4] = {0}; uint8_t resp_auth[4] = {0};
uint8_t ccnr[12] = {0}; uint8_t ccnr[12] = {0};
@ -1495,6 +1489,8 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint
memcpy(cmd_check + 1, payload->key, 8); memcpy(cmd_check + 1, payload->key, 8);
} else { } else {
uint8_t div_key[8] = {0};
if (payload->use_raw) if (payload->use_raw)
memcpy(div_key, payload->key, 8); memcpy(div_key, payload->key, 8);
else else
@ -1792,7 +1788,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac,
uint8_t resp[10] = {0}; uint8_t resp[10] = {0};
uint32_t eof_time = 0, start_time = 0; uint32_t eof_time = 0, start_time = 0;
bool isOK = iclass_send_cmd_with_retries(write, sizeof(write), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time); bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time);
if (isOK == false) { if (isOK == false) {
return false; return false;
} }
@ -1833,7 +1829,7 @@ void iClass_WriteBlock(uint8_t *msg) {
// select tag. // select tag.
uint32_t eof_time = 0; uint32_t eof_time = 0;
picopass_hdr hdr = {0}; picopass_hdr hdr = {0};
bool res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time); uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time);
if (res == false) { if (res == false) {
goto out; goto out;
} }

View file

@ -16,7 +16,7 @@
#include "pm3_cmd.h" #include "pm3_cmd.h"
void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string); void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string);
void ReaderIClass(uint8_t arg0); void ReaderIClass(uint8_t flags);
void iClass_WriteBlock(uint8_t *msg); void iClass_WriteBlock(uint8_t *msg);
void iClass_Dump(uint8_t *msg); void iClass_Dump(uint8_t *msg);
@ -29,7 +29,6 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen); void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen);
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain); void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
void iClass_Authentication(uint8_t *bytes);
bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out); bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out);
void iClass_ReadBlock(uint8_t *msg); void iClass_ReadBlock(uint8_t *msg);

View file

@ -1845,9 +1845,8 @@ void BruteforceIso15693Afi(uint32_t speed) {
int datalen = 5; int datalen = 5;
uint32_t eof_time = 0; uint32_t eof_time = 0;
uint32_t start_time = GetCountSspClk();
int recvlen = SendDataTag(data, datalen, true, speed, recv, sizeof(recv), 0, ISO15693_READER_TIMEOUT, &eof_time); int recvlen = SendDataTag(data, datalen, true, speed, recv, sizeof(recv), 0, ISO15693_READER_TIMEOUT, &eof_time);
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; uint32_t start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
WDT_HIT(); WDT_HIT();

View file

@ -696,7 +696,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
LED_C_ON(); LED_C_ON();
for (uint16_t i = 0; i <= PM3_CMD_DATA_SIZE - 4; i += 4) { while (num_nonces < PM3_CMD_DATA_SIZE / 4) {
// Test if the action was cancelled // Test if the action was cancelled
if (BUTTON_PRESS()) { if (BUTTON_PRESS()) {
@ -746,18 +746,14 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
continue; continue;
} }
num_nonces++;
// Save the tag nonce (nt) // Save the tag nonce (nt)
buf[i] = answer[0]; memcpy(buf + num_nonces * 4, answer, 4);
buf[i + 1] = answer[1]; num_nonces++;
buf[i + 2] = answer[2];
buf[i + 3] = answer[3];
} }
LED_C_OFF(); LED_C_OFF();
LED_B_ON(); LED_B_ON();
reply_old(CMD_ACK, isOK, cuid, num_nonces - 1, buf, sizeof(buf)); reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
LED_B_OFF(); LED_B_OFF();
if (DBGLEVEL >= 3) DbpString("AcquireNonces finished"); if (DBGLEVEL >= 3) DbpString("AcquireNonces finished");
@ -826,7 +822,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
if (!have_uid) { // need a full select cycle to get the uid first if (!have_uid) { // need a full select cycle to get the uid first
iso14a_card_select_t card_info; iso14a_card_select_t card_info;
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (ALL)"); if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (ALL)");
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
@ -845,7 +841,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
if (!iso14443a_fast_select_card(uid, cascade_levels)) { if (!iso14443a_fast_select_card(uid, cascade_levels)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (UID)"); if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (UID)");
continue; continue;
} }
} }
@ -855,7 +851,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
uint32_t nt1; uint32_t nt1;
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth1 error"); if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Auth1 error");
continue; continue;
} }
@ -866,7 +862,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
CHK_TIMEOUT(); CHK_TIMEOUT();
if (len != 4) { if (len != 4) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth2 error len=%d", len); if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Auth2 error len=%d", len);
continue; continue;
} }

View file

@ -68,9 +68,12 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
// send X byte basic commands // send X byte basic commands
int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
uint8_t dcmd[data_size + 3]; uint8_t dcmd[data_size + 3];
dcmd[0] = cmd; dcmd[0] = cmd;
if (data_size > 0)
memcpy(dcmd + 1, data, data_size); memcpy(dcmd + 1, data, data_size);
AddCrc14A(dcmd, data_size + 1); AddCrc14A(dcmd, data_size + 1);
ReaderTransmit(dcmd, sizeof(dcmd), timing); ReaderTransmit(dcmd, sizeof(dcmd), timing);
int len = ReaderReceive(answer, answer_parity); int len = ReaderReceive(answer, answer_parity);

View file

@ -830,7 +830,7 @@ static void arg_date_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -846,11 +846,11 @@ static void arg_date_errorfn(
struct tm tm; struct tm tm;
char buff[200]; char buff[200];
fprintf(fp, "illegal timestamp format \"%s\"\n", argval); fprintf(fp, "[!] illegal timestamp format \"%s\"\n", argval);
memset(&tm, 0, sizeof(tm)); memset(&tm, 0, sizeof(tm));
arg_strptime("1999-12-31 23:59:59", "%F %H:%M:%S", &tm); arg_strptime("1999-12-31 23:59:59", "%F %H:%M:%S", &tm);
strftime(buff, sizeof(buff), parent->format, &tm); strftime(buff, sizeof(buff), parent->format, &tm);
printf("correct format is \"%s\"\n", buff); printf("[+] correct format is \"%s\"\n", buff);
break; break;
} }
} }
@ -1442,7 +1442,7 @@ static void arg_dbl_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -1455,7 +1455,7 @@ static void arg_dbl_errorfn(
break; break;
case EBADDOUBLE: case EBADDOUBLE:
fprintf(fp, "invalid argument \"%s\" to option ", argval); fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n"); arg_print_option(fp, shortopts, longopts, datatype, "\n");
break; break;
} }
@ -1805,7 +1805,7 @@ static void arg_file_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -1818,7 +1818,7 @@ static void arg_file_errorfn(
break; break;
default: default:
fprintf(fp, "unknown error at \"%s\"\n", argval); fprintf(fp, "[!] unknown error at \"%s\"\n", argval);
} }
} }
@ -2136,7 +2136,7 @@ static void arg_int_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -2149,7 +2149,7 @@ static void arg_int_errorfn(
break; break;
case EBADINT: case EBADINT:
fprintf(fp, "invalid argument \"%s\" to option ", argval); fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n"); arg_print_option(fp, shortopts, longopts, datatype, "\n");
break; break;
@ -2394,7 +2394,7 @@ static void arg_u64_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -2407,7 +2407,7 @@ static void arg_u64_errorfn(
break; break;
case EBADINT: case EBADINT:
fprintf(fp, "invalid argument \"%s\" to option ", argval); fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n"); arg_print_option(fp, shortopts, longopts, datatype, "\n");
break; break;
@ -2554,18 +2554,18 @@ static void arg_lit_errorfn(
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fprintf(fp, "%s: missing option ", progname); fprintf(fp, "[!] %s: missing option ", progname);
arg_print_option(fp, shortopts, longopts, datatype, "\n"); arg_print_option(fp, shortopts, longopts, datatype, "\n");
fprintf(fp, "\n"); fprintf(fp, "\n");
break; break;
case EMAXCOUNT: case EMAXCOUNT:
fprintf(fp, "%s: extraneous option ", progname); fprintf(fp, "[!] %s: extraneous option ", progname);
arg_print_option(fp, shortopts, longopts, datatype, "\n"); arg_print_option(fp, shortopts, longopts, datatype, "\n");
break; break;
} }
ARG_TRACE(("%s:errorfn(%p, %p, %d, %s, %s)\n", __FILE__, parent, fp, ARG_TRACE(("[!] %s:errorfn(%p, %p, %d, %s, %s)\n", __FILE__, parent, fp,
errorcode, argval, progname)); errorcode, argval, progname));
} }
@ -2859,7 +2859,7 @@ static void arg_rex_errorfn(struct arg_rex *parent,
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);
@ -3790,7 +3790,7 @@ static void arg_str_errorfn(
/* make argval NULL safe */ /* make argval NULL safe */
argval = argval ? argval : ""; argval = argval ? argval : "";
fprintf(fp, "%s: ", progname); fprintf(fp, "[!] %s: ", progname);
switch (errorcode) { switch (errorcode) {
case EMINCOUNT: case EMINCOUNT:
fputs("missing option ", fp); fputs("missing option ", fp);

View file

@ -118,7 +118,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
if (nerrors > 0) { if (nerrors > 0) {
/* Display the error details contained in the arg_end struct.*/ /* Display the error details contained in the arg_end struct.*/
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName); arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
PrintAndLogEx(WARNING, "Try '%s --help' for more information.\n", ctx->programName); PrintAndLogEx(WARNING, "Try " _YELLOW_("'%s --help'") " for more information.\n", ctx->programName);
fflush(stdout); fflush(stdout);
return 3; return 3;
} }
@ -269,15 +269,19 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
return 0; return 0;
} }
// hexstr -> u64, w optional len input and default value fallback.
// 0 = failed
// 1 = OK
// 3 = optional param - not set
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def) { uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def) {
uint64_t rv = 0; uint64_t rv = 0;
uint8_t data[8]; uint8_t d[8];
int datalen = 0; int dlen = 0;
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), &datalen); int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &dlen);
if (res == 0 && datalen > 0) { if (res == 0 && dlen > 0) {
for (uint8_t i = 0; i < datalen; i++) { for (uint8_t i = 0; i < dlen; i++) {
rv <<= 8; rv <<= 8;
rv |= data[i]; rv |= d[i];
} }
} else { } else {
rv = def; rv = def;
@ -285,11 +289,38 @@ uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_
return rv; return rv;
} }
int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out) { // hexstr -> u64, w optional len input and default value fallback.
return arg_get_u32_hexstr_def_nlen(ctx, paramnum, def, out, 4); // 0 = failed
// 1 = OK
// 2 = wrong len param, use default
// 3 = optional param, if fail, use default.
int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional) {
int n = 0;
uint8_t d[nlen];
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &n);
if (res == 0 && n == nlen) {
uint64_t rv = 0;
for (uint8_t i = 0; i < n; i++) {
rv <<= 8;
rv |= d[i];
}
*out = rv;
return 1;
} else if (res == 0 && n) {
*out = def;
return 2;
} else if (res == 0 && n == 0 && optional) {
*out = def;
return 3;
}
return 0;
} }
int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen) { int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out) {
return arg_get_u32_hexstr_def_nlen(ctx, paramnum, def, out, 4, false);
}
int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen, bool optional) {
int n = 0; int n = 0;
uint8_t d[nlen]; uint8_t d[nlen];
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &n); int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &n);
@ -304,6 +335,9 @@ int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_
} else if (res == 0 && n) { } else if (res == 0 && n) {
*out = def; *out = def;
return 2; return 2;
} else if (res == 0 && n == 0 && optional) {
*out = def;
return 3;
} }
return 0; return 0;
} }

View file

@ -68,6 +68,13 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def); uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def);
int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional);
int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out); int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out);
int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen); int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen, bool optional);
#define CP_SUCCESS_OPTIONAL 1
#define CP_SUCCESS 0
#define CP_ENOPARAM -1
#define CP_WRONGLEN -2
#endif #endif

View file

@ -559,6 +559,10 @@ void SetSIMDInstr(SIMDExecInstr instr) {
static SIMDExecInstr GetSIMDInstr(void) { static SIMDExecInstr GetSIMDInstr(void) {
SIMDExecInstr instr; SIMDExecInstr instr;
#if defined(COMPILER_HAS_SIMD)
__builtin_cpu_init();
#endif
#if defined(COMPILER_HAS_SIMD_AVX512) #if defined(COMPILER_HAS_SIMD_AVX512)
if (__builtin_cpu_supports("avx512f")) if (__builtin_cpu_supports("avx512f"))
instr = SIMD_AVX512; instr = SIMD_AVX512;

View file

@ -465,7 +465,8 @@ float brute_force_benchmark(void) {
free(test_candidates[0].states[ODD_STATE]); free(test_candidates[0].states[ODD_STATE]);
free(test_candidates[0].states[EVEN_STATE]); free(test_candidates[0].states[EVEN_STATE]);
test_candidates[0].len[ODD_STATE] = 0;
test_candidates[0].len[EVEN_STATE] = 0;
return bf_rate; return bf_rate;
} }

View file

@ -25,7 +25,7 @@
typedef struct guess_sum_a8 { typedef struct guess_sum_a8 {
float prob; float prob;
uint64_t num_states; uint64_t num_states;
uint8_t sum_a8_idx; uint16_t sum_a8_idx;
} guess_sum_a8_t; } guess_sum_a8_t;
typedef struct noncelistentry { typedef struct noncelistentry {
@ -40,7 +40,7 @@ typedef struct noncelist {
guess_sum_a8_t sum_a8_guess[NUM_SUMS]; guess_sum_a8_t sum_a8_guess[NUM_SUMS];
bool sum_a8_guess_dirty; bool sum_a8_guess_dirty;
float expected_num_brute_force; float expected_num_brute_force;
uint8_t BitFlips[0x400]; uint16_t BitFlips[0x400];
uint32_t *states_bitarray[2]; uint32_t *states_bitarray[2];
uint32_t num_states_bitarray[2]; uint32_t num_states_bitarray[2];
bool all_bitflips_dirty[2]; bool all_bitflips_dirty[2];

View file

@ -7,11 +7,11 @@ local ansicolors = require('ansicolors')
copyright = '' copyright = ''
author = 'Iceman' author = 'Iceman'
version = 'v1.0.3' version = 'v1.0.4'
desc = [[ desc = [[
This script will load several traces files in current working directory/traces/ folder and do This script will load several traces files in current working directory/traces/ folder and do
"data load" "data load"
"lf search 1 u" "lf search -1u"
The following tracefiles will be loaded: The following tracefiles will be loaded:
em*.pm3 em*.pm3
@ -109,7 +109,7 @@ local function main(args)
end end
p.close(); p.close();
local cmdLFSEARCH = 'lf search 1 u' local cmdLFSEARCH = 'lf search -1u'
-- main loop -- main loop
io.write('Starting to test traces > ') io.write('Starting to test traces > ')

View file

@ -19,6 +19,7 @@
#include "ui.h" // PrintAndLog #include "ui.h" // PrintAndLog
#include "crc.h" #include "crc.h"
#include "crc16.h" // crc16 ccitt #include "crc16.h" // crc16 ccitt
#include "crc32.h" // crc32_ex
#include "tea.h" #include "tea.h"
#include "legic_prng.h" #include "legic_prng.h"
#include "cmddata.h" // demodbuffer #include "cmddata.h" // demodbuffer
@ -170,6 +171,14 @@ static uint16_t calcBSDchecksum4(uint8_t *bytes, uint8_t len, uint32_t mask) {
return sum; return sum;
} }
// 0xFF - ( n1 ^ n... )
static uint16_t calcXORchecksum(uint8_t *bytes, uint8_t len, uint32_t mask) {
return 0xFF - calcSumByteXor(bytes, len, mask);
}
//2148050707DB0A0E000001C4000000
// measuring LFSR maximum length // measuring LFSR maximum length
static int CmdAnalyseLfsr(const char *Cmd) { static int CmdAnalyseLfsr(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
@ -353,6 +362,12 @@ static int CmdAnalyseCRC(const char *Cmd) {
uint16_t crcEE = b1 << 8 | b2; uint16_t crcEE = b1 << 8 | b2;
PrintAndLogEx(INFO, "FeliCa | %04x or %04x (31C3 expected)\n", crcEE, Crc16ex(CRC_FELICA, dataStr, sizeof(dataStr))); PrintAndLogEx(INFO, "FeliCa | %04x or %04x (31C3 expected)\n", crcEE, Crc16ex(CRC_FELICA, dataStr, sizeof(dataStr)));
uint32_t crc32 = 0;
crc32_ex(dataStr, sizeof(dataStr), (uint8_t *)&crc32);
PrintAndLogEx(INFO, "CRC32 (desfire) | %08x ( expected)", crc32);
PrintAndLogEx(INFO, "---------------------------------------------------------------\n\n\n");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -421,11 +436,12 @@ static int CmdAnalyseCHKSUM(const char *Cmd) {
PrintAndLogEx(INFO, "Mask value 0x%x", mask); PrintAndLogEx(INFO, "Mask value 0x%x", mask);
if (verbose) { if (verbose) {
PrintAndLogEx(INFO, " add | sub | add 1's compl | sub 1's compl | xor"); PrintAndLogEx(INFO, "------------------+-------------+------------------+-----------------+------------------+-----------+-------------");
PrintAndLogEx(INFO, "byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb | BSD |"); PrintAndLogEx(INFO, " add | sub | add 1's compl | sub 1's compl | xor | |");
PrintAndLogEx(INFO, "------------------+-------------+------------------+-----------------+--------------------"); PrintAndLogEx(INFO, "byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb | BSD | 0xFF - (n^n)");
PrintAndLogEx(INFO, "------------------+-------------+------------------+-----------------+------------------+-----------+-------------");
} }
PrintAndLogEx(INFO, "0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X |\n", PrintAndLogEx(INFO, "0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X\n",
calcSumByteAdd(data, dlen, mask) calcSumByteAdd(data, dlen, mask)
, calcSumNibbleAdd(data, dlen, mask) , calcSumNibbleAdd(data, dlen, mask)
, calcSumCrumbAdd(data, dlen, mask) , calcSumCrumbAdd(data, dlen, mask)
@ -441,6 +457,7 @@ static int CmdAnalyseCHKSUM(const char *Cmd) {
, calcSumCrumbXor(data, dlen, mask) , calcSumCrumbXor(data, dlen, mask)
, calcBSDchecksum8(data, dlen, mask) , calcBSDchecksum8(data, dlen, mask)
, calcBSDchecksum4(data, dlen, mask) , calcBSDchecksum4(data, dlen, mask)
, calcXORchecksum(data, dlen, mask)
); );
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -921,19 +938,14 @@ static int CmdAnalyseDemodBuffer(const char *Cmd) {
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
const char *s = arg_get_str(ctx, 1)->sval[0]; const char *s = arg_get_str(ctx, 1)->sval[0];
CLIParserFree(ctx);
if (s == NULL) {
PrintAndLogEx(FAILED, "Must provide a binary string");
return PM3_EINVARG;
}
int len = MIN(strlen(s), MAX_DEMOD_BUF_LEN); int len = MIN(strlen(s), MAX_DEMOD_BUF_LEN);
// add 1 for null terminator. // add 1 for null terminator.
uint8_t *data = calloc(len + 1, sizeof(uint8_t)); uint8_t *data = calloc(len + 1, sizeof(uint8_t));
if (data == NULL) if (data == NULL) {
CLIParserFree(ctx);
return PM3_EMALLOC; return PM3_EMALLOC;
}
for (int i = 0; i <= strlen(s); i++) { for (int i = 0; i <= strlen(s); i++) {
char c = s[i]; char c = s[i];
@ -944,6 +956,9 @@ static int CmdAnalyseDemodBuffer(const char *Cmd) {
PrintAndLogEx(NORMAL, "%c" NOLF, c); PrintAndLogEx(NORMAL, "%c" NOLF, c);
} }
CLIParserFree(ctx);
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
DemodBufferLen = len; DemodBufferLen = len;
free(data); free(data);

View file

@ -769,22 +769,22 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) {
int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) { int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) {
//ask raw demod GraphBuffer first //ask raw demod GraphBuffer first
uint8_t BitStream[MAX_DEMOD_BUF_LEN]; uint8_t bs[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(BitStream); size_t size = getFromGraphBuf(bs);
if (size == 0) { if (size == 0) {
PrintAndLogEx(DEBUG, "DEBUG: no data in graphbuf"); PrintAndLogEx(DEBUG, "DEBUG: no data in graphbuf");
return PM3_ESOFT; return PM3_ESOFT;
} }
int startIdx = 0; int startIdx = 0;
//invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
int errCnt = askdemod_ext(BitStream, &size, &clk, &invert, maxErr, 0, 0, &startIdx); int errCnt = askdemod_ext(bs, &size, &clk, &invert, maxErr, 0, 0, &startIdx);
if (errCnt < 0 || errCnt > maxErr) { if (errCnt < 0 || errCnt > maxErr) {
PrintAndLogEx(DEBUG, "DEBUG: no data or error found %d, clock: %d", errCnt, clk); PrintAndLogEx(DEBUG, "DEBUG: no data or error found %d, clock: %d", errCnt, clk);
return PM3_ESOFT; return PM3_ESOFT;
} }
//attempt to Biphase decode BitStream //attempt to Biphase decode BitStream
errCnt = BiphaseRawDecode(BitStream, &size, &offset, invert); errCnt = BiphaseRawDecode(bs, &size, &offset, invert);
if (errCnt < 0) { if (errCnt < 0) {
if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: Error BiphaseRawDecode: %d", errCnt); if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: Error BiphaseRawDecode: %d", errCnt);
return PM3_ESOFT; return PM3_ESOFT;
@ -795,7 +795,7 @@ int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) {
} }
//success set DemodBuffer and return //success set DemodBuffer and return
setDemodBuff(BitStream, size, 0); setDemodBuff(bs, size, 0);
setClockGrid(clk, startIdx + clk * offset / 2); setClockGrid(clk, startIdx + clk * offset / 2);
if (g_debugMode || verbose) { if (g_debugMode || verbose) {
PrintAndLogEx(DEBUG, "Biphase Decoded using offset %d | clock %d | #errors %d | start index %d\ndata\n", offset, clk, errCnt, (startIdx + clk * offset / 2)); PrintAndLogEx(DEBUG, "Biphase Decoded using offset %d | clock %d | #errors %d | start index %d\ndata\n", offset, clk, errCnt, (startIdx + clk * offset / 2));
@ -1576,7 +1576,7 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose) {
uint32_t n = end - start; uint32_t n = end - start;
if (n <= 0 || n > pm3_capabilities.bigbuf_size - 1) if (n == 0 || n > pm3_capabilities.bigbuf_size - 1)
n = pm3_capabilities.bigbuf_size - 1; n = pm3_capabilities.bigbuf_size - 1;
if (verbose) if (verbose)

View file

@ -26,7 +26,7 @@
#include "mifare/ndef.h" // NDEFRecordsDecodeAndPrint #include "mifare/ndef.h" // NDEFRecordsDecodeAndPrint
#include "aidsearch.h" #include "aidsearch.h"
#define MAX_14B_TIMEOUT (uint32_t)40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
#define TIMEOUT 2000 #define TIMEOUT 2000
#define APDU_TIMEOUT 2000 #define APDU_TIMEOUT 2000
@ -202,7 +202,6 @@ static bool wait_cmd_14b(bool verbose, bool is_select) {
(crc) ? _GREEN_("ok") : _RED_("fail") (crc) ? _GREEN_("ok") : _RED_("fail")
); );
} else if (len == 0) { } else if (len == 0) {
if (verbose)
PrintAndLogEx(INFO, "no response from tag"); PrintAndLogEx(INFO, "no response from tag");
} else { } else {
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len));
@ -300,7 +299,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
arg_lit0(NULL, "sr", "activate field, use SRx ST select"), arg_lit0(NULL, "sr", "activate field, use SRx ST select"),
arg_lit0(NULL, "cts", "activate field, use ASK C-ticket select"), arg_lit0(NULL, "cts", "activate field, use ASK C-ticket select"),
arg_lit0("c", "crc", "calculate and append CRC"), arg_lit0("c", "crc", "calculate and append CRC"),
arg_lit0("r", "noresponse", "do not read response from card"), arg_lit0(NULL, "noresponse", "do not read response from card"),
arg_int0("t", "timeout", "<dec>", "timeout in ms"), arg_int0("t", "timeout", "<dec>", "timeout in ms"),
arg_lit0("v", "verbose", "verbose"), arg_lit0("v", "verbose", "verbose"),
arg_strx0("d", "data", "<hex>", "data, bytes to send"), arg_strx0("d", "data", "<hex>", "data, bytes to send"),
@ -347,13 +346,12 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
uint32_t time_wait = 0; uint32_t time_wait = 0;
if (user_timeout > 0) { if (user_timeout > 0) {
#define MAX_14B_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
flags |= ISO14B_SET_TIMEOUT; flags |= ISO14B_SET_TIMEOUT;
if (user_timeout > MAX_14B_TIMEOUT) { if (user_timeout > MAX_14B_TIMEOUT) {
user_timeout = MAX_14B_TIMEOUT; user_timeout = MAX_14B_TIMEOUT;
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
} }
time_wait = 13560000 / 1000 / (8 * 16) * user_timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) time_wait = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
if (verbose) if (verbose)
PrintAndLogEx(INFO, "using timeout %u", user_timeout); PrintAndLogEx(INFO, "using timeout %u", user_timeout);
} }
@ -408,8 +406,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
if (card == NULL) if (card == NULL)
return false; return false;
int status = 0; int status;
PacketResponseNG resp; PacketResponseNG resp;
clearCommandBuffer(); clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0); SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
@ -1544,13 +1541,13 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
uint32_t time_wait = 0; uint32_t time_wait = 0;
if (user_timeout > 0) { if (user_timeout > 0) {
#define MAX_14B_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
flags |= ISO14B_SET_TIMEOUT; flags |= ISO14B_SET_TIMEOUT;
if (user_timeout > MAX_14B_TIMEOUT) { if (user_timeout > MAX_14B_TIMEOUT) {
user_timeout = MAX_14B_TIMEOUT; user_timeout = MAX_14B_TIMEOUT;
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
} }
time_wait = 13560000 / 1000 / (8 * 16) * user_timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) time_wait = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
} }
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes

View file

@ -459,6 +459,10 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
// uid[8] tag uid // uid[8] tag uid
// returns description of the best match // returns description of the best match
static const char *getTagInfo_15(uint8_t *uid) { static const char *getTagInfo_15(uint8_t *uid) {
if (uid == NULL) {
return "";
}
uint64_t myuid, mask; uint64_t myuid, mask;
int i = 0, best = -1; int i = 0, best = -1;
memcpy(&myuid, uid, sizeof(uint64_t)); memcpy(&myuid, uid, sizeof(uint64_t));

View file

@ -191,12 +191,10 @@ static int emrtd_exchange_commands_noout(const char *cmd, bool activate_field, b
static char emrtd_calculate_check_digit(char *data) { static char emrtd_calculate_check_digit(char *data) {
int mrz_weight[] = {7, 3, 1}; int mrz_weight[] = {7, 3, 1};
int cd = 0; int value, cd = 0;
int value = 0;
char d;
for (int i = 0; i < strlen(data); i++) { for (int i = 0; i < strlen(data); i++) {
d = data[i]; char d = data[i];
if ('A' <= d && d <= 'Z') { if ('A' <= d && d <= 'Z') {
value = d - 55; value = d - 55;
} else if ('a' <= d && d <= 'z') { } else if ('a' <= d && d <= 'z') {
@ -652,19 +650,16 @@ static bool emrtd_lds_get_data_by_tag(uint8_t *datain, size_t datainlen, uint8_t
offset += emrtd_get_asn1_field_length(datain, datainlen, offset); offset += emrtd_get_asn1_field_length(datain, datainlen, offset);
} }
int e_idlen = 0;
int e_datalen = 0;
int e_fieldlen = 0;
while (offset < datainlen) { while (offset < datainlen) {
PrintAndLogEx(DEBUG, "emrtd_lds_get_data_by_tag, offset: %i, data: %X", offset, *(datain + offset)); PrintAndLogEx(DEBUG, "emrtd_lds_get_data_by_tag, offset: %i, data: %X", offset, *(datain + offset));
// Determine element ID length to set as offset on asn1datalength // Determine element ID length to set as offset on asn1datalength
e_idlen = emrtd_lds_determine_tag_length(*(datain + offset)); int e_idlen = emrtd_lds_determine_tag_length(*(datain + offset));
// Get the length of the element // Get the length of the element
e_datalen = emrtd_get_asn1_data_length(datain + offset, datainlen - offset, e_idlen); int e_datalen = emrtd_get_asn1_data_length(datain + offset, datainlen - offset, e_idlen);
// Get the length of the element's length // Get the length of the element's length
e_fieldlen = emrtd_get_asn1_field_length(datain + offset, datainlen - offset, e_idlen); int e_fieldlen = emrtd_get_asn1_field_length(datain + offset, datainlen - offset, e_idlen);
PrintAndLogEx(DEBUG, "emrtd_lds_get_data_by_tag, e_idlen: %02X, e_datalen: %02X, e_fieldlen: %02X", e_idlen, e_datalen, e_fieldlen); PrintAndLogEx(DEBUG, "emrtd_lds_get_data_by_tag, e_idlen: %02X, e_datalen: %02X, e_fieldlen: %02X", e_idlen, e_datalen, e_fieldlen);
@ -718,8 +713,8 @@ static int emrtd_dump_ef_dg2(uint8_t *file_contents, size_t file_length, const c
// Note: Doing file_length - 6 to account for the longest data we're checking. // Note: Doing file_length - 6 to account for the longest data we're checking.
// Checks first byte before the rest to reduce overhead // Checks first byte before the rest to reduce overhead
for (offset = 0; offset < file_length - 6; offset++) { for (offset = 0; offset < file_length - 6; offset++) {
if ((file_contents[offset] == 0xFF && memcmp(jpeg_header, file_contents + offset, 4) != 0) || if ((file_contents[offset] == 0xFF && memcmp(jpeg_header, file_contents + offset, 4) == 0) ||
(file_contents[offset] == 0x00 && memcmp(jpeg2k_header, file_contents + offset, 6) != 0)) { (file_contents[offset] == 0x00 && memcmp(jpeg2k_header, file_contents + offset, 6) == 0)) {
datalen = file_length - offset; datalen = file_length - offset;
break; break;
} }
@ -828,7 +823,8 @@ static bool emrtd_dump_file(uint8_t *ks_enc, uint8_t *ks_mac, uint8_t *ssc, cons
char *filepath = calloc(strlen(path) + 100, sizeof(char)); char *filepath = calloc(strlen(path) + 100, sizeof(char));
if (filepath == NULL) if (filepath == NULL)
return PM3_EMALLOC; return false;
strcpy(filepath, path); strcpy(filepath, path);
strncat(filepath, PATHSEP, 2); strncat(filepath, PATHSEP, 2);
strcat(filepath, name); strcat(filepath, name);
@ -1649,8 +1645,6 @@ static int emrtd_parse_ef_sod_hashes(uint8_t *data, size_t datalen, uint8_t *has
size_t emrtdsiglen = 0; size_t emrtdsiglen = 0;
size_t hashlistlen = 0; size_t hashlistlen = 0;
size_t e_datalen = 0;
size_t e_fieldlen = 0;
size_t offset = 0; size_t offset = 0;
if (emrtd_ef_sod_extract_signatures(data, datalen, emrtdsig, &emrtdsiglen) != PM3_SUCCESS) { if (emrtd_ef_sod_extract_signatures(data, datalen, emrtdsig, &emrtdsiglen) != PM3_SUCCESS) {
@ -1670,10 +1664,10 @@ static int emrtd_parse_ef_sod_hashes(uint8_t *data, size_t datalen, uint8_t *has
while (offset < hashlistlen) { while (offset < hashlistlen) {
// Get the length of the element // Get the length of the element
e_datalen = emrtd_get_asn1_data_length(hashlist + offset, hashlistlen - offset, 1); int e_datalen = emrtd_get_asn1_data_length(hashlist + offset, hashlistlen - offset, 1);
// Get the length of the element's length // Get the length of the element's length
e_fieldlen = emrtd_get_asn1_field_length(hashlist + offset, hashlistlen - offset, 1); int e_fieldlen = emrtd_get_asn1_field_length(hashlist + offset, hashlistlen - offset, 1);
switch (hashlist[offset]) { switch (hashlist[offset]) {
case 0x30: case 0x30:
@ -1703,11 +1697,10 @@ static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_s
PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("%s"), hashalg_table[hash_algo].name); PrintAndLogEx(SUCCESS, "Hash algorithm: " _YELLOW_("%s"), hashalg_table[hash_algo].name);
uint8_t all_zeroes[64] = { 0x00 }; uint8_t all_zeroes[64] = { 0x00 };
bool calc_all_zero, sod_all_zero, hash_matches;
for (int i = 1; i <= 16; i++) { for (int i = 1; i <= 16; i++) {
calc_all_zero = (memcmp(dg_hashes_calc + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0); bool calc_all_zero = (memcmp(dg_hashes_calc + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0);
sod_all_zero = (memcmp(dg_hashes_sod + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0); bool sod_all_zero = (memcmp(dg_hashes_sod + (i * 64), all_zeroes, hashalg_table[hash_algo].hashlen) == 0);
hash_matches = (memcmp(dg_hashes_sod + (i * 64), dg_hashes_calc + (i * 64), hashalg_table[hash_algo].hashlen) == 0); bool hash_matches = (memcmp(dg_hashes_sod + (i * 64), dg_hashes_calc + (i * 64), hashalg_table[hash_algo].hashlen) == 0);
// Ignore files we don't haven't read and lack hashes to // Ignore files we don't haven't read and lack hashes to
if (calc_all_zero == true && sod_all_zero == true) { if (calc_all_zero == true && sod_all_zero == true) {
continue; continue;

View file

@ -68,7 +68,7 @@ bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t *
iclass_prekey_t *prekey = calloc(ICLASS_KEYS_MAX, sizeof(iclass_prekey_t)); iclass_prekey_t *prekey = calloc(ICLASS_KEYS_MAX, sizeof(iclass_prekey_t));
if (prekey == false) { if (prekey == false) {
return PM3_EMALLOC; return false;
} }
uint8_t ccnr[12]; uint8_t ccnr[12];
@ -1075,10 +1075,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "Block 9 decoder"); PrintAndLogEx(INFO, "Block 9 decoder");
uint8_t pinsize = 0;
if (use_sc) { if (use_sc) {
pinsize = GetPinSize(decrypted + (8 * 6)); uint8_t pinsize = GetPinSize(decrypted + (8 * 6));
if (pinsize > 0) { if (pinsize > 0) {
uint64_t pin = bytes_to_num(decrypted + (8 * 9), 5); uint64_t pin = bytes_to_num(decrypted + (8 * 9), 5);
@ -2076,7 +2074,7 @@ static int CmdHFiClass_loclass(const char *Cmd) {
" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>\n" " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>\n"
" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>\n" " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>\n"
" ... totalling N*24 bytes", " ... totalling N*24 bytes",
"hf iclass loclass -f iclass-dump.bin\n" "hf iclass loclass -f iclass_dump.bin\n"
"hf iclass loclass --test"); "hf iclass loclass --test");
void *argtable[] = { void *argtable[] = {

View file

@ -17,7 +17,6 @@
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "mifare/mifarehost.h" #include "mifare/mifarehost.h"
#include "mifare/mifaredefault.h"
#include "parity.h" // oddparity #include "parity.h" // oddparity
#include "ui.h" #include "ui.h"
#include "crc16.h" #include "crc16.h"
@ -1335,7 +1334,7 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8
} }
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen) { bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount) {
static struct Crypto1State *traceCrypto1; static struct Crypto1State *traceCrypto1;
*mfDataLen = 0; *mfDataLen = 0;
@ -1383,12 +1382,12 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes
} }
// check default keys // check default keys
if (!traceCrypto1) { if (!traceCrypto1 && dicKeys != NULL && dicKeysCount > 0) {
for (int i = 0; i < ARRAYLEN(g_mifare_default_keys); i++) { for (int i = 0; i < dicKeysCount; i++) {
if (NestedCheckKey(g_mifare_default_keys[i], &AuthData, cmd, cmdsize, parity)) { if (NestedCheckKey(dicKeys[i], &AuthData, cmd, cmdsize, parity)) {
PrintAndLogEx(NORMAL, " | | * |%61s " _GREEN_("%012" PRIX64) "| |", "key", g_mifare_default_keys[i]); PrintAndLogEx(NORMAL, " | | * |%60s " _GREEN_("%012" PRIX64) "| |", "key", dicKeys[i]);
mfLastKey = g_mifare_default_keys[i]; mfLastKey = dicKeys[i];
traceCrypto1 = lfsr_recovery64(AuthData.ks2, AuthData.ks3); traceCrypto1 = lfsr_recovery64(AuthData.ks2, AuthData.ks3);
break; break;
}; };

View file

@ -51,7 +51,7 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8
void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
void annotateCryptoRF(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateCryptoRF(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen); bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount);
bool NTParityChk(TAuthData *ad, uint32_t ntx); bool NTParityChk(TAuthData *ad, uint32_t ntx);
bool NestedCheckKey(uint64_t key, TAuthData *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity); bool NestedCheckKey(uint64_t key, TAuthData *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity);
bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t *parity_enc); bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t *parity_enc);

View file

@ -576,6 +576,9 @@ static int GetHFMF14AUID(uint8_t *uid, int *uidlen) {
} }
static char *GenerateFilename(const char *prefix, const char *suffix) { static char *GenerateFilename(const char *prefix, const char *suffix) {
if (! IfPm3Iso14443a()) {
return NULL;
}
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int uidlen = 0; int uidlen = 0;
char *fptr = calloc(sizeof(char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid) * 2 + 1, sizeof(uint8_t)); char *fptr = calloc(sizeof(char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid) * 2 + 1, sizeof(uint8_t));
@ -1972,8 +1975,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
uint64_t foundkey = 0; uint64_t foundkey = 0;
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename);
if (tests == 0) if ((tests == 0) && IfPm3Iso14443a()) {
DropField(); DropField();
}
if (isOK) { if (isOK) {
switch (isOK) { switch (isOK) {
@ -3542,8 +3546,6 @@ static int CmdHF14AMfSim(const char *Cmd) {
} }
showSectorTable(k_sector, k_sectorsCount); showSectorTable(k_sector, k_sectorsCount);
} }
k_sectorsCount = MIFARE_4K_MAXSECTOR;
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -575,7 +575,7 @@ static void init_nonce_memory(void) {
nonces[i].num = 0; nonces[i].num = 0;
nonces[i].Sum = 0; nonces[i].Sum = 0;
nonces[i].first = NULL; nonces[i].first = NULL;
for (uint16_t j = 0; j < NUM_SUMS; j++) { for (uint8_t j = 0; j < NUM_SUMS; j++) {
nonces[i].sum_a8_guess[j].sum_a8_idx = j; nonces[i].sum_a8_guess[j].sum_a8_idx = j;
nonces[i].sum_a8_guess[j].prob = 0.0; nonces[i].sum_a8_guess[j].prob = 0.0;
} }
@ -679,7 +679,7 @@ static float sum_probability(uint16_t i_K, uint16_t n, uint16_t k) {
double p_T_is_k_when_S_is_K = p_hypergeometric(i_K, n, k); double p_T_is_k_when_S_is_K = p_hypergeometric(i_K, n, k);
double p_S_is_K = p_K[i_K]; double p_S_is_K = p_K[i_K];
double p_T_is_k = 0; double p_T_is_k = 0;
for (uint16_t i = 0; i < NUM_SUMS; i++) { for (uint8_t i = 0; i < NUM_SUMS; i++) {
p_T_is_k += p_K[i] * p_hypergeometric(i, n, k); p_T_is_k += p_K[i] * p_hypergeometric(i, n, k);
} }
return (p_T_is_k_when_S_is_K * p_S_is_K / p_T_is_k); return (p_T_is_k_when_S_is_K * p_S_is_K / p_T_is_k);
@ -1044,7 +1044,7 @@ static void estimate_sum_a8(void) {
if (first_byte_num == 256) { if (first_byte_num == 256) {
for (uint16_t i = 0; i < 256; i++) { for (uint16_t i = 0; i < 256; i++) {
if (nonces[i].sum_a8_guess_dirty) { if (nonces[i].sum_a8_guess_dirty) {
for (uint16_t j = 0; j < NUM_SUMS; j++) { for (uint8_t j = 0; j < NUM_SUMS; j++) {
uint16_t sum_a8_idx = nonces[i].sum_a8_guess[j].sum_a8_idx; uint16_t sum_a8_idx = nonces[i].sum_a8_guess[j].sum_a8_idx;
nonces[i].sum_a8_guess[j].prob = sum_probability(sum_a8_idx, nonces[i].num, nonces[i].Sum); nonces[i].sum_a8_guess[j].prob = sum_probability(sum_a8_idx, nonces[i].num, nonces[i].Sum);
} }
@ -1102,7 +1102,7 @@ static int read_nonce_file(char *filename) {
sprintf(progress_string, "Target Block=%d, Keytype=%c", trgBlockNo, trgKeyType == 0 ? 'A' : 'B'); sprintf(progress_string, "Target Block=%d, Keytype=%c", trgBlockNo, trgKeyType == 0 ? 'A' : 'B');
hardnested_print_progress(num_acquired_nonces, progress_string, (float)(1LL << 47), 0); hardnested_print_progress(num_acquired_nonces, progress_string, (float)(1LL << 47), 0);
for (uint16_t i = 0; i < NUM_SUMS; i++) { for (uint8_t i = 0; i < NUM_SUMS; i++) {
if (first_byte_Sum == sums[i]) { if (first_byte_Sum == sums[i]) {
first_byte_Sum = i; first_byte_Sum = i;
break; break;
@ -1152,14 +1152,20 @@ __attribute__((force_align_arg_pointer))
return NULL; return NULL;
} }
for (uint16_t i = first_byte; i <= last_byte; i++) { for (uint16_t i = first_byte; i <= last_byte; i++) {
if (nonces[i].BitFlips[bitflip] == 0 && nonces[i].BitFlips[bitflip ^ 0x100] == 0 if (nonces[i].BitFlips[bitflip] == 0 && nonces[i].BitFlips[bitflip ^ 0x100] == 0
&& nonces[i].first != NULL && nonces[i ^ (bitflip & 0xff)].first != NULL) { && nonces[i].first != NULL && nonces[i ^ (bitflip & 0xff)].first != NULL) {
uint8_t parity1 = (nonces[i].first->par_enc) >> 3; // parity of first byte uint8_t parity1 = (nonces[i].first->par_enc) >> 3; // parity of first byte
uint8_t parity2 = (nonces[i ^ (bitflip & 0xff)].first->par_enc) >> 3; // parity of nonce with bits flipped uint8_t parity2 = (nonces[i ^ (bitflip & 0xff)].first->par_enc) >> 3; // parity of nonce with bits flipped
if ((parity1 == parity2 && !(bitflip & 0x100)) // bitflip if ((parity1 == parity2 && !(bitflip & 0x100)) // bitflip
|| (parity1 != parity2 && (bitflip & 0x100))) { // not bitflip || (parity1 != parity2 && (bitflip & 0x100))) { // not bitflip
nonces[i].BitFlips[bitflip] = 1; nonces[i].BitFlips[bitflip] = 1;
for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
if (bitflip_bitarrays[odd_even][bitflip] != NULL) { if (bitflip_bitarrays[odd_even][bitflip] != NULL) {
uint32_t old_count = nonces[i].num_states_bitarray[odd_even]; uint32_t old_count = nonces[i].num_states_bitarray[odd_even];
nonces[i].num_states_bitarray[odd_even] = count_bitarray_AND(nonces[i].states_bitarray[odd_even], bitflip_bitarrays[odd_even][bitflip]); nonces[i].num_states_bitarray[odd_even] = count_bitarray_AND(nonces[i].states_bitarray[odd_even], bitflip_bitarrays[odd_even][bitflip]);
@ -1344,7 +1350,7 @@ static void simulate_acquire_nonces(void) {
if (first_byte_num == 256) { if (first_byte_num == 256) {
if (hardnested_stage == CHECK_1ST_BYTES) { if (hardnested_stage == CHECK_1ST_BYTES) {
for (uint16_t i = 0; i < NUM_SUMS; i++) { for (uint8_t i = 0; i < NUM_SUMS; i++) {
if (first_byte_Sum == sums[i]) { if (first_byte_Sum == sums[i]) {
first_byte_Sum = i; first_byte_Sum = i;
break; break;
@ -1471,7 +1477,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
if (first_byte_num == 256) { if (first_byte_num == 256) {
if (hardnested_stage == CHECK_1ST_BYTES) { if (hardnested_stage == CHECK_1ST_BYTES) {
for (uint16_t i = 0; i < NUM_SUMS; i++) { for (uint8_t i = 0; i < NUM_SUMS; i++) {
if (first_byte_Sum == sums[i]) { if (first_byte_Sum == sums[i]) {
first_byte_Sum = i; first_byte_Sum = i;
break; break;
@ -1662,7 +1668,7 @@ static inline bool bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_e
if (!possible) { if (!possible) {
#ifdef DEBUG_KEY_ELIMINATION #ifdef DEBUG_KEY_ELIMINATION
if (!quiet && known_target_key != -1 && state == test_state[odd_even]) { if (!quiet && known_target_key != -1 && state == test_state[odd_even]) {
PrintAndLogEx(NORMAL, "Initial state lists: %s test state eliminated by bitflip property.\n", odd_even == EVEN_STATE ? "even" : "odd"); PrintAndLogEx(INFO, "Initial state lists: %s test state eliminated by bitflip property.", odd_even == EVEN_STATE ? "even" : "odd");
sprintf(failstr, "Initial %s Byte Bitflip property", odd_even == EVEN_STATE ? "even" : "odd"); sprintf(failstr, "Initial %s Byte Bitflip property", odd_even == EVEN_STATE ? "even" : "odd");
} }
#endif #endif
@ -1785,14 +1791,14 @@ static void add_matching_states(statelist_t *cands, uint8_t part_sum_a0, uint8_t
static statelist_t *add_more_candidates(void) { static statelist_t *add_more_candidates(void) {
statelist_t *new_candidates; statelist_t *new_candidates;
if (candidates == NULL) { if (candidates == NULL) {
candidates = (statelist_t *)malloc(sizeof(statelist_t)); candidates = (statelist_t *)calloc(sizeof(statelist_t), sizeof(uint8_t));
new_candidates = candidates; new_candidates = candidates;
} else { } else {
new_candidates = candidates; new_candidates = candidates;
while (new_candidates->next != NULL) { while (new_candidates->next != NULL) {
new_candidates = new_candidates->next; new_candidates = new_candidates->next;
} }
new_candidates = new_candidates->next = (statelist_t *)malloc(sizeof(statelist_t)); new_candidates = new_candidates->next = (statelist_t *)calloc(sizeof(statelist_t), sizeof(uint8_t));
} }
new_candidates->next = NULL; new_candidates->next = NULL;
new_candidates->len[ODD_STATE] = 0; new_candidates->len[ODD_STATE] = 0;
@ -1807,14 +1813,15 @@ static void add_bitflip_candidates(uint8_t byte) {
for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
uint32_t worstcase_size = nonces[byte].num_states_bitarray[odd_even] + 1; uint32_t worstcase_size = nonces[byte].num_states_bitarray[odd_even] + 1;
candidates1->states[odd_even] = (uint32_t *)malloc(sizeof(uint32_t) * worstcase_size); candidates1->states[odd_even] = (uint32_t *)calloc(worstcase_size, sizeof(uint32_t));
if (candidates1->states[odd_even] == NULL) { if (candidates1->states[odd_even] == NULL) {
PrintAndLogEx(ERR, "Out of memory error in add_bitflip_candidates().\n"); PrintAndLogEx(ERR, "Out of memory error in add_bitflip_candidates()");
exit(4); exit(4);
} }
bitarray_to_list(byte, nonces[byte].states_bitarray[odd_even], candidates1->states[odd_even], &(candidates1->len[odd_even]), odd_even); bitarray_to_list(byte, nonces[byte].states_bitarray[odd_even], candidates1->states[odd_even], &(candidates1->len[odd_even]), odd_even);
// slim down the allocated memory.
if (candidates1->len[odd_even] + 1 < worstcase_size) { if (candidates1->len[odd_even] + 1 < worstcase_size) {
candidates1->states[odd_even] = realloc(candidates1->states[odd_even], sizeof(uint32_t) * (candidates1->len[odd_even] + 1)); candidates1->states[odd_even] = realloc(candidates1->states[odd_even], sizeof(uint32_t) * (candidates1->len[odd_even] + 1));
} }
@ -2073,6 +2080,8 @@ static void free_candidates_memory(statelist_t *sl) {
return; return;
free_candidates_memory(sl->next); free_candidates_memory(sl->next);
sl->len[0] = 0;
sl->len[1] = 0;
free(sl); free(sl);
} }
@ -2170,6 +2179,9 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
get_SIMD_instruction_set(instr_set); get_SIMD_instruction_set(instr_set);
PrintAndLogEx(SUCCESS, "Using %s SIMD core.", instr_set); PrintAndLogEx(SUCCESS, "Using %s SIMD core.", instr_set);
memset(part_sum_count, 0, sizeof(part_sum_count));
real_sum_a8 = 0;
srand((unsigned) time(NULL)); srand((unsigned) time(NULL));
brute_force_per_second = brute_force_benchmark(); brute_force_per_second = brute_force_benchmark();
write_stats = false; write_stats = false;

View file

@ -992,7 +992,6 @@ uint32_t GetHF14AMfU_Type(void) {
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x15", 7) == 0) { tagtype = NTAG_I2C_2K_PLUS; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x15", 7) == 0) { tagtype = NTAG_I2C_2K_PLUS; break; }
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL; break; }
else if (version[2] == 0x04) { tagtype = NTAG; break; } else if (version[2] == 0x04) { tagtype = NTAG; break; }
else if (version[2] == 0x03) { tagtype = UL_EV1; } else if (version[2] == 0x03) { tagtype = UL_EV1; }
break; break;
@ -2064,7 +2063,16 @@ static int CmdHF14AMfURestore(const char *Cmd) {
bool verbose = arg_get_lit(ctx, 7); bool verbose = arg_get_lit(ctx, 7);
CLIParserFree(ctx); CLIParserFree(ctx);
bool has_key = false; bool has_key = false;
if (ak_len > 0) {
if (ak_len != 4 && ak_len != 16) {
PrintAndLogEx(ERR, "Wrong key length. expected 4 or 16, got %d", ak_len);
return PM3_EINVARG;
} else {
has_key = true;
}
}
uint8_t *dump = NULL; uint8_t *dump = NULL;
size_t bytes_read = 0; size_t bytes_read = 0;

View file

@ -183,8 +183,6 @@ static void dither_chan_inplace(int16_t *chan, uint16_t width, uint16_t height)
} }
if (Y < height - 1) { if (Y < height - 1) {
chan[X - 1 + (Y + 1) * width] = chan[X - 1 + (Y + 1) * width] + m[1] / 16 * err; chan[X - 1 + (Y + 1) * width] = chan[X - 1 + (Y + 1) * width] + m[1] / 16 * err;
}
if (Y < height - 1) {
chan[X + (Y + 1) * width] = chan[X + (Y + 1) * width] + m[2] / 16 * err; chan[X + (Y + 1) * width] = chan[X + (Y + 1) * width] + m[2] / 16 * err;
} }
if ((X < width - 1) && (Y < height - 1)) { if ((X < width - 1) && (Y < height - 1)) {
@ -250,8 +248,6 @@ static void dither_rgb_inplace(int16_t *chanR, int16_t *chanG, int16_t *chanB, u
chanR[XX - 1 + (Y + 1) * width] = (chanR[XX - 1 + (Y + 1) * width] + m[3] / 16 * errR); chanR[XX - 1 + (Y + 1) * width] = (chanR[XX - 1 + (Y + 1) * width] + m[3] / 16 * errR);
chanG[XX - 1 + (Y + 1) * width] = (chanG[XX - 1 + (Y + 1) * width] + m[3] / 16 * errG); chanG[XX - 1 + (Y + 1) * width] = (chanG[XX - 1 + (Y + 1) * width] + m[3] / 16 * errG);
chanB[XX - 1 + (Y + 1) * width] = (chanB[XX - 1 + (Y + 1) * width] + m[3] / 16 * errB); chanB[XX - 1 + (Y + 1) * width] = (chanB[XX - 1 + (Y + 1) * width] + m[3] / 16 * errB);
}
if (Y < height - 1) {
chanR[XX + (Y + 1) * width] = (chanR[XX + (Y + 1) * width] + m[2] / 16 * errR); chanR[XX + (Y + 1) * width] = (chanR[XX + (Y + 1) * width] + m[2] / 16 * errR);
chanG[XX + (Y + 1) * width] = (chanG[XX + (Y + 1) * width] + m[2] / 16 * errG); chanG[XX + (Y + 1) * width] = (chanG[XX + (Y + 1) * width] + m[2] / 16 * errG);
chanB[XX + (Y + 1) * width] = (chanB[XX + (Y + 1) * width] + m[2] / 16 * errB); chanB[XX + (Y + 1) * width] = (chanB[XX + (Y + 1) * width] + m[2] / 16 * errB);
@ -271,8 +267,6 @@ static void dither_rgb_inplace(int16_t *chanR, int16_t *chanG, int16_t *chanB, u
chanR[XX - 1 + (Y + 1) * width] = (chanR[XX - 1 + (Y + 1) * width] + m[1] / 16 * errR); chanR[XX - 1 + (Y + 1) * width] = (chanR[XX - 1 + (Y + 1) * width] + m[1] / 16 * errR);
chanG[XX - 1 + (Y + 1) * width] = (chanG[XX - 1 + (Y + 1) * width] + m[1] / 16 * errG); chanG[XX - 1 + (Y + 1) * width] = (chanG[XX - 1 + (Y + 1) * width] + m[1] / 16 * errG);
chanB[XX - 1 + (Y + 1) * width] = (chanB[XX - 1 + (Y + 1) * width] + m[1] / 16 * errB); chanB[XX - 1 + (Y + 1) * width] = (chanB[XX - 1 + (Y + 1) * width] + m[1] / 16 * errB);
}
if (Y < height - 1) {
chanR[XX + (Y + 1) * width] = (chanR[XX + (Y + 1) * width] + m[2] / 16 * errR); chanR[XX + (Y + 1) * width] = (chanR[XX + (Y + 1) * width] + m[2] / 16 * errR);
chanG[XX + (Y + 1) * width] = (chanG[XX + (Y + 1) * width] + m[2] / 16 * errG); chanG[XX + (Y + 1) * width] = (chanG[XX + (Y + 1) * width] + m[2] / 16 * errG);
chanB[XX + (Y + 1) * width] = (chanB[XX + (Y + 1) * width] + m[2] / 16 * errB); chanB[XX + (Y + 1) * width] = (chanB[XX + (Y + 1) * width] + m[2] / 16 * errB);
@ -1004,7 +998,7 @@ static int CmdHF14AWSLoadBmp(const char *Cmd) {
); );
char modeldesc[40]; char modeldesc[40];
snprintf(modeldesc, sizeof(modeldesc), "model number [0 - %u] of your tag", MEND - 1); snprintf(modeldesc, sizeof(modeldesc), "model number [0 - %d] of your tag", MEND - 1);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,

View file

@ -332,8 +332,8 @@ static int CmdDbg(const char *Cmd) {
bool lv0 = arg_get_lit(ctx, 1); bool lv0 = arg_get_lit(ctx, 1);
bool lv1 = arg_get_lit(ctx, 2); bool lv1 = arg_get_lit(ctx, 2);
bool lv2 = arg_get_lit(ctx, 3); bool lv2 = arg_get_lit(ctx, 3);
bool lv3 = arg_get_lit(ctx, 3); bool lv3 = arg_get_lit(ctx, 4);
bool lv4 = arg_get_lit(ctx, 4); bool lv4 = arg_get_lit(ctx, 5);
CLIParserFree(ctx); CLIParserFree(ctx);
if ((lv0 + lv1 + lv2 + lv3 + lv4) > 1) { if ((lv0 + lv1 + lv2 + lv3 + lv4) > 1) {

View file

@ -216,20 +216,6 @@ static int usage_lf_simpsk(void) {
PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer"); PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int usage_lf_find(void) {
PrintAndLogEx(NORMAL, "Usage: lf search [h] <0|1> [u]");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " <0|1> Use data from Graphbuffer, if not set, try reading data from tag.");
PrintAndLogEx(NORMAL, " u Search for Unknown tags, if not set, reads only known tags.");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search") " - try reading data from tag & search for known tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search 1") " - use data from GraphBuffer & search for known tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search u") " - try reading data from tag & search for known and unknown tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search 1 u") " - use data from GraphBuffer & search for known and unknown tags");
return PM3_SUCCESS;
}
static int CmdLFTune(const char *Cmd) { static int CmdLFTune(const char *Cmd) {
@ -1263,7 +1249,20 @@ int CmdLFpskSim(const char *Cmd) {
} }
int CmdLFSimBidir(const char *Cmd) { int CmdLFSimBidir(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf simbidir",
"Simulate LF tag with bidirectional data transmission between reader and tag",
"lf simbidir"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
// Set ADC to twice the carrier for a slight supersampling // Set ADC to twice the carrier for a slight supersampling
// HACK: not implemented in ARMSRC. // HACK: not implemented in ARMSRC.
PrintAndLogEx(INFO, "Not implemented yet."); PrintAndLogEx(INFO, "Not implemented yet.");
@ -1405,22 +1404,33 @@ out:
} }
int CmdLFfind(const char *Cmd) { int CmdLFfind(const char *Cmd) {
int retval = PM3_SUCCESS;
int ans = 0;
size_t minLength = 2000;
char cmdp = tolower(param_getchar(Cmd, 0));
char testRaw = param_getchar(Cmd, 1);
if (strlen(Cmd) > 3 || cmdp == 'h') return usage_lf_find(); CLIParserContext *ctx;
CLIParserInit(&ctx, "lf search",
"Read and search for valid known tag. For offline mode, you can `data load` first then search.",
"lf search -> try reading data from tag & search for known tag\n"
"lf search -1 -> use data from GraphBuffer & search for known tag\n"
"lf search -u -> try reading data from tag & search for known and unknown tag\n"
"lf search -1u -> use data from GraphBuffer & search for known and unknown tag\n"
);
if (cmdp == 'u') testRaw = 'u'; void *argtable[] = {
arg_param_begin,
arg_lit0("1", NULL, "Use data from Graphbuffer to search"),
arg_lit0("u", NULL, "Search for unknown tags, if not set, reads only known tags"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool use_gb = arg_get_lit(ctx, 1);
bool search_unk = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
bool isOnline = (session.pm3_present && (cmdp != '1')); bool is_online = (session.pm3_present && (use_gb == false));
if (is_online)
if (isOnline)
lf_read(false, 30000); lf_read(false, 30000);
if (GraphTraceLen < minLength) { size_t min_length = 2000;
if (GraphTraceLen < min_length) {
PrintAndLogEx(FAILED, "Data in Graphbuffer was too small."); PrintAndLogEx(FAILED, "Data in Graphbuffer was too small.");
return PM3_ESOFT; return PM3_ESOFT;
} }
@ -1434,7 +1444,7 @@ int CmdLFfind(const char *Cmd) {
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
// only run these tests if device is online // only run these tests if device is online
if (isOnline) { if (is_online) {
if (IfPm3Hitag()) { if (IfPm3Hitag()) {
if (readHitagUid()) { if (readHitagUid()) {
@ -1474,6 +1484,8 @@ int CmdLFfind(const char *Cmd) {
} }
} }
int retval = PM3_SUCCESS;
if (demodVisa2k(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") " found!"); goto out;} if (demodVisa2k(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") " found!"); goto out;}
if (demodDestron(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-A FECAVA Destron ID") " found!"); goto out;} // to do before HID if (demodDestron(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-A FECAVA Destron ID") " found!"); goto out;} // to do before HID
if (demodHID(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;} if (demodHID(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
@ -1502,10 +1514,10 @@ int CmdLFfind(const char *Cmd) {
PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!")); PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!"));
if (testRaw == 'u') { if (search_unk) {
//test unknown tag formats (raw mode) //test unknown tag formats (raw mode)
PrintAndLogEx(INFO, "\nChecking for unknown tags:\n"); PrintAndLogEx(INFO, "\nChecking for unknown tags:\n");
ans = AutoCorrelate(GraphBuffer, GraphBuffer, GraphTraceLen, 8000, false, false); int ans = AutoCorrelate(GraphBuffer, GraphBuffer, GraphTraceLen, 8000, false, false);
if (ans > 0) { if (ans > 0) {
PrintAndLogEx(INFO, "Possible auto correlation of %d repeating samples", ans); PrintAndLogEx(INFO, "Possible auto correlation of %d repeating samples", ans);
@ -1544,7 +1556,7 @@ int CmdLFfind(const char *Cmd) {
out: out:
// identify chipset // identify chipset
if (CheckChipType(isOnline) == false) { if (CheckChipType(is_online) == false) {
PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed")); PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed"));
retval = false; retval = false;
} }
@ -1586,12 +1598,12 @@ static command_t CommandTable[] = {
{"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"},
{"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"},
{"read", CmdLFRead, IfPm3Lf, "Read LF tag"}, {"read", CmdLFRead, IfPm3Lf, "Read LF tag"},
{"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, {"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag"},
{"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"},
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate " _YELLOW_("LF ASK tag") " from demodbuffer or input"}, {"simask", CmdLFaskSim, IfPm3Lf, "Simulate " _YELLOW_("LF ASK tag") " from demodbuffer or input"},
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate " _YELLOW_("LF FSK tag") " from demodbuffer or input"}, {"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate " _YELLOW_("LF FSK tag") " from demodbuffer or input"},
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate " _YELLOW_("LF PSK tag") " from demodbuffer or input"}, {"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate " _YELLOW_("LF PSK tag") " from demodbuffer or input"},
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate " _YELLOW_("LF NRZ tag") " from demodbuffer or input"}, // {"simnrz", CmdLFnrzSim, IfPm3Lf, "Simulate " _YELLOW_("LF NRZ tag") " from demodbuffer or input"},
{"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},

View file

@ -125,10 +125,9 @@ static int doPreambleSearch(size_t *startIdx) {
// skip first two 0 bits as they might have been missed in the demod // skip first two 0 bits as they might have been missed in the demod
uint8_t preamble[EM_PREAMBLE_LEN] = {0, 0, 0, 0, 1, 0, 1, 0}; uint8_t preamble[EM_PREAMBLE_LEN] = {0, 0, 0, 0, 1, 0, 1, 0};
uint8_t errpreamble[EM_PREAMBLE_LEN] = {0, 0, 0, 0, 0, 0, 0, 1};
if (!preambleSearchEx(DemodBuffer, preamble, EM_PREAMBLE_LEN, &size, startIdx, true)) { if (!preambleSearchEx(DemodBuffer, preamble, EM_PREAMBLE_LEN, &size, startIdx, true)) {
uint8_t errpreamble[EM_PREAMBLE_LEN] = {0, 0, 0, 0, 0, 0, 0, 1};
if (!preambleSearchEx(DemodBuffer, errpreamble, EM_PREAMBLE_LEN, &size, startIdx, true)) { if (!preambleSearchEx(DemodBuffer, errpreamble, EM_PREAMBLE_LEN, &size, startIdx, true)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM4305 preamble not found :: %zu", *startIdx); PrintAndLogEx(DEBUG, "DEBUG: Error - EM4305 preamble not found :: %zu", *startIdx);
return PM3_ESOFT; return PM3_ESOFT;
@ -258,10 +257,10 @@ static int em4x05_setdemod_buffer(uint32_t *word, size_t idx) {
// should cover 90% of known used configs // should cover 90% of known used configs
// the rest will need to be manually demoded for now... // the rest will need to be manually demoded for now...
static int em4x05_demod_resp(uint32_t *word, bool onlyPreamble) { static int em4x05_demod_resp(uint32_t *word, bool onlyPreamble) {
size_t idx = 0;
*word = 0; *word = 0;
int res;
size_t idx = 0;
bool found_err = false; bool found_err = false;
int res = PM3_SUCCESS;
do { do {
if (detectASK_MAN()) { if (detectASK_MAN()) {
res = doPreambleSearch(&idx); res = doPreambleSearch(&idx);
@ -773,15 +772,38 @@ int CmdEM4x05Write(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_int0("a", "addr", "<dec>", "memory address to write to. (0-13)"), arg_int0("a", "addr", "<dec>", "memory address to write to. (0-13)"),
arg_str1("d", "data", "<hex>", "data to write, 4 bytes hex"), arg_str1("d", "data", "<hex>", "data to write (4 hex bytes)"),
arg_str0("p", "pwd", "<hex>", "optional - password, 4 bytes hex"), arg_str0("p", "pwd", "<hex>", "password (4 hex bytes)"),
arg_lit0(NULL, "po", "protect operation"), arg_lit0(NULL, "po", "protect operation"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t addr = (uint8_t)arg_get_int_def(ctx, 1, 50); uint8_t addr = (uint8_t)arg_get_int_def(ctx, 1, 50);
uint32_t data = arg_get_u32(ctx, 2); uint32_t data = 0;
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 3, 0xFFFFFFFFFFFFFFFF); int res = arg_get_u32_hexstr_def(ctx, 2, 0, &data);
if (res == 2) {
CLIParserFree(ctx);
PrintAndLogEx(WARNING, "Data must be 4 hex bytes");
return PM3_EINVARG;
} else if (res == 0) {
CLIParserFree(ctx);
PrintAndLogEx(WARNING, "Data must be 4 hex bytes");
return PM3_EINVARG;
}
bool use_pwd = false;
uint32_t pwd = 0;
res = arg_get_u32_hexstr_def_nlen(ctx, 3, 0, &pwd, 4, true);
if (res == 2) {
CLIParserFree(ctx);
PrintAndLogEx(WARNING, "Password must be 4 hex bytes");
return PM3_EINVARG;
} else if (res == 3) {
use_pwd = false;
} else if (res == 1) {
use_pwd = true;
}
bool protect_operation = arg_get_lit(ctx, 4); bool protect_operation = arg_get_lit(ctx, 4);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -790,22 +812,19 @@ int CmdEM4x05Write(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
bool use_pwd = false; if (use_pwd) {
uint32_t pwd = (inputpwd != 0xFFFFFFFFFFFFFFFF) ? (inputpwd & 0xFFFFFFFF) : 0;
if (pwd == 0xFFFFFFFF) {
if (protect_operation)
PrintAndLogEx(INFO, "Writing protection words data %08X", data);
else
PrintAndLogEx(INFO, "Writing address %d data %08X", addr, data);
} else {
use_pwd = true;
if (protect_operation) if (protect_operation)
PrintAndLogEx(INFO, "Writing protection words data %08X using password %08X", data, pwd); PrintAndLogEx(INFO, "Writing protection words data %08X using password %08X", data, pwd);
else else
PrintAndLogEx(INFO, "Writing address %d data %08X using password %08X", addr, data, pwd); PrintAndLogEx(INFO, "Writing address %d data %08X using password %08X", addr, data, pwd);
} else {
if (protect_operation)
PrintAndLogEx(INFO, "Writing protection words data %08X", data);
else
PrintAndLogEx(INFO, "Writing address %d data %08X", addr, data);
} }
int res = PM3_SUCCESS; res = PM3_SUCCESS;
// set Protect Words // set Protect Words
if (protect_operation) { if (protect_operation) {
res = em4x05_protect(pwd, use_pwd, data); res = em4x05_protect(pwd, use_pwd, data);
@ -1674,6 +1693,10 @@ int CmdEM4x05Unlock(const char *Cmd) {
// write // write
res = unlock_write_protect(use_pwd, pwd, write_value, verbose); res = unlock_write_protect(use_pwd, pwd, write_value, verbose);
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "failed unlock write");
return PM3_ESOFT;
}
// read after trigger // read after trigger
res = em4x05_read_word_ext(14, pwd, use_pwd, &word14); res = em4x05_read_word_ext(14, pwd, use_pwd, &word14);
@ -1833,7 +1856,7 @@ int CmdEM4x05Unlock(const char *Cmd) {
PrintAndLogEx(INFO, "Old protection word => " _YELLOW_("%08X"), search_value); PrintAndLogEx(INFO, "Old protection word => " _YELLOW_("%08X"), search_value);
char bitstring[9] = {0}; char bitstring[9] = {0};
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
bitstring[i] = bitflips & (0xF << ((7 - i) * 4)) ? 'x' : '.'; bitstring[i] = (bitflips & (0xF << ((7 - i) * 4))) ? 'x' : '.';
} }
// compute number of bits flipped // compute number of bits flipped
@ -1935,23 +1958,8 @@ uint32_t static em4x05_Sniff_GetBlock(char *bits, bool fwd) {
int CmdEM4x05Sniff(const char *Cmd) { int CmdEM4x05Sniff(const char *Cmd) {
bool sampleData = true; bool pwd = false, fwd = false;
bool haveData = false; bool haveData, sampleData = true;
size_t idx = 0;
char cmdText [100];
char dataText [100];
char blkAddr[4];
char bits[80];
int bitidx;
int ZeroWidth; // 32-42 "1" is 32
int CycleWidth;
size_t pulseSamples;
size_t pktOffset;
int i;
bool eop = false;
uint32_t tmpValue;
bool pwd = false;
bool fwd = false;
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "lf em 4x05_sniff", CLIParserInit(&ctx, "lf em 4x05_sniff",
@ -1968,12 +1976,21 @@ int CmdEM4x05Sniff(const char *Cmd) {
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
sampleData = (arg_get_lit(ctx, 1) == false);
sampleData = !arg_get_lit(ctx, 1);
fwd = arg_get_lit(ctx, 2); fwd = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
char cmdText[100];
char dataText[100];
char blkAddr[4];
char bits[80];
int i, bitidx;
int ZeroWidth; // 32-42 "1" is 32
int CycleWidth;
size_t idx = 0, pulseSamples, pktOffset;
uint32_t tmpValue;
bool eop = false;
// setup and sample data from Proxmark // setup and sample data from Proxmark
// if not directed to existing sample/graphbuffer // if not directed to existing sample/graphbuffer
if (sampleData) { if (sampleData) {
@ -2056,7 +2073,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
haveData = true; haveData = true;
sprintf(cmdText, "Write"); sprintf(cmdText, "Write");
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
sprintf(blkAddr, "%d", tmpValue); sprintf(blkAddr, "%u", tmpValue);
if (tmpValue == 2) { if (tmpValue == 2) {
pwd = true; pwd = true;
} }
@ -2070,7 +2087,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
pwd = false; pwd = false;
sprintf(cmdText, "Read"); sprintf(cmdText, "Read");
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
sprintf(blkAddr, "%d", tmpValue); sprintf(blkAddr, "%u", tmpValue);
sprintf(dataText, " "); sprintf(dataText, " ");
} }

View file

@ -653,16 +653,10 @@ static int CmdFdxBReader(const char *Cmd) {
return res; return res;
} }
int16_t tmp_div = config.divisor;
if (tmp_div != LF_DIVISOR_134) {
config.divisor = LF_DIVISOR_134;
config.verbose = false; config.verbose = false;
res = lf_config(&config);
if (res != PM3_SUCCESS) { int16_t old_div = config.divisor;
PrintAndLogEx(ERR, "failed to change LF configuration"); int16_t curr_div = config.divisor;
return res;
}
}
if (cm) { if (cm) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit"); PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
@ -670,13 +664,32 @@ static int CmdFdxBReader(const char *Cmd) {
int ret = PM3_SUCCESS; int ret = PM3_SUCCESS;
do { do {
if (curr_div == LF_DIVISOR_125) {
config.divisor = LF_DIVISOR_134;
res = lf_config(&config);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to change to 134 KHz LF configuration");
return res;
}
} else {
config.divisor = LF_DIVISOR_125;
res = lf_config(&config);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to change to 125 KHz LF configuration");
return res;
}
}
curr_div = config.divisor;
lf_read(false, 10000); lf_read(false, 10000);
ret = demodFDXB(!cm); // be verbose only if not in continuous mode ret = demodFDXB(!cm); // be verbose only if not in continuous mode
//PrintAndLogEx(INPLACE, "");
} while (cm && !kbd_enter_pressed()); } while (cm && !kbd_enter_pressed());
if (tmp_div != LF_DIVISOR_134) {
config.divisor = tmp_div; if (old_div != curr_div) {
config.divisor = old_div;
res = lf_config(&config); res = lf_config(&config);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to restore LF configuration"); PrintAndLogEx(ERR, "failed to restore LF configuration");

View file

@ -277,7 +277,6 @@ static int CmdGallagherSim(const char *Cmd) {
return resp.status; return resp.status;
return PM3_SUCCESS; return PM3_SUCCESS;
return PM3_SUCCESS;
} }
static command_t CommandTable[] = { static command_t CommandTable[] = {

View file

@ -262,26 +262,7 @@ static int usage_t55xx_wakup(void) {
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx wakeup p 11223344") " - send wakeup password"); PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx wakeup p 11223344") " - send wakeup password");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int usage_t55xx_chk(void) {
PrintAndLogEx(NORMAL, "This command uses a dictionary attack");
PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command");
PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!");
PrintAndLogEx(NORMAL, "Try to reading block 7 before\n");
PrintAndLogEx(NORMAL, "Usage: lf t55xx chk [h] [m] [r <mode>] [f <*.dic>] [e <em4100 id>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help");
PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n");
print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL, T55XX_DLMODE_ALL);
PrintAndLogEx(NORMAL, " f <*.dic> - loads a default keys dictionary file <*.dic>");
PrintAndLogEx(NORMAL, " e <EM4100> - will try the calculated password from some cloners based on EM4100 ID");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx chk m"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx chk f t55xx_default_pwds"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx chk e aa11223344"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_t55xx_dangerraw(void) { static int usage_t55xx_dangerraw(void) {
PrintAndLogEx(NORMAL, "This command allows to emit arbitrary raw commands on T5577 and cut the field after arbitrary duration."); PrintAndLogEx(NORMAL, "This command allows to emit arbitrary raw commands on T5577 and cut the field after arbitrary duration.");
PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may lock definitively the tag in an unusable state!"); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may lock definitively the tag in an unusable state!");
@ -1523,8 +1504,20 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
return false; return false;
} }
int special(const char *Cmd) { int CmdT55xxSpecial(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf t55xx special",
"Show block changes with 64 different offsets, data taken from Demod buffer.",
"lf t55xx special\n"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
uint8_t bits[32] = {0x00}; uint8_t bits[32] = {0x00};
@ -2974,68 +2967,86 @@ static bool IsCancelled(void) {
// load a default pwd file. // load a default pwd file.
static int CmdT55xxChkPwds(const char *Cmd) { static int CmdT55xxChkPwds(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf t55xx chk",
"This command uses a dictionary attack.\n"
"For some cloners, try '--em' for known pwdgen algo.\n"
"Try to reading Page 0 block 7 before.\n"
_RED_("WARNING:") _CYAN_(" this may brick non-password protected chips!"),
"lf t55xx chk -m -> use dictionary from flash memory (RDV4)\n"
"lf t55xx chk -f my_dictionary_pwds -> loads a default keys dictionary file\n"
"lf t55xx chk --em aa11223344 -> try known pwdgen algo from some cloners based on EM4100 ID"
);
// Calculate size of argtable accordingly:
// 1 (help) + 3 (three user specified params) + ( 5 or 6 T55XX_DLMODE)
// 4 + (T55XX_DLMODE_xxx 5)
// 4 + (T55XX_DLMODE_ALL 6) == 10
void *argtable[10] = {
arg_param_begin,
arg_lit0("m", "fm", "use dictionary from flash memory (RDV4)"),
arg_str0("f", "file", "<filename>", "file name"),
arg_str0(NULL, "em", "<hex>", "EM4100 ID (5 hex bytes)"),
};
uint8_t idx = 4;
arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_ALL, T55XX_DLMODE_ALL);
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool from_flash = arg_get_lit(ctx, 1);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
bool found = false; CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, sizeof(filename), &fnlen);
uint8_t timeout = 0;
uint8_t *keyBlock = NULL;
bool from_flash = false;
bool try_all_dl_modes = false;
uint8_t downlink_mode = 0;
bool use_pwd_file = false;
int dl_mode; // to try each downlink mode for each password
uint8_t cmdp = 0;
bool errors = false;
bool useCardPassword = false;
uint32_t cardPassword = 0x00;
uint64_t cardID = 0x00;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_chk();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode >= 4) {
try_all_dl_modes = true;
downlink_mode = 0;
}
cmdp += 2;
break;
case 'm':
from_flash = true;
cmdp++;
break;
case 'f':
if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) {
PrintAndLogEx(ERR, "Error, no filename after 'f' was found");
errors = true;
}
use_pwd_file = true;
cmdp += 2;
break;
case 'e':
// White cloner password based on EM4100 ID // White cloner password based on EM4100 ID
useCardPassword = true; bool use_calc_password = false;
cardID = param_get64ex(Cmd, cmdp + 1, 0, 16); uint32_t card_password = 0x00;
uint32_t card32Bit = cardID & 0xFFFFFFFF; uint64_t cardid = 0;
cardPassword = lf_t55xx_white_pwdgen(card32Bit); int res = arg_get_u64_hexstr_def_nlen(ctx, 3, 0x00, &cardid, 5, true);
cmdp += 2; if (res == 1) {
break; use_calc_password = true;
default: uint32_t calc = cardid & 0xFFFFFFFF;
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); card_password = lf_t55xx_white_pwdgen(calc);
errors = true;
break;
} }
if (res == 2) {
CLIParserFree(ctx);
PrintAndLogEx(WARNING, "EM4100 ID must be 5 hex bytes");
return PM3_EINVARG;
}
if (res == 0) {
CLIParserFree(ctx);
return PM3_EINVARG;
} }
if (errors) return usage_t55xx_chk(); bool r0 = arg_get_lit(ctx, 4);
bool r1 = arg_get_lit(ctx, 5);
bool r2 = arg_get_lit(ctx, 6);
bool r3 = arg_get_lit(ctx, 7);
bool ra = arg_get_lit(ctx, 8);
CLIParserFree(ctx);
if ((r0 + r1 + r2 + r3 + ra) > 1) {
PrintAndLogEx(FAILED, "Error multiple downlink encoding");
return PM3_EINVARG;
}
uint8_t downlink_mode = config.downlink_mode;
if (r0)
downlink_mode = refFixedBit;
else if (r1)
downlink_mode = refLongLeading;
else if (r2)
downlink_mode = refLeading0;
else if (r3)
downlink_mode = ref1of4;
bool use_pwd_file = false;
if (strlen(filename) == 0) { if (strlen(filename) == 0) {
snprintf(filename, sizeof(filename), "t55xx_default_pwds"); snprintf(filename, sizeof(filename), "t55xx_default_pwds");
use_pwd_file = true; use_pwd_file = true;
} }
PrintAndLogEx(INFO, "press " _GREEN_("'enter'") " to cancel the command");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
/* /*
// block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000
@ -3047,6 +3058,8 @@ static int CmdT55xxChkPwds(const char *Cmd) {
} }
*/ */
bool found = false;
uint64_t t1 = msclock(); uint64_t t1 = msclock();
uint8_t flags = downlink_mode << 3; uint8_t flags = downlink_mode << 3;
@ -3055,6 +3068,7 @@ static int CmdT55xxChkPwds(const char *Cmd) {
SendCommandNG(CMD_LF_T55XX_CHK_PWDS, &flags, sizeof(flags)); SendCommandNG(CMD_LF_T55XX_CHK_PWDS, &flags, sizeof(flags));
PacketResponseNG resp; PacketResponseNG resp;
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_LF_T55XX_CHK_PWDS, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_LF_T55XX_CHK_PWDS, &resp, 2000)) {
timeout++; timeout++;
PrintAndLogEx(NORMAL, "." NOLF); PrintAndLogEx(NORMAL, "." NOLF);
@ -3090,55 +3104,59 @@ static int CmdT55xxChkPwds(const char *Cmd) {
goto out; goto out;
} }
// try calculated password // to try each downlink mode for each password
if (useCardPassword) { int dl_mode;
PrintAndLogEx(INFO, "testing %08"PRIX32" generated ", cardPassword); // try calculated password
if (use_calc_password) {
PrintAndLogEx(INFO, "testing %08"PRIX32" generated ", card_password);
for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) {
if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, cardPassword, dl_mode)) { if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, card_password, dl_mode)) {
continue; continue;
} }
found = t55xxTryDetectModulationEx(dl_mode, T55XX_PrintConfig, 0, cardPassword); found = t55xxTryDetectModulationEx(dl_mode, T55XX_PrintConfig, 0, card_password);
if (found) { if (found) {
PrintAndLogEx(SUCCESS, "found valid password : [ " _GREEN_("%08"PRIX32) " ]", cardPassword); PrintAndLogEx(SUCCESS, "found valid password : [ " _GREEN_("%08"PRIX32) " ]", card_password);
dl_mode = 4; // Exit other downlink mode checks break;
} }
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes if (ra == false)
dl_mode = 4; break;
} }
} }
if ((found == false) && use_pwd_file) { if ((found == false) && use_pwd_file) {
uint32_t keycount = 0; uint32_t keycount = 0;
uint8_t *keyblock = NULL;
int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount); res = loadFileDICTIONARY_safe(filename, (void **) &keyblock, 4, &keycount);
if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { if (res != PM3_SUCCESS || keycount == 0 || keyblock == NULL) {
PrintAndLogEx(WARNING, "no keys found in file"); PrintAndLogEx(WARNING, "no keys found in file");
if (keyBlock != NULL) if (keyblock != NULL)
free(keyBlock); free(keyblock);
return PM3_ESOFT; return PM3_ESOFT;
} }
PrintAndLogEx(INFO, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(INFO, "press " _GREEN_("'enter'") " to cancel the command");
for (uint32_t c = 0; c < keycount; ++c) { for (uint32_t c = 0; c < keycount && found == false; ++c) {
if (!session.pm3_present) { if (!session.pm3_present) {
PrintAndLogEx(WARNING, "device offline\n"); PrintAndLogEx(WARNING, "device offline\n");
free(keyBlock); free(keyblock);
return PM3_ENODATA; return PM3_ENODATA;
} }
if (IsCancelled()) { if (IsCancelled()) {
free(keyBlock); free(keyblock);
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }
uint32_t curr_password = bytes_to_num(keyBlock + 4 * c, 4); uint32_t curr_password = bytes_to_num(keyblock + 4 * c, 4);
PrintAndLogEx(INFO, "testing %08"PRIX32, curr_password); PrintAndLogEx(INFO, "testing %08"PRIX32, curr_password);
for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) { for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++) {
@ -3150,20 +3168,19 @@ static int CmdT55xxChkPwds(const char *Cmd) {
found = t55xxTryDetectModulationEx(dl_mode, T55XX_PrintConfig, 0, curr_password); found = t55xxTryDetectModulationEx(dl_mode, T55XX_PrintConfig, 0, curr_password);
if (found) { if (found) {
PrintAndLogEx(SUCCESS, "found valid password: [ " _GREEN_("%08"PRIX32) " ]", curr_password); PrintAndLogEx(SUCCESS, "found valid password: [ " _GREEN_("%08"PRIX32) " ]", curr_password);
dl_mode = 4; // Exit other downlink mode checks break;
c = keycount; // Exit loop
} }
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes if (ra == false) // Exit loop if not trying all downlink modes
dl_mode = 4; break;
} }
} }
free(keyblock);
} }
if (found == false) if (found == false)
PrintAndLogEx(WARNING, "check pwd failed"); PrintAndLogEx(WARNING, "failed to find password");
free(keyBlock);
out: out:
t1 = msclock() - t1; t1 = msclock() - t1;
@ -3310,7 +3327,7 @@ static int CmdT55xxRecoverPW(const char *Cmd) {
// 2 + (5 or 6) // 2 + (5 or 6)
void *argtable[8] = { void *argtable[8] = {
arg_param_begin, arg_param_begin,
arg_str1("p", "pwd", "<hex>", "password (4 hex bytes)"), arg_str0("p", "pwd", "<hex>", "password (4 hex bytes)"),
}; };
uint8_t idx = 2; uint8_t idx = 2;
arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_ALL, T55XX_DLMODE_ALL); arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_ALL, T55XX_DLMODE_ALL);
@ -3564,6 +3581,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) {
int res = arg_get_u32_hexstr_def(ctx, 2, 0, &password); int res = arg_get_u32_hexstr_def(ctx, 2, 0, &password);
if (res == 2) { if (res == 2) {
PrintAndLogEx(INFO, "Password should be 4 hex bytes"); PrintAndLogEx(INFO, "Password should be 4 hex bytes");
CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
} else if (res == 1) { } else if (res == 1) {
usepwd = true; usepwd = true;
@ -3758,7 +3776,7 @@ static int CmdT55xxProtect(const char *Cmd) {
void *argtable[4 + 5] = { void *argtable[4 + 5] = {
arg_param_begin, arg_param_begin,
arg_lit0("o", "override", "override safety check"), arg_lit0("o", "override", "override safety check"),
arg_str1("p", "pwd", "<hex>", "password (4 hex bytes)"), arg_str0("p", "pwd", "<hex>", "password (4 hex bytes)"),
arg_str1("n", "new", "<hex>", "new password (4 hex bytes)"), arg_str1("n", "new", "<hex>", "new password (4 hex bytes)"),
}; };
uint8_t idx = 4; uint8_t idx = 4;
@ -3883,24 +3901,39 @@ static int CmdT55xxSniff(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
bool use_graphbuf = arg_get_lit(ctx, 1); bool use_graphbuf = arg_get_lit(ctx, 1);
uint8_t tolerance = arg_get_int_def(ctx, 2, 5); uint8_t tolerance = arg_get_int_def(ctx, 2, 5);
uint8_t width1 = arg_get_int(ctx, 3); int opt_width1 = arg_get_int_def(ctx, 3, -1);
uint8_t width0 = arg_get_int(ctx, 4); int opt_width0 = arg_get_int_def(ctx, 4, -1);
CLIParserFree(ctx); CLIParserFree(ctx);
if (width0 && width1 == 0) { if (opt_width0 > 0 && opt_width1 == -1) {
PrintAndLogEx(ERR, _RED_("Missing sample width for ONE")); PrintAndLogEx(ERR, _RED_("Missing sample width for ONE"));
return PM3_EINVARG; return PM3_EINVARG;
} }
if (width1 && width0 == 0) { if (opt_width1 > 0 && opt_width0 == -1) {
PrintAndLogEx(ERR, _RED_("Missing sample width for ZERO")); PrintAndLogEx(ERR, _RED_("Missing sample width for ZERO"));
return PM3_EINVARG; return PM3_EINVARG;
} }
if ((width0 == 0) || (width1 == 0)) { if (opt_width0 == 0) {
PrintAndLogEx(ERR, "Must call with --one and --zero params"); PrintAndLogEx(ERR, "Must call with --zero larger than 0");
return PM3_EINVARG; return PM3_EINVARG;
} }
if ((opt_width0 == 0) || (opt_width1 == 0)) {
PrintAndLogEx(ERR, "Must call with --one larger than 0");
return PM3_EINVARG;
}
uint8_t width1 = 0;
uint8_t width0 = 0;
if (opt_width0 > -1)
width0 = (uint8_t)opt_width0 & 0xFF;
if (opt_width1 > -1)
width1 = (uint8_t)opt_width1 & 0xFF;
/* /*
Notes: Notes:
@ -4196,7 +4229,7 @@ static command_t CommandTable[] = {
{"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"}, {"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"},
{"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "Try to recover from bad password write from a cloner"}, {"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "Try to recover from bad password write from a cloner"},
{"sniff", CmdT55xxSniff, AlwaysAvailable, "Attempt to recover T55xx commands from sample buffer"}, {"sniff", CmdT55xxSniff, AlwaysAvailable, "Attempt to recover T55xx commands from sample buffer"},
{"special", special, IfPm3Lf, "Show block changes with 64 different offsets"}, {"special", CmdT55xxSpecial, IfPm3Lf, "Show block changes with 64 different offsets"},
{"wipe", CmdT55xxWipe, IfPm3Lf, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"}, {"wipe", CmdT55xxWipe, IfPm3Lf, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -196,7 +196,7 @@ bool testKnownConfigBlock(uint32_t block0);
bool tryDetectP1(bool getData); bool tryDetectP1(bool getData);
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5); bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
int special(const char *Cmd); int CmdT55xxSpecial(const char *Cmd);
bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode); bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode);
uint8_t t55xx_try_one_password(uint32_t password, uint8_t downlink_mode, bool try_all_dl_modes); uint8_t t55xx_try_one_password(uint32_t password, uint8_t downlink_mode, bool try_all_dl_modes);

View file

@ -15,6 +15,8 @@
#include "protocols.h" #include "protocols.h"
#include "parity.h" // oddparity #include "parity.h" // oddparity
#include "cmdhflist.h" // annotations #include "cmdhflist.h" // annotations
#include "commonutil.h" // ARRAYLEN
#include "mifare/mifaredefault.h" // mifare default key array
#include "comms.h" // for sending cmds to device. GetFromBigBuf #include "comms.h" // for sending cmds to device. GetFromBigBuf
#include "fileutils.h" // for saveFile #include "fileutils.h" // for saveFile
#include "cmdlfhitag.h" // annotate hitag #include "cmdlfhitag.h" // annotate hitag
@ -131,7 +133,8 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac
return ret; return ret;
} }
static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes, uint32_t *prev_eot, bool use_us) { static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes, uint32_t *prev_eot, bool use_us,
const uint64_t *mfDicKeys, uint32_t mfDicKeysCount) {
// sanity check // sanity check
if (is_last_record(tracepos, traceLen)) { if (is_last_record(tracepos, traceLen)) {
PrintAndLogEx(DEBUG, "last record triggered. t-pos: %u t-len %u", tracepos, traceLen); PrintAndLogEx(DEBUG, "last record triggered. t-pos: %u t-len %u", tracepos, traceLen);
@ -428,7 +431,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
} }
if (protocol == PROTO_MIFARE) { if (protocol == PROTO_MIFARE) {
if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen)) { if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) {
memset(explanation, 0x00, sizeof(explanation)); memset(explanation, 0x00, sizeof(explanation));
if (hdr->isResponse == false) { if (hdr->isResponse == false) {
annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen); annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen);
@ -579,12 +582,11 @@ static int CmdTraceSave(const char *Cmd) {
if (g_traceLen == 0) { if (g_traceLen == 0) {
download_trace(); download_trace();
}
if (g_traceLen == 0) { if (g_traceLen == 0) {
PrintAndLogEx(WARNING, "trace is empty, nothing to save"); PrintAndLogEx(WARNING, "trace is empty, nothing to save");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
}
saveFile(filename, ".trace", g_trace, g_traceLen); saveFile(filename, ".trace", g_trace, g_traceLen);
return PM3_SUCCESS; return PM3_SUCCESS;
@ -612,6 +614,7 @@ int CmdTraceList(const char *Cmd) {
"trace list -t hitags -> interpret as " _YELLOW_("HitagS") " communications\n" "trace list -t hitags -> interpret as " _YELLOW_("HitagS") " communications\n"
"trace list -t lto -> interpret as " _YELLOW_("LTO-CM") " communications\n" "trace list -t lto -> interpret as " _YELLOW_("LTO-CM") " communications\n"
"trace list -t cryptorf -> interpret as " _YELLOW_("CryptoRF") " communitcations\n" "trace list -t cryptorf -> interpret as " _YELLOW_("CryptoRF") " communitcations\n"
"trace list -t mf --dict <mfc_default_keys> -> use dictionary keys file\n"
"trace list -t 14a -f -> show frame delay times\n" "trace list -t 14a -f -> show frame delay times\n"
"trace list -t 14a -1 -> use trace buffer " "trace list -t 14a -1 -> use trace buffer "
); );
@ -626,6 +629,7 @@ int CmdTraceList(const char *Cmd) {
arg_lit0("x", NULL, "show hexdump to convert to pcap(ng)\n" arg_lit0("x", NULL, "show hexdump to convert to pcap(ng)\n"
" or to import into Wireshark using encapsulation type \"ISO 14443\""), " or to import into Wireshark using encapsulation type \"ISO 14443\""),
arg_strx0("t", "type", NULL, "protocol to annotate the trace"), arg_strx0("t", "type", NULL, "protocol to annotate the trace"),
arg_strx0(NULL, "dict", "<file>", "use dictionary keys file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -642,6 +646,13 @@ int CmdTraceList(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)type, sizeof(type), &tlen); CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)type, sizeof(type), &tlen);
str_lower(type); str_lower(type);
int diclen = 0;
char dictionary[FILE_PATH_SIZE + 2] = {0};
if (CLIParamStrToBuf(arg_get_str(ctx, 8), (uint8_t *)dictionary, FILE_PATH_SIZE, &diclen)) {
PrintAndLogEx(FAILED, "Dictionary file name too long or invalid.");
diclen = 0;
}
CLIParserFree(ctx); CLIParserFree(ctx);
clearCommandBuffer(); clearCommandBuffer();
@ -742,6 +753,34 @@ int CmdTraceList(const char *Cmd) {
} }
const uint64_t *dicKeys = NULL;
uint32_t dicKeysCount = 0;
bool dictionaryLoad = false;
if (protocol == PROTO_MIFARE) {
if (diclen > 0) {
uint8_t *keyBlock = NULL;
int res = loadFileDICTIONARY_safe(dictionary, (void **) &keyBlock, 6, &dicKeysCount);
if (res != PM3_SUCCESS || dicKeysCount == 0 || keyBlock == NULL) {
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)");
} else {
dicKeys = calloc(dicKeysCount, sizeof(uint64_t));
for (int i = 0; i < dicKeysCount; i++) {
uint64_t key = bytes_to_num(keyBlock + i * 6, 6);
memcpy((uint8_t *) &dicKeys[i], &key, sizeof(uint64_t));
}
dictionaryLoad = true;
}
if (keyBlock != NULL) {
free(keyBlock);
}
}
if (dicKeys == NULL) {
dicKeys = g_mifare_default_keys;
dicKeysCount = ARRAYLEN(g_mifare_default_keys);
}
}
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
if (use_relative) { if (use_relative) {
PrintAndLogEx(NORMAL, " Gap | Duration | Src | Data (! denotes parity error, ' denotes short bytes) | CRC | Annotation"); PrintAndLogEx(NORMAL, " Gap | Duration | Src | Data (! denotes parity error, ' denotes short bytes) | CRC | Annotation");
@ -761,11 +800,14 @@ int CmdTraceList(const char *Cmd) {
} }
while (tracepos < g_traceLen) { while (tracepos < g_traceLen) {
tracepos = printTraceLine(tracepos, g_traceLen, g_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us); tracepos = printTraceLine(tracepos, g_traceLen, g_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us, dicKeys, dicKeysCount);
if (kbd_enter_pressed()) if (kbd_enter_pressed())
break; break;
} }
if (dictionaryLoad)
free((void *) dicKeys);
} }
if (show_hex) if (show_hex)

View file

@ -25,24 +25,6 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static void print_wiegand_code(wiegand_message_t *packed) {
const char *s = "Encoded wiegand: ";
if (packed->Top != 0) {
PrintAndLogEx(SUCCESS, "%s" _GREEN_("%X%08X%08X"),
s,
(uint32_t)packed->Top,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
} else {
PrintAndLogEx(SUCCESS, "%s" _YELLOW_("%X%08X"),
s,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
}
}
int CmdWiegandList(const char *Cmd) { int CmdWiegandList(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
@ -67,7 +49,8 @@ int CmdWiegandEncode(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "wiegand encode", CLIParserInit(&ctx, "wiegand encode",
"Encode wiegand formatted number to raw hex", "Encode wiegand formatted number to raw hex",
"wiegand encode -w H10301 --fc 101 --cn 1337" "wiegand encode --fc 101 --cn 1337 -> show all formats\n"
"wiegand encode -w H10301 --fc 101 --cn 1337 -> H10301 format "
); );
void *argtable[] = { void *argtable[] = {
@ -76,7 +59,7 @@ int CmdWiegandEncode(const char *Cmd) {
arg_u64_1(NULL, "cn", "<dec>", "card number"), arg_u64_1(NULL, "cn", "<dec>", "card number"),
arg_u64_0(NULL, "issue", "<dec>", "issue level"), arg_u64_0(NULL, "issue", "<dec>", "issue level"),
arg_u64_0(NULL, "oem", "<dec>", "OEM code"), arg_u64_0(NULL, "oem", "<dec>", "OEM code"),
arg_str1("w", "wiegand", "<format>", "see `wiegand list` for available formats"), arg_str0("w", "wiegand", "<format>", "see `wiegand list` for available formats"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -94,21 +77,27 @@ int CmdWiegandEncode(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)format, sizeof(format), &len); CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)format, sizeof(format), &len);
CLIParserFree(ctx); CLIParserFree(ctx);
int idx = HIDFindCardFormat(format); int idx = -1;
if (len) {
idx = HIDFindCardFormat(format);
if (idx == -1) { if (idx == -1) {
PrintAndLogEx(WARNING, "Unknown format: %s", format); PrintAndLogEx(WARNING, "Unknown format: %s", format);
return PM3_EINVARG; return PM3_EINVARG;
} }
}
if (idx != -1) {
wiegand_message_t packed; wiegand_message_t packed;
memset(&packed, 0, sizeof(wiegand_message_t)); memset(&packed, 0, sizeof(wiegand_message_t));
if (HIDPack(idx, &data, &packed) == false) { if (HIDPack(idx, &data, &packed) == false) {
PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
return PM3_ESOFT; return PM3_ESOFT;
} }
print_wiegand_code(&packed); print_wiegand_code(&packed);
} else {
// try all formats and print only the ones that work.
HIDPackTryAll(&data);
}
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -149,7 +149,7 @@ void convertGraphFromBitstreamEx(int hi, int low) {
} }
// Get or auto-detect ask clock rate // Get or auto-detect ask clock rate
int GetAskClock(const char *str, bool printAns) { int GetAskClock(const char *str, bool verbose) {
if (getSignalProperties()->isnoise) if (getSignalProperties()->isnoise)
return -1; return -1;
@ -183,7 +183,7 @@ int GetAskClock(const char *str, bool printAns) {
setClockGrid(clock1, idx); setClockGrid(clock1, idx);
} }
// Only print this message if we're not looping something // Only print this message if we're not looping something
if (printAns || g_debugMode) if (verbose || g_debugMode)
PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d, Best Starting Position: %d", clock1, idx); PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d, Best Starting Position: %d", clock1, idx);
free(bits); free(bits);

View file

@ -91,12 +91,12 @@ uint8_t pi[35] = {
* @param n bitnumber * @param n bitnumber
* @return * @return
*/ */
#define getSixBitByte(c, n) ((uint8_t)(((c) >> (42 - 6 * (n))) & 0x3F)) //#define getSixBitByte(c, n) ((uint8_t)(((c) >> (42 - 6 * (n))) & 0x3F))
/*
static inline uint8_t getSixBitByte(uint64_t c, int n) { static inline uint8_t getSixBitByte(uint64_t c, int n) {
return (c >> (42 - 6 * n)) & 0x3F; return (c >> (42 - 6 * n)) & 0x3F;
} }
*/
/** /**
* @brief Puts back a six-bit 'byte' into a uint64_t. * @brief Puts back a six-bit 'byte' into a uint64_t.
* @param c buffer * @param c buffer

View file

@ -106,7 +106,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
pathlen += strlen(subdir); pathlen += strlen(subdir);
char *tmp = realloc(path, pathlen * sizeof(char)); char *tmp = realloc(path, pathlen * sizeof(char));
if (tmp == NULL) { if (tmp == NULL) {
free(path); //free(path);
return PM3_EMALLOC; return PM3_EMALLOC;
} }
path = tmp; path = tmp;
@ -146,7 +146,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
pathlen += strlen(filename); pathlen += strlen(filename);
char *tmp = realloc(path, pathlen * sizeof(char)); char *tmp = realloc(path, pathlen * sizeof(char));
if (tmp == NULL) { if (tmp == NULL) {
free(path); //free(path);
return PM3_EMALLOC; return PM3_EMALLOC;
} }
path = tmp; path = tmp;
@ -474,7 +474,7 @@ static bool emojify_token(const char *token, uint8_t token_length, const char **
case EMO_ALTTEXT: { case EMO_ALTTEXT: {
int j = 0; int j = 0;
*emojified_token_length = 0; *emojified_token_length = 0;
while (EmojiAltTable[j].alias && EmojiAltTable[i].alttext) { while (EmojiAltTable[j].alias && EmojiAltTable[j].alttext) {
if ((strlen(EmojiAltTable[j].alias) == token_length) && (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) { if ((strlen(EmojiAltTable[j].alias) == token_length) && (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) {
*emojified_token = EmojiAltTable[j].alttext; *emojified_token = EmojiAltTable[j].alttext;
*emojified_token_length = strlen(EmojiAltTable[j].alttext); *emojified_token_length = strlen(EmojiAltTable[j].alttext);
@ -642,9 +642,12 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
prev_cols = cols; prev_cols = cols;
#endif #endif
int width = cols - 35; int width = cols - 35;
if (width < 1)
return;
#define PERCENTAGE(V, T) ((V * width) / T) #define PERCENTAGE(V, T) ((V * width) / T)
// x/8 fractional part of the percentage // x/8 fractional part of the percentage
#define PERCENTAGEFRAC(V, T) ((int)(((((float)V * width) / T) - ((V * width) / T)) * 8)) #define PERCENTAGEFRAC(V, T) ((uint8_t)(((((float)V * width) / T) - ((V * width) / T)) * 8))
const char *smoothtable[] = { const char *smoothtable[] = {
"\xe2\x80\x80", "\xe2\x80\x80",
@ -658,14 +661,15 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
"\xe2\x96\x88", "\xe2\x96\x88",
}; };
uint8_t mode = (session.emoji_mode == EMO_EMOJI); int mode = (session.emoji_mode == EMO_EMOJI);
const char *block[] = {"#", "\xe2\x96\x88"}; const char *block[] = {"#", "\xe2\x96\x88"};
// use a 3-byte space in emoji mode to ease computations // use a 3-byte space in emoji mode to ease computations
const char *space[] = {" ", "\xe2\x80\x80"}; const char *space[] = {" ", "\xe2\x80\x80"};
uint8_t unit = strlen(block[mode]);
size_t unit = strlen(block[mode]);
// +1 for \0 // +1 for \0
char *bar = calloc(unit * width + 1, sizeof(uint8_t)); char *bar = (char *)calloc(unit * width + 1, sizeof(uint8_t));
uint8_t value = PERCENTAGE(count, max); uint8_t value = PERCENTAGE(count, max);
@ -687,7 +691,7 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
} }
// color buffer // color buffer
size_t collen = strlen(bar) + 40; size_t collen = strlen(bar) + 40;
char *cbar = calloc(collen, sizeof(uint8_t)); char *cbar = (char *)calloc(collen, sizeof(uint8_t));
// Add colors // Add colors
if (session.supports_colors) { if (session.supports_colors) {
@ -695,23 +699,23 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
int p20 = unit * (width * 20 / 100); int p20 = unit * (width * 20 / 100);
snprintf(cbar, collen, _GREEN_("%.*s"), p60, bar); snprintf(cbar, collen, _GREEN_("%.*s"), p60, bar);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), p20, bar + p60); snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), p20, bar + p60);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), unit * width - p60 - p20, bar + p60 + p20); snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), (int)(unit * width - p60 - p20), bar + p60 + p20);
} else { } else {
snprintf(cbar, collen, "%s", bar); snprintf(cbar, collen, "%s", bar);
} }
size_t len = strlen(cbar) + 32; size_t olen = strlen(cbar) + 40;
char *buffer = calloc(len, sizeof(uint8_t)); char *out = (char *)calloc(olen, sizeof(uint8_t));
switch (style) { switch (style) {
case STYLE_BAR: { case STYLE_BAR: {
sprintf(buffer, "%s", cbar); sprintf(out, "%s", cbar);
printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, buffer); printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, out);
break; break;
} }
case STYLE_MIXED: { case STYLE_MIXED: {
sprintf(buffer, "%s [ %zu mV / %2u V / %2u Vmax ] ", cbar, count, (uint32_t)(count / 1000), (uint32_t)(max / 1000)); sprintf(out, "%s [ %zu mV / %2u V / %2u Vmax ]", cbar, count, (uint32_t)(count / 1000), (uint32_t)(max / 1000));
printf("\b%c[2K\r[" _YELLOW_("=")"] %s ", 27, buffer); printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, out);
break; break;
} }
case STYLE_VALUE: { case STYLE_VALUE: {
@ -719,9 +723,8 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
break; break;
} }
} }
fflush(stdout); fflush(stdout);
free(buffer); free(out);
free(bar); free(bar);
free(cbar); free(cbar);
} }

View file

@ -8,8 +8,10 @@
// HID card format packing/unpacking routines // HID card format packing/unpacking routines
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "wiegand_formats.h" #include "wiegand_formats.h"
#include <stdlib.h>
#include "commonutil.h" #include "commonutil.h"
static bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { static bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) {
memset(packed, 0, sizeof(wiegand_message_t)); memset(packed, 0, sizeof(wiegand_message_t));
@ -823,7 +825,7 @@ static const cardformat_t FormatTable[] = {
{"Optus34", Pack_Optus, Unpack_Optus, "Indala Optus 34-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"Optus34", Pack_Optus, Unpack_Optus, "Indala Optus 34-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au
{"Smartpass", Pack_Smartpass, Unpack_Smartpass, "Cardkey Smartpass 34-bit", {1, 1, 1, 0, 0}}, // from cardinfo.barkweb.com.au {"Smartpass", Pack_Smartpass, Unpack_Smartpass, "Cardkey Smartpass 34-bit", {1, 1, 1, 0, 0}}, // from cardinfo.barkweb.com.au
{"BQT", Pack_bqt, Unpack_bqt, "BQT 34-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"BQT", Pack_bqt, Unpack_bqt, "BQT 34-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au
{"C1k35s", Pack_C1k35s, Unpack_C1k35s, "HID Corporate 1000 35-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"C1k35s", Pack_C1k35s, Unpack_C1k35s, "HID Corporate 1000 35-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack
{"C15001", Pack_C15001, Unpack_C15001, "HID KeyScan 36-bit", {1, 1, 0, 1, 1}}, // from Proxmark forums {"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 {"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 {"Sie36", Pack_Sie36, Unpack_Sie36, "HID 36-bit Siemens", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au
@ -834,7 +836,7 @@ static const cardformat_t FormatTable[] = {
{"MDI37", Pack_MDI37, Unpack_MDI37, "PointGuard MDI 37-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"MDI37", Pack_MDI37, Unpack_MDI37, "PointGuard MDI 37-bit", {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, 1, 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 {"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 standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack
{NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array
}; };
@ -842,18 +844,59 @@ void HIDListFormats(void) {
if (FormatTable[0].Name == NULL) if (FormatTable[0].Name == NULL)
return; return;
PrintAndLogEx(NORMAL, "%-10s %s", "Name", "Description"); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "------------------------------------------------------------"); PrintAndLogEx(INFO, "%-10s %s", "Name", "Description");
PrintAndLogEx(INFO, "------------------------------------------------------------");
int i = 0; int i = 0;
while (FormatTable[i].Name) { while (FormatTable[i].Name) {
PrintAndLogEx(NORMAL, _YELLOW_("%-10s")" %-30s", FormatTable[i].Name, FormatTable[i].Descrp); PrintAndLogEx(INFO, _YELLOW_("%-10s")" %-30s", FormatTable[i].Name, FormatTable[i].Descrp);
++i; ++i;
} }
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return; return;
} }
void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed) {
char *s = calloc(128, sizeof(uint8_t));
sprintf(s, _YELLOW_("%-10s")" %-30s", fmt->Name, fmt->Descrp);
if (packed->Top != 0) {
PrintAndLogEx(SUCCESS, "%s --> " _GREEN_("%X%08X%08X"),
s,
(uint32_t)packed->Top,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
} else {
PrintAndLogEx(SUCCESS, "%s --> " _YELLOW_("%X%08X"),
s,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
}
free(s);
}
void print_wiegand_code(wiegand_message_t *packed) {
const char *s = "Encoded wiegand: ";
if (packed->Top != 0) {
PrintAndLogEx(SUCCESS, "%s" _GREEN_("%X%08X%08X"),
s,
(uint32_t)packed->Top,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
} else {
PrintAndLogEx(SUCCESS, "%s" _YELLOW_("%X%08X"),
s,
(uint32_t)packed->Mid,
(uint32_t)packed->Bot
);
}
}
cardformat_t HIDGetCardFormat(int idx) { cardformat_t HIDGetCardFormat(int idx) {
return FormatTable[idx]; return FormatTable[idx];
} }
@ -886,6 +929,26 @@ bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) {
return FormatTable[format_idx].Pack(card, packed); return FormatTable[format_idx].Pack(card, packed);
} }
void HIDPackTryAll(wiegand_card_t *card) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "%-10s %-30s --> Encoded wiegand", "Name", "Description");
PrintAndLogEx(INFO, "----------------------------------------------------------------------");
wiegand_message_t packed;
int i = 0;
while (FormatTable[i].Name) {
memset(&packed, 0, sizeof(wiegand_message_t));
bool res = FormatTable[i].Pack(card, &packed);
if (res) {
cardformat_t fmt = HIDGetCardFormat(i);
print_desc_wiegand(&fmt, &packed);
}
i++;
}
PrintAndLogEx(NORMAL, "");
}
static void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { static void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) {
/* /*
@ -951,3 +1014,4 @@ bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity) {
return result; return result;
} }

View file

@ -44,5 +44,7 @@ int HIDFindCardFormat(const char *format);
cardformat_t HIDGetCardFormat(int idx); cardformat_t HIDGetCardFormat(int idx);
bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed); bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed);
bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity); bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity);
void HIDPackTryAll(wiegand_card_t *card);
void print_wiegand_code(wiegand_message_t *packed);
void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed);
#endif #endif

View file

@ -121,6 +121,12 @@ bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBit
} }
static uint8_t get_length_from_header(wiegand_message_t *data) { static uint8_t get_length_from_header(wiegand_message_t *data) {
/**
* detect if message has "preamble" / "sentinel bit"
*
*/
uint8_t len = 0; uint8_t len = 0;
uint32_t hfmt = 0; // for calculating card length uint32_t hfmt = 0; // for calculating card length

View file

@ -18,17 +18,18 @@ static void crc32_byte(uint32_t *crc, const uint8_t value) {
} }
} }
void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc) { void crc32_ex(const uint8_t *d, const size_t n, uint8_t *crc) {
uint32_t desfire_crc = CRC32_PRESET; uint32_t c = CRC32_PRESET;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < n; i++) {
crc32_byte(&desfire_crc, data[i]); crc32_byte(&c, d[i]);
}
uint32_t crctmp = htole32(desfire_crc);
for (size_t i = 0; i < sizeof(uint32_t); i++) {
crc[i] = ((uint8_t *) &crctmp)[i];
} }
crc[0] = (uint8_t) c;
crc[1] = (uint8_t)(c >> 8);
crc[2] = (uint8_t)(c >> 16);
crc[3] = (uint8_t)(c >> 24);
} }
void crc32_append(uint8_t *data, const size_t len) {
crc32_ex(data, len, data + len); void crc32_append(uint8_t *d, const size_t n) {
crc32_ex(d, n, d + n);
} }

View file

@ -11,7 +11,7 @@
#include "common.h" #include "common.h"
void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc); void crc32_ex(const uint8_t *d, const size_t n, uint8_t *crc);
void crc32_append(uint8_t *data, const size_t len); void crc32_append(uint8_t *d, const size_t n);
#endif #endif

View file

@ -307,10 +307,10 @@ static void cm_crypt(const CryptoAction ca, const uint8_t offset, const uint8_t
} }
} }
void cm_encrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s) { void cm_encrypt(const uint8_t offset, const uint8_t len, const uint8_t *pt, uint8_t *ct, crypto_state s) {
next_n(true, 5, 0, s); next_n(true, 5, 0, s);
next(true, 0, s); next(true, 0, s);
cm_crypt(CA_ENCRYPT, offset, len, ct, pt, s); cm_crypt(CA_ENCRYPT, offset, len, pt, ct, s);
} }
void cm_decrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s) { void cm_decrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s) {

View file

@ -15,14 +15,15 @@
// uid[] the UID in transmission order // uid[] the UID in transmission order
// return: ptr to string // return: ptr to string
char *iso15693_sprintUID(char *dest, uint8_t *uid) { char *iso15693_sprintUID(char *dest, uint8_t *uid) {
static char tempbuf[3 * 8 + 1] = {0}; static char tempbuf[3 * 8 + 1] = {0};
if (dest == NULL) if (dest == NULL)
dest = tempbuf; dest = tempbuf;
if (uid) {
sprintf(dest, "%02X %02X %02X %02X %02X %02X %02X %02X", sprintf(dest, "%02X %02X %02X %02X %02X %02X %02X %02X",
uid[7], uid[6], uid[5], uid[4], uid[7], uid[6], uid[5], uid[4],
uid[3], uid[2], uid[1], uid[0] uid[3], uid[2], uid[1], uid[0]
); );
}
return dest; return dest;
} }

View file

@ -41,6 +41,8 @@
#include <stdlib.h> // qsort #include <stdlib.h> // qsort
#include "parity.h" // for parity test #include "parity.h" // for parity test
#include "pm3_cmd.h" // error codes #include "pm3_cmd.h" // error codes
#include "commonutil.h" // Arraylen
// ********************************************************************************************** // **********************************************************************************************
// ---------------------------------Utilities Section-------------------------------------------- // ---------------------------------Utilities Section--------------------------------------------
// ********************************************************************************************** // **********************************************************************************************
@ -770,6 +772,22 @@ int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr) {
//if (g_debugMode == 2) prnt("DEBUG ASK: clk %d, # Errors %d, Current Best Clk %d, bestStart %d", clk[k], bestErr[k], clk[best], bestStart[best]); //if (g_debugMode == 2) prnt("DEBUG ASK: clk %d, # Errors %d, Current Best Clk %d, bestStart %d", clk[k], bestErr[k], clk[best], bestStart[best]);
} }
bool chg = false;
for (i = 0; i < ARRAYLEN(bestErr); i++) {
chg = (bestErr[i] != 1000);
if (chg)
break;
chg = (bestStart[i] != 0);
if (chg)
break;
}
// just noise - no super good detection. good enough
if (chg == false) {
if (g_debugMode == 2) prnt("DEBUG DetectASKClock: no good values detected - aborting");
return -2;
}
if (!found_clk) if (!found_clk)
*clock = clk[best]; *clock = clk[best];

View file

@ -1,5 +1,6 @@
clear clear
pref pref
analyse foo
data biphaserawdecode data biphaserawdecode
data detectclock data detectclock
data fsktonrz data fsktonrz
@ -95,12 +96,10 @@ hf mf ice
lf config lf config
lf cmdread lf cmdread
lf read lf read
lf search
lf sim lf sim
lf simask lf simask
lf simfsk lf simfsk
lf simpsk lf simpsk
lf simbidir
lf sniff lf sniff
lf em 410x lf em 410x
lf em 4x05 lf em 4x05

View file

@ -38,6 +38,7 @@ Check column "offline" for their availability.
|`analyse nuid `|Y |`create NUID from 7byte UID` |`analyse nuid `|Y |`create NUID from 7byte UID`
|`analyse demodbuff `|Y |`Load binary string to demodbuffer` |`analyse demodbuff `|Y |`Load binary string to demodbuffer`
|`analyse freq `|Y |`Calc wave lengths` |`analyse freq `|Y |`Calc wave lengths`
|`analyse foo `|Y |`muxer`
### data ### data
@ -883,25 +884,25 @@ Check column "offline" for their availability.
|`lf t55xx help `|Y |`This help` |`lf t55xx help `|Y |`This help`
|`lf t55xx clonehelp `|N |`Shows the available clone commands` |`lf t55xx clonehelp `|N |`Shows the available clone commands`
|`lf t55xx config `|Y |`Set/Get T55XX configuration (modulation, inverted, offset, rate)` |`lf t55xx config `|Y |`Set/Get T55XX configuration (modulation, inverted, offset, rate)`
|`lf t55xx dangerraw `|N |`Sends raw bitstream. Dangerous, do not use!! b <bitstream> t <timing>` |`lf t55xx dangerraw `|N |`Sends raw bitstream. Dangerous, do not use!!`
|`lf t55xx detect `|Y |`[1] Try detecting the tag modulation from reading the configuration block.` |`lf t55xx detect `|Y |`Try detecting the tag modulation from reading the configuration block`
|`lf t55xx deviceconfig `|N |`Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap` |`lf t55xx deviceconfig `|N |`Set/Get T55XX device configuration`
|`lf t55xx dump `|N |`[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]` |`lf t55xx dump `|N |`Dump T55xx card Page 0 block 0-7`
|`lf t55xx info `|Y |`[1] Show T55x7 configuration data (page 0/ blk 0)` |`lf t55xx info `|Y |`Show T55x7 configuration data (page 0/ blk 0)`
|`lf t55xx p1detect `|N |`[1] Try detecting if this is a t55xx tag by reading page 1` |`lf t55xx p1detect `|N |`Try detecting if this is a t55xx tag by reading page 1`
|`lf t55xx read `|N |`b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]` |`lf t55xx read `|N |`Read T55xx block data`
|`lf t55xx resetread `|N |`Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)` |`lf t55xx resetread `|N |`Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)`
|`lf t55xx restore `|N |`f <filename> [p <password>] Restore T55xx card Page 0 / Page 1 blocks` |`lf t55xx restore `|N |`Restore T55xx card Page 0 / Page 1 blocks`
|`lf t55xx trace `|Y |`[1] Show T55x7 traceability data (page 1/ blk 0-1)` |`lf t55xx trace `|Y |`Show T55x7 traceability data (page 1/ blk 0-1)`
|`lf t55xx wakeup `|N |`Send AOR wakeup command` |`lf t55xx wakeup `|N |`Send AOR wakeup command`
|`lf t55xx write `|N |`b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]` |`lf t55xx write `|N |`Write T55xx block data`
|`lf t55xx bruteforce `|N |`<start password> <end password> Simple bruteforce attack to find password` |`lf t55xx bruteforce `|N |`Simple bruteforce attack to find password`
|`lf t55xx chk `|N |`Check passwords from dictionary/flash` |`lf t55xx chk `|N |`Check passwords from dictionary/flash`
|`lf t55xx protect `|N |`Password protect tag` |`lf t55xx protect `|N |`Password protect tag`
|`lf t55xx recoverpw `|N |`[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!` |`lf t55xx recoverpw `|N |`Try to recover from bad password write from a cloner`
|`lf t55xx sniff `|Y |`Attempt to recover T55xx commands from sample buffer` |`lf t55xx sniff `|Y |`Attempt to recover T55xx commands from sample buffer`
|`lf t55xx special `|N |`Show block changes with 64 different offsets` |`lf t55xx special `|N |`Show block changes with 64 different offsets`
|`lf t55xx wipe `|N |`[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)` |`lf t55xx wipe `|N |`Wipe a T55xx tag and set defaults (will destroy any data on tag)`
### lf viking ### lf viking

View file

@ -60,6 +60,9 @@ TCK | 23
GND | 6 GND | 6
3.3 | 1 3.3 | 1
# Where to find more information?
There has been lots of articles and blogposts about recoving, debricking, JTAG your Proxmark3 and you find here below a sortiment of resources that will be of help.
## Third party notes on using a BusPirate ## Third party notes on using a BusPirate
* https://github.com/Proxmark/proxmark3/wiki/Debricking-Proxmark3-with-buspirate * https://github.com/Proxmark/proxmark3/wiki/Debricking-Proxmark3-with-buspirate
@ -84,3 +87,6 @@ GND | 6
## Stack Overflow write up article. ## Stack Overflow write up article.
https://stackoverflow.com/questions/48794076/error-halt-timed-out-wake-up-gdb/64291913#64291913 https://stackoverflow.com/questions/48794076/error-halt-timed-out-wake-up-gdb/64291913#64291913
## Old original doc,
Describes the SEGGER JLINK, JTAG process but be warned, this document is old.
https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/original_proxmark3/Compiling%20Proxmark%20source%20and%20firmware%20upgrading%20v1.pdf

View file

@ -593,7 +593,6 @@ typedef struct {
#define CMD_HF_ICLASS_READBL 0x0396 #define CMD_HF_ICLASS_READBL 0x0396
#define CMD_HF_ICLASS_WRITEBL 0x0397 #define CMD_HF_ICLASS_WRITEBL 0x0397
#define CMD_HF_ICLASS_EML_MEMSET 0x0398 #define CMD_HF_ICLASS_EML_MEMSET 0x0398
#define CMD_HF_ICLASS_AUTH 0x0399
#define CMD_HF_ICLASS_CHKKEYS 0x039A #define CMD_HF_ICLASS_CHKKEYS 0x039A
#define CMD_HF_ICLASS_RESTORE 0x039B #define CMD_HF_ICLASS_RESTORE 0x039B

View file

@ -701,7 +701,7 @@ void combine_valid_left_right_states(vector<cs_t> *plcstates, vector<cs_t> *prcs
} }
} }
printf("Found a total of " _YELLOW_("%llu")" combinations, ", ((unsigned long long)plcstates->size()) * prcstates->size()); printf("Found a total of " _YELLOW_("%llu")" combinations, ", ((unsigned long long)plcstates->size()) * prcstates->size());
printf("but only " _GREEN_("%lu")" were valid!\n", pgc_candidates->size()); printf("but only " _GREEN_("%zu")" were valid!\n", pgc_candidates->size());
} }
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
@ -814,7 +814,7 @@ int main(int argc, const char *argv[]) {
printf("Determing the right states that correspond to the keystream\n"); printf("Determing the right states that correspond to the keystream\n");
rbits = sm_right(ks, mask, &rstates); rbits = sm_right(ks, mask, &rstates);
printf("Top-bin for the right state contains " _GREEN_("%d")" correct bits\n", rbits); printf("Top-bin for the right state contains " _GREEN_("%u")" correct bits\n", rbits);
printf("Total count of right bins: " _YELLOW_("%lu") "\n", (unsigned long)rstates.size()); printf("Total count of right bins: " _YELLOW_("%lu") "\n", (unsigned long)rstates.size());
if (rbits < 96) { if (rbits < 96) {
@ -827,16 +827,16 @@ int main(int argc, const char *argv[]) {
printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc); printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc);
search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates); search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates);
printf("Found " _YELLOW_("%lu")" right candidates using the meet-in-the-middle attack\n", crstates.size()); printf("Found " _YELLOW_("%zu")" right candidates using the meet-in-the-middle attack\n", crstates.size());
if (crstates.size() == 0) continue; if (crstates.size() == 0) continue;
printf("Calculating left states using the (unknown bits) mask from the top-right state\n"); printf("Calculating left states using the (unknown bits) mask from the top-right state\n");
sm_left(ks, mask, &clstates); sm_left(ks, mask, &clstates);
printf("Found a total of " _YELLOW_("%lu")" left cipher states, recovering left candidates...\n", clstates.size()); printf("Found a total of " _YELLOW_("%zu")" left cipher states, recovering left candidates...\n", clstates.size());
if (clstates.size() == 0) continue; if (clstates.size() == 0) continue;
search_gc_candidates_left(lstate_before_gc, Q, &clstates); search_gc_candidates_left(lstate_before_gc, Q, &clstates);
printf("The meet-in-the-middle attack returned " _YELLOW_("%lu")" left cipher candidates\n", clstates.size()); printf("The meet-in-the-middle attack returned " _YELLOW_("%zu")" left cipher candidates\n", clstates.size());
if (clstates.size() == 0) continue; if (clstates.size() == 0) continue;
printf("Combining left and right states, disposing invalid combinations\n"); printf("Combining left and right states, disposing invalid combinations\n");

View file

@ -371,7 +371,7 @@ static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstat
std::atomic<bool> key_found{0}; std::atomic<bool> key_found{0};
std::atomic<uint64_t> key{0}; std::atomic<uint64_t> key{0};
std::atomic<size_t> topbits{0}; std::atomic<size_t> g_topbits{0};
std::mutex g_ice_mtx; std::mutex g_ice_mtx;
static uint32_t g_num_cpus = std::thread::hardware_concurrency(); static uint32_t g_num_cpus = std::thread::hardware_concurrency();
@ -421,9 +421,9 @@ static void ice_sm_right_thread(
} }
g_ice_mtx.lock(); g_ice_mtx.lock();
if (bits > topbits.load(std::memory_order_relaxed)) { if (bits > g_topbits.load(std::memory_order_relaxed)) {
// Copy the winning mask // Copy the winning mask
topbits = bits; g_topbits = bits;
memcpy(mask, tmp_mask, 16); memcpy(mask, tmp_mask, 16);
} }
g_ice_mtx.unlock(); g_ice_mtx.unlock();
@ -450,7 +450,7 @@ static void ice_sm_right_thread(
static uint32_t ice_sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) { static uint32_t ice_sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) {
map<uint64_t, uint64_t> bincstates; map<uint64_t, uint64_t> bincstates;
topbits = ATOMIC_VAR_INIT(0); g_topbits = ATOMIC_VAR_INIT(0);
std::vector<std::thread> threads(g_num_cpus); std::vector<std::thread> threads(g_num_cpus);
for (uint8_t m = 0; m < g_num_cpus; m++) { for (uint8_t m = 0; m < g_num_cpus; m++) {
@ -474,7 +474,7 @@ static uint32_t ice_sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t>
// Reverse the vector order (so the higest bin comes first) // Reverse the vector order (so the higest bin comes first)
reverse(pcrstates->begin(), pcrstates->end()); reverse(pcrstates->begin(), pcrstates->end());
return topbits; return g_topbits;
} }
static void ice_sm_left_thread( static void ice_sm_left_thread(
@ -899,7 +899,7 @@ void combine_valid_left_right_states(vector<cs_t> *plcstates, vector<cs_t> *prcs
inner = *plcstates; inner = *plcstates;
} }
printf("Outer " _YELLOW_("%lu")" , inner " _YELLOW_("%lu") "\n", outer.size(), inner.size()); printf("Outer " _YELLOW_("%zu")" , inner " _YELLOW_("%zu") "\n", outer.size(), inner.size());
// Clean up the candidate list // Clean up the candidate list
pgc_candidates->clear(); pgc_candidates->clear();
@ -928,7 +928,7 @@ void combine_valid_left_right_states(vector<cs_t> *plcstates, vector<cs_t> *prcs
} }
} }
printf("Found a total of " _YELLOW_("%llu")" combinations, ", ((unsigned long long)plcstates->size()) * prcstates->size()); printf("Found a total of " _YELLOW_("%llu")" combinations, ", ((unsigned long long)plcstates->size()) * prcstates->size());
printf("but only " _GREEN_("%lu")" were valid!\n", pgc_candidates->size()); printf("but only " _GREEN_("%zu")" were valid!\n", pgc_candidates->size());
} }
static void ice_compare( static void ice_compare(
@ -1080,8 +1080,8 @@ int main(int argc, const char *argv[]) {
//rbits = sm_right(ks, mask, &rstates); //rbits = sm_right(ks, mask, &rstates);
rbits = ice_sm_right(ks, mask, &rstates); rbits = ice_sm_right(ks, mask, &rstates);
printf("Top-bin for the right state contains " _GREEN_("%d")" correct bits\n", rbits); printf("Top-bin for the right state contains " _GREEN_("%u")" correct bits\n", rbits);
printf("Total count of right bins: " _YELLOW_("%lu") "\n", (unsigned long)rstates.size()); printf("Total count of right bins: " _YELLOW_("%zu") "\n", (unsigned long)rstates.size());
if (rbits < 96) { if (rbits < 96) {
printf(_RED_("\n WARNING!!! Better find another trace, the right top-bin is < 96 bits\n\n")); printf(_RED_("\n WARNING!!! Better find another trace, the right top-bin is < 96 bits\n\n"));
@ -1093,19 +1093,19 @@ int main(int argc, const char *argv[]) {
printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc); printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc);
search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates); search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates);
printf("Found " _YELLOW_("%lu")" right candidates using the meet-in-the-middle attack\n", crstates.size()); printf("Found " _YELLOW_("%zu")" right candidates using the meet-in-the-middle attack\n", crstates.size());
if (crstates.size() == 0) continue; if (crstates.size() == 0) continue;
printf("Calculating left states using the (unknown bits) mask from the top-right state\n"); printf("Calculating left states using the (unknown bits) mask from the top-right state\n");
//sm_left(ks, mask, &clstates); //sm_left(ks, mask, &clstates);
ice_sm_left(ks, mask, &clstates); ice_sm_left(ks, mask, &clstates);
printf("Found a total of " _YELLOW_("%lu")" left cipher states, recovering left candidates...\n", clstates.size()); printf("Found a total of " _YELLOW_("%zu")" left cipher states, recovering left candidates...\n", clstates.size());
if (clstates.size() == 0) continue; if (clstates.size() == 0) continue;
search_gc_candidates_left(lstate_before_gc, Q, &clstates); search_gc_candidates_left(lstate_before_gc, Q, &clstates);
printf("The meet-in-the-middle attack returned " _YELLOW_("%lu")" left cipher candidates\n", clstates.size()); printf("The meet-in-the-middle attack returned " _YELLOW_("%zu")" left cipher candidates\n", clstates.size());
if (clstates.size() == 0) continue; if (clstates.size() == 0) continue;
printf("Combining left and right states, disposing invalid combinations\n"); printf("Combining left and right states, disposing invalid combinations\n");

View file

@ -115,7 +115,7 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) {
} }
LZ4_freeStreamHC(lz4_streamhc); LZ4_freeStreamHC(lz4_streamhc);
fprintf(stdout, "compressed %u input bytes to %u output bytes\n", total_size, current_out); fprintf(stdout, "compressed %u input bytes to %d output bytes\n", total_size, current_out);
if (current_out == 0) { if (current_out == 0) {
fprintf(stderr, "Error in lz4"); fprintf(stderr, "Error in lz4");
@ -399,9 +399,6 @@ int main(int argc, char **argv) {
int ret = generate_fpga_version_info(infiles, infile_names, num_input_files, outfile); int ret = generate_fpga_version_info(infiles, infile_names, num_input_files, outfile);
free(infile_names); free(infile_names);
free(infiles); free(infiles);
if (ret) {
return (EXIT_FAILURE);
}
return (ret); return (ret);
} else { } else {
int ret = zlib_compress(infiles, num_input_files, outfile); int ret = zlib_compress(infiles, num_input_files, outfile);

View file

@ -454,8 +454,7 @@ int main(int argc, char **argv) {
if (show) verbose = true; if (show) verbose = true;
// now discover and set up compute device(s) // now discover and set up compute device(s)
if ((err = discoverDevices(profile_selected, device_types_selected, &ocl_platform_cnt, &selected_platforms_cnt, &selected_devices_cnt, &cd_ctx, plat_sel, plat_cnt, dev_sel, dev_cnt, verbose, show)) != 0) if ((err = discoverDevices(profile_selected, device_types_selected, &ocl_platform_cnt, &selected_platforms_cnt, &selected_devices_cnt, &cd_ctx, plat_sel, plat_cnt, dev_sel, dev_cnt, verbose, show)) != 0) {
{
printf("Error: discoverDevices() failed\n"); printf("Error: discoverDevices() failed\n");
if (err < -5) free(cd_ctx); if (err < -5) free(cd_ctx);
MEMORY_FREE_ALL MEMORY_FREE_ALL

View file

@ -40,8 +40,7 @@ bool plat_dev_enabled(unsigned int id, unsigned int *sel, unsigned int cnt, unsi
return false; return false;
} }
unsigned int get_smallest_profile (compute_platform_ctx_t *cd_ctx, size_t ocl_platform_cnt) unsigned int get_smallest_profile(compute_platform_ctx_t *cd_ctx, size_t ocl_platform_cnt) {
{
unsigned int profile = 0xff; unsigned int profile = 0xff;
size_t x = 0, y = 0; size_t x = 0, y = 0;
@ -68,8 +67,7 @@ unsigned int get_smallest_profile (compute_platform_ctx_t *cd_ctx, size_t ocl_pl
return profile; return profile;
} }
int discoverDevices(unsigned int profile_selected, uint32_t device_types_selected, cl_uint *platform_detected_cnt, size_t *selected_platforms_cnt, size_t *selected_devices_cnt, compute_platform_ctx_t **cd_ctx, unsigned int *plat_sel, unsigned int plat_cnt, unsigned int *dev_sel, unsigned int dev_cnt, bool verbose, bool show) int discoverDevices(unsigned int profile_selected, uint32_t device_types_selected, cl_uint *platform_detected_cnt, size_t *selected_platforms_cnt, size_t *selected_devices_cnt, compute_platform_ctx_t **cd_ctx, unsigned int *plat_sel, unsigned int plat_cnt, unsigned int *dev_sel, unsigned int dev_cnt, bool verbose, bool show) {
{
int err = 0; int err = 0;
unsigned int ocl_platform_max = MAX_OPENCL_DEVICES; // 16 unsigned int ocl_platform_max = MAX_OPENCL_DEVICES; // 16
cl_uint ocl_platform_cnt; cl_uint ocl_platform_cnt;

View file

@ -176,8 +176,7 @@ int thread_init(thread_ctx_t *ctx, short type, size_t thread_count) {
return 0; return 0;
} }
int thread_start_scheduler (thread_ctx_t *ctx, thread_args_t *t_arg, wu_queue_ctx_t *queue_ctx) int thread_start_scheduler(thread_ctx_t *ctx, thread_args_t *t_arg, wu_queue_ctx_t *queue_ctx) {
{
size_t z = 0; size_t z = 0;
bool found = false; bool found = false;
bool done = false; bool done = false;

View file

@ -347,112 +347,112 @@ while true; do
if ! CheckExecute "trace load/list x" "$CLIENTBIN -c 'trace load -f traces/hf_14a_mfu.trace; trace list -x1 -t 14a;'" "0.0101840425"; then break; fi if ! CheckExecute "trace load/list x" "$CLIENTBIN -c 'trace load -f traces/hf_14a_mfu.trace; trace list -x1 -t 14a;'" "0.0101840425"; then break; fi
echo -e "\n${C_BLUE}Testing LF:${C_NC}" echo -e "\n${C_BLUE}Testing LF:${C_NC}"
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 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 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 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-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-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 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 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 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 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 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 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 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 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 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 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 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 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 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'" \ if ! CheckExecute slow "lf T55 awid 26 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_26.pm3; lf awid demod'" \
"AWID - len: 26 FC: 224 Card: 1337 - Wiegand: 3c00a73"; then break; fi "AWID - len: 26 FC: 224 Card: 1337 - Wiegand: 3c00a73"; then break; fi
if ! CheckExecute slow "lf T55 awid 50 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf search 1'" "AWID ID found"; then break; fi if ! CheckExecute slow "lf T55 awid 50 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf search -1'" "AWID ID found"; then break; fi
if ! CheckExecute slow "lf T55 awid 50 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf awid demod'" \ if ! CheckExecute slow "lf T55 awid 50 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf awid demod'" \
"AWID - len: 50 FC: 2001 Card: 13371337 - Wiegand: 20fa201980f92, Raw: 0128b12eb1811d7117e22111"; then break; fi "AWID - len: 50 FC: 2001 Card: 13371337 - Wiegand: 20fa201980f92, Raw: 0128b12eb1811d7117e22111"; then break; fi
if ! CheckExecute slow "lf T55 em410x test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf search 1'" "EM410x ID found"; then break; fi if ! CheckExecute slow "lf T55 em410x test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf search -1'" "EM410x ID found"; then break; fi
if ! CheckExecute slow "lf T55 em410x test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf em 410x demod'" \ if ! CheckExecute slow "lf T55 em410x test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf em 410x demod'" \
"EM 410x ID 0F0368568B"; then break; fi "EM 410x ID 0F0368568B"; then break; fi
if ! CheckExecute slow "lf T55 fdxb_animal test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf search 1'" "FDX-B ID found"; then break; fi if ! CheckExecute slow "lf T55 fdxb_animal test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf search -1'" "FDX-B ID found"; then break; fi
if ! CheckExecute slow "lf T55 fdxb_animal test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf fdxb demod'" \ if ! CheckExecute slow "lf T55 fdxb_animal test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf fdxb demod'" \
"Animal ID 999-000000112233"; then break; fi "Animal ID 999-000000112233"; then break; fi
if ! CheckExecute slow "lf T55 fdxb_extended test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_extended.pm3; lf search 1'" "FDX-B ID found"; then break; fi if ! CheckExecute slow "lf T55 fdxb_extended test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_extended.pm3; lf search -1'" "FDX-B ID found"; then break; fi
if ! CheckExecute slow "lf T55 fdxb_extended test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_extended.pm3; lf fdxb demod'" \ if ! CheckExecute slow "lf T55 fdxb_extended test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_extended.pm3; lf fdxb demod'" \
"temperature 95.2 F / 35.1 C"; then break; fi "temperature 95.2 F / 35.1 C"; then break; fi
if ! CheckExecute slow "lf T55 gallagher test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gallagher.pm3; lf search 1'" "GALLAGHER ID found"; then break; fi if ! CheckExecute slow "lf T55 gallagher test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gallagher.pm3; lf search -1'" "GALLAGHER ID found"; then break; fi
if ! CheckExecute slow "lf T55 gallagher test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gallagher.pm3; lf gallagher demod'" \ if ! CheckExecute slow "lf T55 gallagher test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gallagher.pm3; lf gallagher demod'" \
"GALLAGHER - Region: 0 FC: 27865 CN: 682758 Issue Level: 13"; then break; fi "GALLAGHER - Region: 0 FC: 27865 CN: 682758 Issue Level: 13"; then break; fi
if ! CheckExecute slow "lf T55 gproxii test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf search 1'" "Guardall G-Prox II ID found"; then break; fi if ! CheckExecute slow "lf T55 gproxii test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi
if ! CheckExecute slow "lf T55 gproxii test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf gproxii demod'" \ if ! CheckExecute slow "lf T55 gproxii test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf gproxii demod'" \
"G-Prox-II - len: 26 FC: 123 Card: 11223, Raw: f98c7038c63356c7ac26398c"; then break; fi "G-Prox-II - len: 26 FC: 123 Card: 11223, Raw: f98c7038c63356c7ac26398c"; then break; fi
if ! CheckExecute slow "lf T55 hid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf search 1'" "HID Prox ID found"; then break; fi if ! CheckExecute slow "lf T55 hid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf search -1'" "HID Prox ID found"; then break; fi
if ! CheckExecute slow "lf T55 hid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf hid demod'" \ if ! CheckExecute slow "lf T55 hid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf hid demod'" \
"HID H10301 26-bit; FC: 118 CN: 1603"; then break; fi "HID H10301 26-bit; FC: 118 CN: 1603"; then break; fi
if ! CheckExecute slow "lf T55 hid_48 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid_48.pm3; lf search 1'" "HID Prox ID found"; then break; fi if ! CheckExecute slow "lf T55 hid_48 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid_48.pm3; lf search -1'" "HID Prox ID found"; then break; fi
if ! CheckExecute slow "lf T55 hid_48 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid_48.pm3; lf hid demod'" \ if ! CheckExecute slow "lf T55 hid_48 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid_48.pm3; lf hid demod'" \
"HID Corporate 1000 48-bit"; then break; fi "HID Corporate 1000 48-bit"; then break; fi
if ! CheckExecute slow "lf T55 indala_hedem test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf search 1'" "Indala ID found"; then break; fi if ! CheckExecute slow "lf T55 indala_hedem test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf search -1'" "Indala ID found"; then break; fi
if ! CheckExecute slow "lf T55 indala_hedem test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf indala demod'" \ if ! CheckExecute slow "lf T55 indala_hedem test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf indala demod'" \
"Heden-2L \| 888"; then break; fi "Heden-2L \| 888"; then break; fi
if ! CheckExecute slow "lf T55 indala test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf search 1'" "Indala ID found"; then break; fi if ! CheckExecute slow "lf T55 indala test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf search -1'" "Indala ID found"; then break; fi
if ! CheckExecute slow "lf T55 indala test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf indala demod'" \ if ! CheckExecute slow "lf T55 indala test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf indala demod'" \
"Fmt 26 FC: 123 Card: 1337 checksum: 10"; then break; fi "Fmt 26 FC: 123 Card: 1337 checksum: 10"; then break; fi
if ! CheckExecute slow "lf T55 indala_224 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf search 1'" "Indala ID found"; then break; fi if ! CheckExecute slow "lf T55 indala_224 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf search -1'" "Indala ID found"; then break; fi
if ! CheckExecute slow "lf T55 indala_224 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf indala demod'" \ if ! CheckExecute slow "lf T55 indala_224 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf indala demod'" \
"Indala (len 224) Raw: 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"; then break; fi "Indala (len 224) Raw: 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"; then break; fi
if ! CheckExecute slow "lf T55 io test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf search 1'" "IO Prox ID found"; then break; fi if ! CheckExecute slow "lf T55 io test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf search -1'" "IO Prox ID found"; then break; fi
if ! CheckExecute slow "lf T55 io test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf io demod'" \ if ! CheckExecute slow "lf T55 io test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf io demod'" \
"IO Prox - XSF(01)01:01337, Raw: 007840603059cf3f (ok)"; then break; fi "IO Prox - XSF(01)01:01337, Raw: 007840603059cf3f (ok)"; then break; fi
if ! CheckExecute slow "lf T55 jablotron test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf search 1'" "Jablotron ID found"; then break; fi if ! CheckExecute slow "lf T55 jablotron test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf search -1'" "Jablotron ID found"; then break; fi
if ! CheckExecute slow "lf T55 jablotron test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf jablotron demod'" \ if ! CheckExecute slow "lf T55 jablotron test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf jablotron demod'" \
"Printed: 1410-00-0011-2233"; then break; fi "Printed: 1410-00-0011-2233"; then break; fi
if ! CheckExecute slow "lf T55 keri test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri.pm3; lf search 1'" "KERI ID found"; then break; fi if ! CheckExecute slow "lf T55 keri test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri.pm3; lf search -1'" "KERI ID found"; then break; fi
if ! CheckExecute slow "lf T55 keri test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri.pm3; lf keri demod'" \ if ! CheckExecute slow "lf T55 keri test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri.pm3; lf keri demod'" \
"KERI - Internal ID: 112233, Raw: E00000008001B669"; then break; fi "KERI - Internal ID: 112233, Raw: E00000008001B669"; then break; fi
if ! CheckExecute slow "lf T55 keri_internalid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_internalid.pm3; lf search 1'" "KERI ID found"; then break; fi if ! CheckExecute slow "lf T55 keri_internalid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_internalid.pm3; lf search -1'" "KERI ID found"; then break; fi
if ! CheckExecute slow "lf T55 keri_internalid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_internalid.pm3; lf keri demod'" \ if ! CheckExecute slow "lf T55 keri_internalid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_internalid.pm3; lf keri demod'" \
"KERI - Internal ID: 12345, Raw: E000000080003039"; then break; fi "KERI - Internal ID: 12345, Raw: E000000080003039"; then break; fi
if ! CheckExecute slow "lf T55 keri_msid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_msid.pm3; lf search 1'" "KERI ID found"; then break; fi if ! CheckExecute slow "lf T55 keri_msid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_msid.pm3; lf search -1'" "KERI ID found"; then break; fi
if ! CheckExecute slow "lf T55 keri_msid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_msid.pm3; lf keri demod'" \ if ! CheckExecute slow "lf T55 keri_msid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_keri_msid.pm3; lf keri demod'" \
"Descrambled MS - FC: 6 Card: 12345"; then break; fi "Descrambled MS - FC: 6 Card: 12345"; then break; fi
# if ! CheckExecute slow "lf T55 motorola test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_motorola.pm3; lf search 1'" "Indala ID found"; then break; fi # if ! CheckExecute slow "lf T55 motorola test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_motorola.pm3; lf search -1'" "Indala ID found"; then break; fi
if ! CheckExecute slow "lf T55 motorola test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_motorola.pm3; lf motorola demod'" \ if ! CheckExecute slow "lf T55 motorola test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_motorola.pm3; lf motorola demod'" \
"Motorola - fmt: 26 FC: 258 Card: 2, Raw: A0000000A0002021"; then break; fi "Motorola - fmt: 26 FC: 258 Card: 2, Raw: A0000000A0002021"; then break; fi
if ! CheckExecute slow "lf T55 nedap test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf search 1'" "NEDAP ID found"; then break; fi if ! CheckExecute slow "lf T55 nedap test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf search -1'" "NEDAP ID found"; then break; fi
if ! CheckExecute slow "lf T55 nedap test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf nedap demod'" \ if ! CheckExecute slow "lf T55 nedap test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf nedap demod'" \
"NEDAP (64b) - ID: 12345 subtype: 1 customer code: 291 / 0x123 Raw: FF82246508209953"; then break; fi "NEDAP (64b) - ID: 12345 subtype: 1 customer code: 291 / 0x123 Raw: FF82246508209953"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf search 1'" "NexWatch ID found"; then break; fi if ! CheckExecute slow "lf T55 nexwatch test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf search -1'" "NexWatch ID found"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf nexwatch demod'" \ if ! CheckExecute slow "lf T55 nexwatch test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf nexwatch demod'" \
"Raw : 5600000000213C9F8F150C00"; then break; fi "Raw : 5600000000213C9F8F150C00"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch_nexkey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_nexkey.pm3; lf search 1'" "NexWatch ID found"; then break; fi if ! CheckExecute slow "lf T55 nexwatch_nexkey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_nexkey.pm3; lf search -1'" "NexWatch ID found"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch_nexkey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_nexkey.pm3; lf nexwatch demod'" \ if ! CheckExecute slow "lf T55 nexwatch_nexkey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_nexkey.pm3; lf nexwatch demod'" \
"88bit id : 521512301 (0x1f15a56d)"; then break; fi "88bit id : 521512301 (0x1f15a56d)"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch_quadrakey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_quadrakey.pm3; lf search 1'" "NexWatch ID found"; then break; fi if ! CheckExecute slow "lf T55 nexwatch_quadrakey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_quadrakey.pm3; lf search -1'" "NexWatch ID found"; then break; fi
if ! CheckExecute slow "lf T55 nexwatch_quadrakey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_quadrakey.pm3; lf nexwatch demod'" \ if ! CheckExecute slow "lf T55 nexwatch_quadrakey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch_quadrakey.pm3; lf nexwatch demod'" \
"88bit id : 521512301 (0x1f15a56d)"; then break; fi "88bit id : 521512301 (0x1f15a56d)"; then break; fi
if ! CheckExecute slow "lf T55 noralsy test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_noralsy.pm3; lf search 1'" "Noralsy ID found"; then break; fi if ! CheckExecute slow "lf T55 noralsy test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_noralsy.pm3; lf search -1'" "Noralsy ID found"; then break; fi
if ! CheckExecute slow "lf T55 noralsy test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_noralsy.pm3; lf noralsy demod'" \ if ! CheckExecute slow "lf T55 noralsy test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_noralsy.pm3; lf noralsy demod'" \
"Noralsy - Card: 112233, Year: 2000, Raw: BB0214FF0110002233070000"; then break; fi "Noralsy - Card: 112233, Year: 2000, Raw: BB0214FF0110002233070000"; then break; fi
if ! CheckExecute slow "lf T55 pac test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pac.pm3; lf search 1'" "PAC/Stanley ID found"; then break; fi if ! CheckExecute slow "lf T55 pac test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pac.pm3; lf search -1'" "PAC/Stanley ID found"; then break; fi
if ! CheckExecute slow "lf T55 pac test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pac.pm3; lf pac demod'" \ if ! CheckExecute slow "lf T55 pac test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pac.pm3; lf pac demod'" \
"PAC/Stanley - Card: CD4F5552, Raw: FF2049906D8511C593155B56D5B2649F"; then break; fi "PAC/Stanley - Card: CD4F5552, Raw: FF2049906D8511C593155B56D5B2649F"; then break; fi
if ! CheckExecute slow "lf T55 paradox test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_paradox.pm3; lf search 1'" "Paradox ID found"; then break; fi if ! CheckExecute slow "lf T55 paradox test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_paradox.pm3; lf search -1'" "Paradox ID found"; then break; fi
if ! CheckExecute slow "lf T55 paradox test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_paradox.pm3; lf paradox demod'" \ if ! CheckExecute slow "lf T55 paradox test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_paradox.pm3; lf paradox demod'" \
"Paradox - ID: 004209dea FC: 96 Card: 40426, Checksum: b2, Raw: 0f55555695596a6a9999a59a"; then break; fi "Paradox - ID: 004209dea FC: 96 Card: 40426, Checksum: b2, Raw: 0f55555695596a6a9999a59a"; then break; fi
if ! CheckExecute slow "lf T55 presco test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_presco.pm3; lf search 1'" "Presco ID found"; then break; fi if ! CheckExecute slow "lf T55 presco test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_presco.pm3; lf search -1'" "Presco ID found"; then break; fi
if ! CheckExecute slow "lf T55 presco test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_presco.pm3; lf presco demod'" \ if ! CheckExecute slow "lf T55 presco test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_presco.pm3; lf presco demod'" \
"Presco Site code: 30 User code: 8665 Full code: 1E8021D9 Raw: 10D0000000000000000000001E8021D9"; then break; fi "Presco Site code: 30 User code: 8665 Full code: 1E8021D9 Raw: 10D0000000000000000000001E8021D9"; then break; fi
if ! CheckExecute slow "lf T55 pyramid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pyramid.pm3; lf search 1'" "Pyramid ID found"; then break; fi if ! CheckExecute slow "lf T55 pyramid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pyramid.pm3; lf search -1'" "Pyramid ID found"; then break; fi
if ! CheckExecute slow "lf T55 pyramid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pyramid.pm3; lf pyramid demod'" \ if ! CheckExecute slow "lf T55 pyramid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_pyramid.pm3; lf pyramid demod'" \
"Pyramid - len: 26, FC: 123 Card: 11223 - Wiegand: 2f657ae, Raw: 00010101010101010101016eb35e5da4"; then break; fi "Pyramid - len: 26, FC: 123 Card: 11223 - Wiegand: 2f657ae, Raw: 00010101010101010101016eb35e5da4"; then break; fi
if ! CheckExecute slow "lf T55 securakey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_securakey.pm3; lf search 1'" "Securakey ID found"; then break; fi if ! CheckExecute slow "lf T55 securakey test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_securakey.pm3; lf search -1'" "Securakey ID found"; then break; fi
if ! CheckExecute slow "lf T55 securakey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_securakey.pm3; lf securakey demod'" \ if ! CheckExecute slow "lf T55 securakey test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_securakey.pm3; lf securakey demod'" \
"Securakey - len: 26 FC: 0x35 Card: 64169, Raw: 7FCB400001ADEA5344300000"; then break; fi "Securakey - len: 26 FC: 0x35 Card: 64169, Raw: 7FCB400001ADEA5344300000"; then break; fi
if ! CheckExecute slow "lf T55 viking test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_viking.pm3; lf search 1'" "Viking ID found"; then break; fi if ! CheckExecute slow "lf T55 viking test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_viking.pm3; lf search -1'" "Viking ID found"; then break; fi
if ! CheckExecute slow "lf T55 viking test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_viking.pm3; lf viking demod'" \ if ! CheckExecute slow "lf T55 viking test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_viking.pm3; lf viking demod'" \
"Viking - Card 0001A337, Raw: F200000001A337CF"; then break; fi "Viking - Card 0001A337, Raw: F200000001A337CF"; then break; fi
if ! CheckExecute slow "lf T55 visa2000 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_visa2000.pm3; lf search 1'" "Visa2000 ID found"; then break; fi if ! CheckExecute slow "lf T55 visa2000 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_visa2000.pm3; lf search -1'" "Visa2000 ID found"; then break; fi
if ! CheckExecute slow "lf T55 visa2000 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_visa2000.pm3; lf visa2000 demod'" \ if ! CheckExecute slow "lf T55 visa2000 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_visa2000.pm3; lf visa2000 demod'" \
"Visa2000 - Card 112233, Raw: 564953320001B66900000183"; then break; fi "Visa2000 - Card 112233, Raw: 564953320001B66900000183"; then break; fi