mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
em4x70: Update receive function with expected bits to receive.
This commit is contained in:
parent
f18a297e41
commit
ff762027d9
1 changed files with 28 additions and 29 deletions
|
@ -42,7 +42,7 @@ static bool command_parity = true;
|
||||||
|
|
||||||
#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this
|
#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this
|
||||||
#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window
|
#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window
|
||||||
|
#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods)
|
||||||
|
|
||||||
#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command
|
#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command
|
||||||
#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command
|
#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command
|
||||||
|
@ -73,7 +73,7 @@ static bool command_parity = true;
|
||||||
|
|
||||||
static uint8_t bits2byte(const uint8_t *bits, int length);
|
static uint8_t bits2byte(const uint8_t *bits, int length);
|
||||||
static void bits2bytes(const uint8_t *bits, int length, uint8_t *out);
|
static void bits2bytes(const uint8_t *bits, int length, uint8_t *out);
|
||||||
static int em4x70_receive(uint8_t *bits);
|
static int em4x70_receive(uint8_t *bits, size_t length);
|
||||||
static bool find_listen_window(bool command);
|
static bool find_listen_window(bool command);
|
||||||
|
|
||||||
static void init_tag(void) {
|
static void init_tag(void) {
|
||||||
|
@ -329,8 +329,8 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon
|
||||||
|
|
||||||
// Receive header, 20-bit g(RN), LIW
|
// Receive header, 20-bit g(RN), LIW
|
||||||
uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
||||||
int num = em4x70_receive(grnd);
|
int num = em4x70_receive(grnd, 20);
|
||||||
if (num < 10) {
|
if (num < 20) {
|
||||||
Dbprintf("Auth failed");
|
Dbprintf("Auth failed");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ static int send_pin(const uint32_t pin) {
|
||||||
WaitTicks(EM4X70_T_TAG_WEE);
|
WaitTicks(EM4X70_T_TAG_WEE);
|
||||||
// <-- Receive header + ID
|
// <-- Receive header + ID
|
||||||
uint8_t tag_id[EM4X70_MAX_RECEIVE_LENGTH];
|
uint8_t tag_id[EM4X70_MAX_RECEIVE_LENGTH];
|
||||||
int num = em4x70_receive(tag_id);
|
int num = em4x70_receive(tag_id, 32);
|
||||||
if (num < 32) {
|
if (num < 32) {
|
||||||
Dbprintf("Invalid ID Received");
|
Dbprintf("Invalid ID Received");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -480,7 +480,7 @@ static uint8_t bits2byte(const uint8_t *bits, int length) {
|
||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_t *out_bytes) {
|
static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length) {
|
||||||
|
|
||||||
int retries = EM4X70_COMMAND_RETRIES;
|
int retries = EM4X70_COMMAND_RETRIES;
|
||||||
while (retries) {
|
while (retries) {
|
||||||
|
@ -488,13 +488,14 @@ static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_
|
||||||
|
|
||||||
if (find_listen_window(true)) {
|
if (find_listen_window(true)) {
|
||||||
uint8_t bits[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
uint8_t bits[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
||||||
|
size_t out_length_bits = length * 8;
|
||||||
em4x70_send_nibble(command, command_parity);
|
em4x70_send_nibble(command, command_parity);
|
||||||
int len = em4x70_receive(bits);
|
int len = em4x70_receive(bits, out_length_bits);
|
||||||
if (len < resp_len_bits) {
|
if (len < out_length_bits) {
|
||||||
Dbprintf("Invalid data received length: %d", len);
|
Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bits2bytes(bits, len, out_bytes);
|
bits2bytes(bits, len, bytes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,7 +511,7 @@ static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_
|
||||||
*/
|
*/
|
||||||
static bool em4x70_read_id(void) {
|
static bool em4x70_read_id(void) {
|
||||||
|
|
||||||
return send_command_and_read(EM4X70_COMMAND_ID, 32, &tag.data[4]);
|
return send_command_and_read(EM4X70_COMMAND_ID, &tag.data[4], 4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +522,7 @@ static bool em4x70_read_id(void) {
|
||||||
*/
|
*/
|
||||||
static bool em4x70_read_um1(void) {
|
static bool em4x70_read_um1(void) {
|
||||||
|
|
||||||
return send_command_and_read(EM4X70_COMMAND_UM1, 32, &tag.data[0]);
|
return send_command_and_read(EM4X70_COMMAND_UM1, &tag.data[0], 4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +534,7 @@ static bool em4x70_read_um1(void) {
|
||||||
*/
|
*/
|
||||||
static bool em4x70_read_um2(void) {
|
static bool em4x70_read_um2(void) {
|
||||||
|
|
||||||
return send_command_and_read(EM4X70_COMMAND_UM2, 64, &tag.data[24]);
|
return send_command_and_read(EM4X70_COMMAND_UM2, &tag.data[24], 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +544,7 @@ static bool find_em4x70_Tag(void) {
|
||||||
return find_listen_window(false);
|
return find_listen_window(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int em4x70_receive(uint8_t *bits) {
|
static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||||
|
|
||||||
uint32_t pl;
|
uint32_t pl;
|
||||||
int bit_pos = 0;
|
int bit_pos = 0;
|
||||||
|
@ -558,10 +559,8 @@ static int em4x70_receive(uint8_t *bits) {
|
||||||
WaitTicks(6 * EM4X70_T_TAG_FULL_PERIOD);
|
WaitTicks(6 * EM4X70_T_TAG_FULL_PERIOD);
|
||||||
|
|
||||||
// wait until we get the transition from 1's to 0's which is 1.5 full windows
|
// wait until we get the transition from 1's to 0's which is 1.5 full windows
|
||||||
int pulse_count = 0;
|
for(int i = 0; i < EM4X70_T_READ_HEADER_LEN; i++) {
|
||||||
while (pulse_count < 12) {
|
|
||||||
pl = get_pulse_length(edge);
|
pl = get_pulse_length(edge);
|
||||||
pulse_count++;
|
|
||||||
if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
|
if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
|
||||||
foundheader = true;
|
foundheader = true;
|
||||||
break;
|
break;
|
||||||
|
@ -575,23 +574,26 @@ static int em4x70_receive(uint8_t *bits) {
|
||||||
|
|
||||||
// Skip next 3 0's, header check consumes the first 0
|
// Skip next 3 0's, header check consumes the first 0
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
get_pulse_length(edge);
|
// If pulse length is not 1 bit, then abort early
|
||||||
|
if(!check_pulse_length(get_pulse_length(edge), EM4X70_T_TAG_FULL_PERIOD)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// identify remaining bits based on pulse lengths
|
// identify remaining bits based on pulse lengths
|
||||||
// between listen windows only pulse lengths of 1, 1.5 and 2 are possible
|
// between listen windows only pulse lengths of 1, 1.5 and 2 are possible
|
||||||
while (bit_pos < EM4X70_MAX_RECEIVE_LENGTH) {
|
while (bit_pos < length) {
|
||||||
|
|
||||||
pl = get_pulse_length(edge);
|
pl = get_pulse_length(edge);
|
||||||
|
|
||||||
if (check_pulse_length(pl, EM4X70_T_TAG_FULL_PERIOD)) {
|
if (check_pulse_length(pl, EM4X70_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
// pulse length = 1
|
// pulse length 1 -> assign bit
|
||||||
bits[bit_pos++] = edge == FALLING_EDGE ? 1 : 0;
|
bits[bit_pos++] = edge == FALLING_EDGE ? 1 : 0;
|
||||||
|
|
||||||
} else if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
|
} else if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
|
||||||
|
|
||||||
// pulse length = 1.5 -> flip edge detection
|
// pulse length 1.5 -> 2 bits + flip edge detection
|
||||||
if (edge == FALLING_EDGE) {
|
if (edge == FALLING_EDGE) {
|
||||||
bits[bit_pos++] = 0;
|
bits[bit_pos++] = 0;
|
||||||
bits[bit_pos++] = 0;
|
bits[bit_pos++] = 0;
|
||||||
|
@ -604,7 +606,7 @@ static int em4x70_receive(uint8_t *bits) {
|
||||||
|
|
||||||
} else if (check_pulse_length(pl, 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
} else if (check_pulse_length(pl, 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
// pulse length of 2
|
// pulse length of 2 -> two bits
|
||||||
if (edge == FALLING_EDGE) {
|
if (edge == FALLING_EDGE) {
|
||||||
bits[bit_pos++] = 0;
|
bits[bit_pos++] = 0;
|
||||||
bits[bit_pos++] = 1;
|
bits[bit_pos++] = 1;
|
||||||
|
@ -613,16 +615,13 @@ static int em4x70_receive(uint8_t *bits) {
|
||||||
bits[bit_pos++] = 0;
|
bits[bit_pos++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (((edge == FALLING_EDGE) && check_pulse_length(pl, (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_FULL_PERIOD)) ||
|
} else {
|
||||||
((edge == RISING_EDGE) && check_pulse_length(pl, (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD))) {
|
// Listen Window, or invalid bit
|
||||||
|
break;
|
||||||
// LIW detected (either invert or normal)
|
|
||||||
return --bit_pos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should not get here
|
return bit_pos;
|
||||||
return --bit_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x70_info(em4x70_data_t *etd) {
|
void em4x70_info(em4x70_data_t *etd) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue