mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-02 21:41:11 +08:00
clean up
This commit is contained in:
parent
68db54028c
commit
b4a8409349
5 changed files with 136 additions and 298 deletions
|
@ -80,53 +80,6 @@ static void DownloadLogInstructions(const char *logfile) {
|
|||
Dbprintf(_YELLOW_("3.") " cat %s", logfile);
|
||||
}
|
||||
|
||||
static bool strip_check_parities(uint64_t data, uint32_t *word) {
|
||||
|
||||
uint8_t rparity = 0, cparity = 0;
|
||||
uint8_t rparity_m = 0, cparity_m = 0, stop_bit_m = 0;
|
||||
|
||||
// strip parities
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
*word <<= 1;
|
||||
*word += (data >> (EM4X50_TAG_WORD - 1 - 9 * i - j)) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate row parities
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rparity <<= 1;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
rparity ^= (*word >> (31 - 8 * i - j)) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate column parities
|
||||
for (int i = 0; i < 8; i++) {
|
||||
cparity <<= 1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
cparity ^= (*word >> (31 - 8 * j - i)) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
// measured row parities
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rparity_m <<= 1;
|
||||
rparity_m += (data >> (EM4X50_TAG_WORD - 9 * (i + 1))) & 1;
|
||||
}
|
||||
|
||||
// measured column parities
|
||||
cparity_m = (data >> 1) & 0xFF;
|
||||
|
||||
// measured stop bit
|
||||
stop_bit_m = data & 1;
|
||||
|
||||
if ((cparity_m == cparity) && (rparity_m == rparity) && (stop_bit_m == 0))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int get_input_data_from_file(uint32_t *words, char *inputfile) {
|
||||
|
||||
size_t now = 0;
|
||||
|
@ -173,8 +126,6 @@ void RunMod(void) {
|
|||
|
||||
bool state_change = true;//, password_found = false;
|
||||
int pwd_found = false;
|
||||
//int cnt = 0;
|
||||
//int iterprint = 0;
|
||||
uint8_t state = STATE_SIM;
|
||||
// declarations for simulating
|
||||
uint32_t words[33] = {0x0};
|
||||
|
@ -183,8 +134,7 @@ void RunMod(void) {
|
|||
size_t now = 0;
|
||||
// declarations for reading
|
||||
int no_words = 0;
|
||||
uint64_t data[EM4X50_TAG_WORD];
|
||||
uint32_t word = 0;//, pwd = 0x0, rpwd = 0x0;
|
||||
//uint32_t words[EM4X50_TAG_WORD];
|
||||
uint8_t entry[81];
|
||||
|
||||
rdv40_spiffs_lazy_mount();
|
||||
|
@ -273,14 +223,14 @@ void RunMod(void) {
|
|||
Dbprintf(_YELLOW_("switched to EM4x50 reading mode"));
|
||||
|
||||
memset(entry, 0, sizeof(entry));
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(words, 0, sizeof(words));
|
||||
|
||||
log_exists = exists_in_spiffs(LF_EM4X50COLLECT_LOGFILE);
|
||||
|
||||
state_change = false;
|
||||
}
|
||||
|
||||
no_words = em4x50_standalone_read(data);
|
||||
no_words = em4x50_standalone_read(words);
|
||||
|
||||
if (no_words > 0) {
|
||||
|
||||
|
@ -293,11 +243,7 @@ void RunMod(void) {
|
|||
|
||||
for (int i = 0; i < no_words; i++) {
|
||||
|
||||
if (strip_check_parities(data[i], &word))
|
||||
sprintf((char *)entry, " %2i -> 0x%08"PRIx32" (parity check ok)", i + 1, word);
|
||||
else
|
||||
sprintf((char *)entry, " %2i -> 0x%08"PRIx32" (parity check failed)", i + 1, word);
|
||||
|
||||
sprintf((char *)entry, " %2i -> 0x%08"PRIx32"", i + 1, words[i]);
|
||||
Dbprintf("%s", entry);
|
||||
strcat((char *)entry, "\n");
|
||||
append(LF_EM4X50COLLECT_LOGFILE, entry, strlen((char *)entry));
|
||||
|
|
301
armsrc/em4x50.c
301
armsrc/em4x50.c
|
@ -15,50 +15,6 @@
|
|||
#include "commonutil.h"
|
||||
#include "em4x50.h"
|
||||
|
||||
// 4 data bytes
|
||||
// + byte with row parities
|
||||
// + column parity byte
|
||||
// + byte with stop bit
|
||||
|
||||
static em4x50_tag_t tag = {
|
||||
.sectors = {
|
||||
[0] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // password
|
||||
[1] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // protection word
|
||||
[2] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // control word
|
||||
[3] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[4] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[5] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[7] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[11] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[13] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[14] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[15] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[17] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[18] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[19] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[20] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[21] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[22] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[23] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[24] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[25] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[26] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[27] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[28] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[29] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[30] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[31] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user
|
||||
[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // device serial number
|
||||
[33] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // device identification
|
||||
},
|
||||
};
|
||||
|
||||
// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
|
||||
// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
|
||||
// EM4x50 units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
|
||||
|
@ -93,6 +49,7 @@ static em4x50_tag_t tag = {
|
|||
#define EM4X50_COMMAND_TIMEOUT 5000
|
||||
#define FPGA_TIMER_0 0
|
||||
|
||||
static uint32_t em4x50_tag[34] = {0x0};
|
||||
int gHigh = 0;
|
||||
int gLow = 0;
|
||||
|
||||
|
@ -100,27 +57,7 @@ int gLow = 0;
|
|||
|
||||
static void init_tag(void) {
|
||||
|
||||
// iceman: memset(tag.sectors, 0x00, sizeof));
|
||||
|
||||
// initialize global tag structure
|
||||
for (int i = 0; i < 34; i++)
|
||||
for (int j = 0; j < 7; j++)
|
||||
tag.sectors[i][j] = 0x00;
|
||||
}
|
||||
|
||||
static uint8_t bits2byte(uint8_t *bits, int length) {
|
||||
|
||||
// converts <length> separate bits into a single "byte"
|
||||
uint8_t byte = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
byte |= bits[i];
|
||||
|
||||
if (i != length - 1)
|
||||
byte <<= 1;
|
||||
}
|
||||
|
||||
return byte;
|
||||
memset(em4x50_tag, 0x00, sizeof(em4x50_tag));
|
||||
}
|
||||
|
||||
static void msb2lsb_word(uint8_t *word) {
|
||||
|
@ -139,31 +76,6 @@ static void msb2lsb_word(uint8_t *word) {
|
|||
word[3] = buff[3];
|
||||
}
|
||||
|
||||
static void save_word(int pos, uint8_t bits[EM4X50_TAG_WORD]) {
|
||||
|
||||
// split "raw" word into data, row and column parity bits and stop bit and
|
||||
// save them in global tag structure
|
||||
uint8_t row_parity[4];
|
||||
uint8_t col_parity[8];
|
||||
|
||||
// data and row parities
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tag.sectors[pos][i] = bits2byte(&bits[9 * i], 8);
|
||||
row_parity[i] = bits[9 * i + 8];
|
||||
}
|
||||
|
||||
tag.sectors[pos][4] = bits2byte(row_parity, 4);
|
||||
|
||||
// column parities
|
||||
for (int i = 0; i < 8; i++)
|
||||
col_parity[i] = bits[36 + i];
|
||||
|
||||
tag.sectors[pos][5] = bits2byte(col_parity, 8);
|
||||
|
||||
// stop bit
|
||||
tag.sectors[pos][6] = bits[44];
|
||||
}
|
||||
|
||||
static void wait_timer(int timer, uint32_t period) {
|
||||
|
||||
// do nothing for <period> using timer <timer>
|
||||
|
@ -316,8 +228,6 @@ static int get_next_bit(void) {
|
|||
|
||||
static uint32_t get_pulse_length(void) {
|
||||
|
||||
// Dbprintf( _CYAN_("4x50 get_pulse_length A") );
|
||||
|
||||
int32_t timeout = (T0 * 3 * EM4X50_T_TAG_FULL_PERIOD);
|
||||
|
||||
// iterates pulse length (low -> high -> low)
|
||||
|
@ -354,6 +264,7 @@ static uint32_t get_pulse_length(void) {
|
|||
}
|
||||
|
||||
static bool check_pulse_length(uint32_t pl, int length) {
|
||||
|
||||
// check if pulse length <pl> corresponds to given length <length>
|
||||
return ((pl >= T0 * (length - EM4X50_TAG_TOLERANCE)) && (pl <= T0 * (length + EM4X50_TAG_TOLERANCE)));
|
||||
}
|
||||
|
@ -612,9 +523,7 @@ bool em4x50_sim_send_word(uint32_t word) {
|
|||
|
||||
bool em4x50_sim_send_listen_window(void) {
|
||||
|
||||
//int i = 0;
|
||||
uint16_t check = 0;
|
||||
//uint8_t test[100] = {0};
|
||||
|
||||
for (int t = 0; t < 5 * EM4X50_T_TAG_FULL_PERIOD; t++) {
|
||||
|
||||
|
@ -643,7 +552,7 @@ bool em4x50_sim_send_listen_window(void) {
|
|||
|
||||
check = 0;
|
||||
|
||||
//wait until SSC_CLK goes LOW
|
||||
// wait until SSC_CLK goes LOW
|
||||
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
||||
WDT_HIT();
|
||||
if (check == 1000) {
|
||||
|
@ -671,8 +580,7 @@ static int request_receive_mode(void) {
|
|||
// To issue a command we have to find a listen window first.
|
||||
// Because identification and sychronization at the same time is not
|
||||
// possible when using pulse lengths a double listen window is used.
|
||||
bool bcommand = true;
|
||||
return find_double_listen_window(bcommand);
|
||||
return find_double_listen_window(true);
|
||||
}
|
||||
|
||||
static bool check_ack(bool bliw) {
|
||||
|
@ -728,90 +636,146 @@ static bool check_ack(bool bliw) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static int get_word_from_bitstream(uint8_t bits[EM4X50_TAG_WORD]) {
|
||||
static bool extract_parities(uint64_t word, uint32_t *data) {
|
||||
|
||||
// extract and check parities
|
||||
// return result of parity check and extracted plain data
|
||||
|
||||
uint8_t row_parities = 0x0, col_parities = 0x0;
|
||||
uint8_t row_parities_calculated = 0x0, col_parities_calculated = 0x0;
|
||||
|
||||
*data = 0x0;
|
||||
|
||||
// extract plain data (32 bits) from raw word (45 bits)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
*data <<= 8;
|
||||
*data |= (word >> ((4 - i) * 9 + 1)) & 0xFF;
|
||||
}
|
||||
|
||||
// extract row parities (4 bits + stop bit) from raw word (45 bits)
|
||||
for (int i = 0; i < 5; i++) {
|
||||
row_parities <<= 1;
|
||||
row_parities |= (word >> ((4 - i) * 9)) & 0x1;
|
||||
}
|
||||
|
||||
// extract col_parities (8 bits, no stop bit) from raw word (45 bits)
|
||||
col_parities = (word >> 1) & 0xFF;
|
||||
|
||||
// check extracted parities against extracted data
|
||||
|
||||
// calculate row parities from data
|
||||
for (int i = 0; i < 4; i++) {
|
||||
row_parities_calculated <<= 1;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
row_parities_calculated ^= (*data >> ((3 - i) * 8 + (7 - j))) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
// add stop bit (always zero)
|
||||
row_parities_calculated <<= 1;
|
||||
|
||||
// calculate column parities from data
|
||||
for (int i = 0; i < 8; i++) {
|
||||
col_parities_calculated <<= 1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
col_parities_calculated ^= (*data >> ((3 - j) * 8 + (7 - i))) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((row_parities == row_parities_calculated) && (col_parities == col_parities_calculated))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int get_word_from_bitstream(uint32_t *data) {
|
||||
|
||||
// decodes one word by evaluating pulse lengths and previous bit;
|
||||
// word must have 45 bits in total:
|
||||
// 32 data bits + 4 row parity bits + 8 column parity bits + 1 stop bit
|
||||
|
||||
bool bbitchange = false;
|
||||
int i = 0;
|
||||
bool bitchange = false;
|
||||
int cnt = 0;
|
||||
uint32_t pl = 0;
|
||||
uint64_t word = 0x0;
|
||||
|
||||
*data = 0x0;
|
||||
|
||||
// initial bit value depends on last pulse length of listen window
|
||||
pl = get_pulse_length();
|
||||
if (check_pulse_length(pl, 3 * EM4X50_T_TAG_HALF_PERIOD)) {
|
||||
|
||||
// pulse length = 1.5
|
||||
bits[0] = 1;
|
||||
word = 0x1;
|
||||
|
||||
} else if (check_pulse_length(pl, 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||
|
||||
// pulse length = 2
|
||||
bits[0] = 0;
|
||||
bbitchange = true;
|
||||
bitchange = true;
|
||||
|
||||
} else {
|
||||
|
||||
// pulse length = 2.5
|
||||
bits[0] = 0;
|
||||
bits[1] = 1;
|
||||
i++;
|
||||
word = 0x1;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
// identify remaining bits based on pulse lengths
|
||||
// between two listen windows only pulse lengths of 1, 1.5 and 2 are possible
|
||||
while (BUTTON_PRESS() == false) {
|
||||
while (true) {
|
||||
|
||||
i++;
|
||||
cnt++;
|
||||
word <<= 1;
|
||||
|
||||
pl = get_pulse_length();
|
||||
|
||||
if (check_pulse_length(pl, EM4X50_T_TAG_FULL_PERIOD)) {
|
||||
|
||||
// pulse length = 1 -> keep former bit value
|
||||
bits[i] = bits[i - 1];
|
||||
word |= (word >> 1) & 0x1;
|
||||
|
||||
} else if (check_pulse_length(pl, 3 * EM4X50_T_TAG_HALF_PERIOD)) {
|
||||
|
||||
// pulse length = 1.5 -> decision on bit change
|
||||
|
||||
if (bbitchange) {
|
||||
if (bitchange) {
|
||||
|
||||
// if number of pulse lengths with 1.5 periods is even -> add bit
|
||||
bits[i] = (bits[i - 1] == 1) ? 1 : 0;
|
||||
word |= (word >> 1) & 0x1;
|
||||
word <<= 1;
|
||||
|
||||
// pulse length of 1.5 changes bit value
|
||||
bits[i + 1] = (bits[i] == 1) ? 0 : 1;
|
||||
i++;
|
||||
word |= ((word >> 1) & 0x1) ^ 0x1;
|
||||
cnt++;
|
||||
|
||||
// next time add only one bit
|
||||
bbitchange = false;
|
||||
bitchange = false;
|
||||
|
||||
} else {
|
||||
|
||||
bits[i] = (bits[i - 1] == 1) ? 0 : 1;
|
||||
word |= ((word >> 1) & 0x1) ^ 0x1;
|
||||
|
||||
// next time two bits have to be added
|
||||
bbitchange = true;
|
||||
bitchange = true;
|
||||
}
|
||||
|
||||
} else if (check_pulse_length(pl, 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||
|
||||
// pulse length of 2 means: adding 2 bits "01"
|
||||
bits[i] = 0;
|
||||
bits[i + 1] = 1;
|
||||
i++;
|
||||
cnt++;
|
||||
|
||||
word <<= 1;
|
||||
word |= 0x1;
|
||||
|
||||
} else if (check_pulse_length(pl, 3 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||
|
||||
// pulse length of 3 indicates listen window -> clear last
|
||||
// bit (= 0) and return
|
||||
return --i;
|
||||
// bit (= 0) and return (without parities)
|
||||
word >>= 2;
|
||||
return (extract_parities(word, data)) ? --cnt : 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -877,14 +841,14 @@ static bool standard_read(int *now) {
|
|||
// (standard read mode); number of read words is saved in <now>
|
||||
|
||||
int fwr = *now;
|
||||
uint8_t bits[EM4X50_TAG_WORD] = {0};
|
||||
uint32_t data = 0x0;
|
||||
|
||||
// start with the identification of two succsessive listening windows
|
||||
if (find_double_listen_window(false)) {
|
||||
|
||||
// read and save words until following double listen window is detected
|
||||
while (get_word_from_bitstream(bits) == EM4X50_TAG_WORD)
|
||||
save_word((*now)++, bits);
|
||||
while (get_word_from_bitstream(&data) == EM4X50_TAG_WORD)
|
||||
em4x50_tag[(*now)++] = data;
|
||||
|
||||
// number of detected words
|
||||
*now -= fwr;
|
||||
|
@ -942,7 +906,6 @@ void em4x50_info(em4x50_data_t *etd) {
|
|||
bool bsuccess = false, blogin = false;
|
||||
uint8_t status = 0;
|
||||
uint8_t addresses[] = {0x00, 0x00, 0x21, 0x00}; // fwr = 0, lwr = 33
|
||||
uint8_t password[] = {0x00, 0x00, 0x00, 0x00}; // default password
|
||||
|
||||
init_tag();
|
||||
em4x50_setup_read();
|
||||
|
@ -955,11 +918,6 @@ void em4x50_info(em4x50_data_t *etd) {
|
|||
// try to login with given password
|
||||
blogin = login(etd->password);
|
||||
|
||||
} else {
|
||||
|
||||
// if no password is given, try to login with "0x00000000"
|
||||
blogin = login(password);
|
||||
|
||||
}
|
||||
|
||||
bsuccess = selective_read(addresses);
|
||||
|
@ -967,8 +925,11 @@ void em4x50_info(em4x50_data_t *etd) {
|
|||
|
||||
status = (bsuccess << 1) + blogin;
|
||||
|
||||
for (int i = 0; i < 34; i++)
|
||||
Dbprintf("em4x5_tag[%i] = %08x", i, em4x50_tag[i]);
|
||||
|
||||
lf_finalize();
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)em4x50_tag, 136);
|
||||
}
|
||||
|
||||
void em4x50_read(em4x50_data_t *etd) {
|
||||
|
@ -1013,7 +974,7 @@ void em4x50_read(em4x50_data_t *etd) {
|
|||
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
lf_finalize();
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)em4x50_tag, 136);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -1102,7 +1063,8 @@ void em4x50_write(em4x50_data_t *etd) {
|
|||
|
||||
bool bsuccess = false, blogin = false;
|
||||
uint8_t status = 0;
|
||||
uint8_t word[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
//uint8_t word[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
uint32_t word = 0x0;
|
||||
uint8_t addresses[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
init_tag();
|
||||
|
@ -1133,15 +1095,27 @@ void em4x50_write(em4x50_data_t *etd) {
|
|||
if (selective_read(addresses)) {
|
||||
|
||||
// compare with given word
|
||||
word = em4x50_tag[etd->address];
|
||||
/*
|
||||
word[0] = tag.sectors[etd->address][0];
|
||||
word[1] = tag.sectors[etd->address][1];
|
||||
word[2] = tag.sectors[etd->address][2];
|
||||
word[3] = tag.sectors[etd->address][3];
|
||||
msb2lsb_word(word);
|
||||
*/
|
||||
reflect32(word);
|
||||
|
||||
bsuccess = true;
|
||||
for (int i = 0; i < 4; i++)
|
||||
bsuccess &= (word[i] == etd->word[i]) ? true : false;
|
||||
//bsuccess = true;
|
||||
//for (int i = 0; i < 4; i++)
|
||||
// bsuccess &= (word[i] == etd->word[i]) ? true : false;
|
||||
uint32_t tmp = 0x0;
|
||||
tmp = etd->word[0];
|
||||
tmp <<= 8;
|
||||
tmp |= etd->word[1];
|
||||
tmp <<= 8;
|
||||
tmp |= etd->word[2];
|
||||
tmp <<= 8;
|
||||
tmp |= etd->word[3];
|
||||
bsuccess = (word == tmp);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1151,7 +1125,7 @@ void em4x50_write(em4x50_data_t *etd) {
|
|||
status = (bsuccess << 1) + blogin;
|
||||
|
||||
lf_finalize();
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
||||
reply_ng(CMD_ACK, status, (uint8_t *)em4x50_tag, 136);
|
||||
}
|
||||
|
||||
void em4x50_write_password(em4x50_data_t *etd) {
|
||||
|
@ -1223,8 +1197,7 @@ void em4x50_wipe(em4x50_data_t *etd) {
|
|||
// check if everything is zero
|
||||
bsuccess = true;
|
||||
for (int i = 1; i <= EM4X50_NO_WORDS - 3; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
bsuccess &= (tag.sectors[i][j] == 0) ? true : false;
|
||||
bsuccess &= (em4x50_tag[i] == 0) ? true : false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1244,7 +1217,7 @@ void em4x50_wipe(em4x50_data_t *etd) {
|
|||
}
|
||||
|
||||
lf_finalize();
|
||||
reply_ng(CMD_ACK, bsuccess, (uint8_t *)tag.sectors, 238);
|
||||
reply_ng(CMD_ACK, bsuccess, (uint8_t *)em4x50_tag, 136);
|
||||
}
|
||||
|
||||
void em4x50_reset(void) {
|
||||
|
@ -1364,49 +1337,33 @@ int em4x50_standalone_brute(uint32_t start, uint32_t stop, uint32_t *pwd) {
|
|||
|
||||
em4x50_setup_read();
|
||||
|
||||
if (get_signalproperties() && find_em4x50_tag()) {
|
||||
if (get_signalproperties() && find_em4x50_tag())
|
||||
status = brute(start, stop, pwd);
|
||||
} else {
|
||||
else
|
||||
status = PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
lf_finalize();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int em4x50_standalone_read(uint64_t *words) {
|
||||
int em4x50_standalone_read(uint32_t *words) {
|
||||
|
||||
int now = 0;
|
||||
uint8_t bits[EM4X50_TAG_WORD];
|
||||
|
||||
em4x50_setup_read();
|
||||
|
||||
if (get_signalproperties() && find_em4x50_tag()) {
|
||||
|
||||
if (find_double_listen_window(false)) {
|
||||
|
||||
memset(bits, 0, sizeof(bits));
|
||||
|
||||
while (get_word_from_bitstream(bits) == EM4X50_TAG_WORD) {
|
||||
words[now] = 0;
|
||||
|
||||
for (int i = 0; i < EM4X50_TAG_WORD; i++) {
|
||||
words[now] <<= 1;
|
||||
words[now] += bits[i] & 1;
|
||||
}
|
||||
|
||||
if (get_signalproperties() && find_em4x50_tag())
|
||||
if (find_double_listen_window(false))
|
||||
while (get_word_from_bitstream(&words[now]) == EM4X50_TAG_WORD)
|
||||
now++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
void em4x50_watch() {
|
||||
|
||||
// reads continuously and displays standard reads of tag
|
||||
// read continuously and display standard reads of tag
|
||||
|
||||
int now = 0;
|
||||
|
||||
|
@ -1429,16 +1386,8 @@ void em4x50_watch() {
|
|||
for (int i = 0; i < now; i++) {
|
||||
|
||||
Dbprintf("EM4x50 TAG ID: "
|
||||
_GREEN_("%02x%02x%02x%02x") " (msb) - "
|
||||
_GREEN_("%02x%02x%02x%02x") " (lsb)",
|
||||
tag.sectors[i][0],
|
||||
tag.sectors[i][1],
|
||||
tag.sectors[i][2],
|
||||
tag.sectors[i][3],
|
||||
reflect8(tag.sectors[i][3]),
|
||||
reflect8(tag.sectors[i][2]),
|
||||
reflect8(tag.sectors[i][1]),
|
||||
reflect8(tag.sectors[i][0]));
|
||||
_GREEN_("%08x") " (msb) - " _GREEN_("%08x") " (lsb)",
|
||||
em4x50_tag[i], reflect32(em4x50_tag[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#include "../include/em4x50.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t sectors[34][7];
|
||||
uint8_t sectors[34][4];
|
||||
} em4x50_tag_t;
|
||||
|
||||
int em4x50_standalone_read(uint64_t *words);
|
||||
int em4x50_standalone_read(uint32_t *words);
|
||||
int em4x50_standalone_brute(uint32_t start, uint32_t stop, uint32_t *pwd);
|
||||
bool em4x50_sim_send_listen_window(void);
|
||||
bool em4x50_sim_send_word(uint32_t word);
|
||||
|
|
|
@ -145,60 +145,13 @@ static int usage_lf_em4x50_watch(void) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void prepare_result(const uint8_t *byte, int fwr, int lwr, em4x50_word_t *words) {
|
||||
static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) {
|
||||
|
||||
// restructure received result in "em4x50_word_t" structure and check all
|
||||
// parities including stop bit; result of each check is stored in structure
|
||||
// restructure received result in "em4x50_word_t" structure
|
||||
|
||||
int p = 0, c[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
for (int i = fwr; i <= lwr; i++) {
|
||||
|
||||
words[i].stopparity = true;
|
||||
words[i].parity = true;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
c[j] = 0;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
words[i].byte[j] = byte[i * 7 + j];
|
||||
words[i].row_parity[j] = (byte[i * 7 + 4] >> (3 - j)) & 1;
|
||||
|
||||
// collect parities
|
||||
p = 0;
|
||||
|
||||
for (int k = 0; k < 8; k++) {
|
||||
|
||||
// row parity
|
||||
p ^= (words[i].byte[j] >> k) & 1;
|
||||
|
||||
// column parity
|
||||
c[k] ^= (words[i].byte[j] >> (7 - k)) & 1;
|
||||
}
|
||||
|
||||
// check row parities
|
||||
words[i].rparity[j] = (words[i].row_parity[j] == p) ? true : false;
|
||||
|
||||
if (!words[i].rparity[j])
|
||||
words[i].parity = false;
|
||||
}
|
||||
|
||||
// check column parities
|
||||
words[i].col_parity = byte[i * 7 + 5];
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
words[i].cparity[j] = (((words[i].col_parity >> (7 - j)) & 1) == c[j]) ? true : false;
|
||||
|
||||
if (!words[i].cparity[j])
|
||||
words[i].parity = false;
|
||||
}
|
||||
|
||||
// check stop bit
|
||||
words[i].stopbit = byte[i * 7 + 6] & 1;
|
||||
|
||||
if (words[i].stopbit == 1)
|
||||
words[i].stopparity = false;
|
||||
}
|
||||
for (int i = fwr; i <= lwr; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
words[i].byte[j] = data[i * 4 + (3 - j)];
|
||||
}
|
||||
|
||||
static void print_result(const em4x50_word_t *words, int fwr, int lwr) {
|
||||
|
|
|
@ -44,11 +44,8 @@ typedef struct {
|
|||
bool addr_given;
|
||||
bool pwd_given;
|
||||
bool newpwd_given;
|
||||
uint8_t carrier;
|
||||
uint8_t byte;
|
||||
uint8_t password[4];
|
||||
uint8_t new_password[4];
|
||||
uint8_t addresses[4];
|
||||
uint8_t address;
|
||||
uint8_t word[4];
|
||||
uint32_t start_password;
|
||||
|
@ -58,13 +55,6 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint8_t byte[4];
|
||||
uint8_t row_parity[4];
|
||||
uint8_t col_parity;
|
||||
uint8_t stopbit;
|
||||
bool rparity[4];
|
||||
bool cparity[8];
|
||||
bool stopparity;
|
||||
bool parity;
|
||||
} em4x50_word_t;
|
||||
|
||||
#endif /* EM4X50_H__ */
|
||||
|
|
Loading…
Reference in a new issue