mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge remote-tracking branch 'remotes/origin/master' into standalone-mfc-rewrite
This commit is contained in:
@@ -122,3 +122,7 @@ fpga_version_info.c
|
||||
|
||||
# docs
|
||||
!doc/*.json
|
||||
|
||||
# local codeql
|
||||
_codeql*
|
||||
/codeql
|
||||
+6
-1
@@ -4,7 +4,12 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Changed standalone mode HF_MATTYRUN - support more card sizes, user dictionaries, improved emulation (@michaelroland)
|
||||
- Added AIDs `002000` and `FF30FF` from Metrolinx Presto Card (@RunTheBot)
|
||||
- Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001)
|
||||
- Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd`
|
||||
- Fixed `hf 15 dump` memory leaks (@jlitewski)
|
||||
- Changed `hf search` - topaz is detect before ISO14443a and commented out WIP ICT code path (@iceman1001)
|
||||
- Fixed `hf search` - where felica reader now doesnt timeout and give wrong response (@iceman1001)
|
||||
- Fixed overflow in deps/jansson library (@iceman1001)
|
||||
- Added `lf hitag crack2` - WIP. Trying to add the second attack vector against Hitag2 (@iceman1001)
|
||||
- Changed `hf 14b reader --plot` - made the anticollision signal trace download optional (@iceman1001)
|
||||
- Added `lf_hitag_crypto.trace` - trace file of a complete read out of a Hitag2 in crypto mode (@iceman1001)
|
||||
|
||||
@@ -48,7 +48,6 @@ void RunMod(void) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
const uint32_t high = 0x20; // LF high value is always 0x20 here
|
||||
uint32_t low = 0;
|
||||
|
||||
uint32_t fac = FACILITY_CODE, cardnum = 0;
|
||||
|
||||
@@ -80,7 +79,7 @@ void RunMod(void) {
|
||||
if (BUTTON_HELD(1000) == BUTTON_HOLD) break; // long button press (>=1sec) exit
|
||||
|
||||
// calculate the new LF low value including Card number, Facility code and checksum
|
||||
low = (cardnum << 1) | (fac << 17);
|
||||
uint32_t low = (cardnum << 1) | (fac << 17);
|
||||
low |= oddparity32((low >> 1) & 0xFFF);
|
||||
low |= evenparity32((low >> 13) & 0xFFF) << 25;
|
||||
|
||||
|
||||
+3
-3
@@ -101,9 +101,9 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
||||
d += 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}void print_result(const char *name, const uint8_t *d, size_t
|
||||
|
||||
void print_result(const char *name, const uint8_t *d, size_t n) {
|
||||
n) {
|
||||
|
||||
const uint8_t *p = d;
|
||||
uint16_t tmp = n & 0xFFF0;
|
||||
@@ -129,7 +129,7 @@ void print_result(const char *name, const uint8_t *d, size_t n) {
|
||||
}
|
||||
|
||||
// Prints message and hexdump
|
||||
void print_dbg(char *msg, uint8_t *d, uint16_t n) {
|
||||
void print_dbg(const char *msg, const uint8_t *d, uint16_t n) {
|
||||
if (g_dbglevel == DBG_DEBUG) {
|
||||
print_result(msg, d, n);
|
||||
}
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ void DbpStringEx(uint32_t flags, const char *src, size_t srclen);
|
||||
void Dbprintf(const char *fmt, ...);
|
||||
void DbprintfEx(uint32_t flags, const char *fmt, ...);
|
||||
void Dbhexdump(int len, const uint8_t *d, bool bAsci);
|
||||
void print_result(const char *name, const uint8_t *buf, size_t len);
|
||||
void print_dbg(char *msg, uint8_t *d, uint16_t n);
|
||||
void print_result(const char *name, const uint8_t *d, size_t n);
|
||||
void print_dbg(const char *msg, const uint8_t *d, uint16_t n);
|
||||
//void PrintToSendBuffer(void);
|
||||
|
||||
#endif
|
||||
|
||||
+67
-44
@@ -543,30 +543,35 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
|
||||
|
||||
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) {
|
||||
void *res = data;
|
||||
void *edata = NULL;
|
||||
uint8_t first_cmac_byte = 0x00;
|
||||
|
||||
desfirekey_t key = DESFIRE(tag)->session_key;
|
||||
|
||||
if (!key)
|
||||
if (!key) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Return directly if we just have a status code.
|
||||
if (1 == *nbytes)
|
||||
if (1 == *nbytes) {
|
||||
return res;
|
||||
}
|
||||
|
||||
switch (communication_settings & MDCM_MASK) {
|
||||
case MDCM_PLAIN:
|
||||
case MDCM_PLAIN: {
|
||||
|
||||
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
|
||||
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) {
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
/* pass through */
|
||||
case MDCM_MACED:
|
||||
case MDCM_MACED: {
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
if (communication_settings & MAC_VERIFY) {
|
||||
case AS_LEGACY: {
|
||||
|
||||
if ((communication_settings & MAC_VERIFY) == MAC_VERIFY) {
|
||||
|
||||
*nbytes -= key_macing_length(key);
|
||||
|
||||
if (*nbytes == 0) {
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
@@ -577,18 +582,17 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
}
|
||||
|
||||
size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
|
||||
edata = BigBuf_malloc(edl);
|
||||
|
||||
uint8_t edata[edl];
|
||||
memset(edata, 0, sizeof(edata));
|
||||
memcpy(edata, data, *nbytes - 1);
|
||||
memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
|
||||
|
||||
mifare_cypher_blocks_chained(tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
|
||||
|
||||
if (0 != memcmp((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) {
|
||||
if (0 != memcmp((uint8_t *)data + *nbytes - 1, edata + edl - 8, 4)) {
|
||||
#ifdef WITH_DEBUG
|
||||
Dbprintf("MACing not verified");
|
||||
hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0);
|
||||
hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
||||
hexdump(edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
||||
#endif
|
||||
DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
|
||||
*nbytes = -1;
|
||||
@@ -596,10 +600,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AS_NEW:
|
||||
if (!(communication_settings & CMAC_COMMAND))
|
||||
}
|
||||
case AS_NEW: {
|
||||
|
||||
if ((communication_settings & CMAC_COMMAND) != CMAC_COMMAND) {
|
||||
break;
|
||||
if (communication_settings & CMAC_VERIFY) {
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) {
|
||||
if (*nbytes < 9) {
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
@@ -607,13 +617,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
}
|
||||
first_cmac_byte = ((uint8_t *)data)[*nbytes - 9];
|
||||
((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes - 1];
|
||||
|
||||
n = 8;
|
||||
}
|
||||
|
||||
int n = (communication_settings & CMAC_VERIFY) ? 8 : 0;
|
||||
cmac(key, DESFIRE(tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE(tag)->cmac);
|
||||
|
||||
if (communication_settings & CMAC_VERIFY) {
|
||||
if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) {
|
||||
|
||||
((uint8_t *)data)[*nbytes - 9] = first_cmac_byte;
|
||||
|
||||
if (0 != memcmp(DESFIRE(tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) {
|
||||
#ifdef WITH_DEBUG
|
||||
Dbprintf("CMAC NOT verified :-(");
|
||||
@@ -628,12 +641,11 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(edata);
|
||||
|
||||
break;
|
||||
case MDCM_ENCIPHERED:
|
||||
}
|
||||
case MDCM_ENCIPHERED: {
|
||||
(*nbytes)--;
|
||||
bool verified = false;
|
||||
int crc_pos = 0x00;
|
||||
@@ -670,48 +682,50 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
* verified, and accumulating 0's in it should not change it.
|
||||
*/
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
|
||||
if (crc_pos < 0) {
|
||||
/* Single block */
|
||||
crc_pos = 0;
|
||||
crc_pos = 0; // Single block
|
||||
}
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
/* Move status between payload and CRC */
|
||||
res = DESFIRE(tag)->crypto_buffer;
|
||||
memcpy(res, data, *nbytes);
|
||||
|
||||
crc_pos = (*nbytes) - 16 - 3;
|
||||
if (crc_pos < 0) {
|
||||
/* Single block */
|
||||
crc_pos = 0;
|
||||
crc_pos = 0; // Single block
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos);
|
||||
((uint8_t *)res)[crc_pos] = 0x00;
|
||||
crc_pos++;
|
||||
*nbytes += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
uint16_t crc_16 = 0x00;
|
||||
uint32_t crc = 0x00;
|
||||
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
AddCrc14A((uint8_t *)res, end_crc_pos);
|
||||
end_crc_pos = crc_pos + 2;
|
||||
//
|
||||
|
||||
|
||||
crc = crc_16;
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
end_crc_pos = crc_pos + 4;
|
||||
crc32_ex(res, end_crc_pos, (uint8_t *)&crc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!crc) {
|
||||
|
||||
if (crc == 0) {
|
||||
verified = true;
|
||||
for (int n = end_crc_pos; n < *nbytes - 1; n++) {
|
||||
uint8_t byte = ((uint8_t *)res)[n];
|
||||
@@ -719,31 +733,40 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
verified = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (verified) {
|
||||
|
||||
*nbytes = crc_pos;
|
||||
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
((uint8_t *)data)[(*nbytes)++] = 0x00;
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
/* The status byte was already before the CRC */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
x = ((uint8_t *)res)[crc_pos - 1];
|
||||
((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos];
|
||||
((uint8_t *)res)[crc_pos] = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
crc_pos++;
|
||||
}
|
||||
} while (!verified && (end_crc_pos < *nbytes));
|
||||
|
||||
if (!verified) {
|
||||
} while (verified == false && (end_crc_pos < *nbytes));
|
||||
|
||||
if (verified == false) {
|
||||
#ifdef WITH_DEBUG
|
||||
/* FIXME In some configurations, the file is transmitted PLAIN */
|
||||
Dbprintf("CRC not verified in decyphered stream");
|
||||
@@ -752,14 +775,14 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default: {
|
||||
Dbprintf("Unknown communication settings");
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
+5
-1
@@ -1255,7 +1255,11 @@ static int em4x50_sim_read_bit(void) {
|
||||
int cycles = 0;
|
||||
int timeout = EM4X50_T_SIMULATION_TIMEOUT_READ;
|
||||
|
||||
while (cycles < EM4X50_T_TAG_FULL_PERIOD) {
|
||||
// wait 16 cycles to make sure there is no field when reading a "0" bit
|
||||
uint32_t waitval = GetTicks();
|
||||
while(GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS);
|
||||
|
||||
while (cycles < EM4X50_T_TAG_THREE_QUARTER_PERIOD) {
|
||||
|
||||
// wait until reader field disappears
|
||||
while ((timeout--) && !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK));
|
||||
|
||||
+79
-65
@@ -30,43 +30,50 @@ static em4x70_tag_t tag = { 0 };
|
||||
// EM4170 requires a parity bit on commands, other variants do not.
|
||||
static bool command_parity = true;
|
||||
|
||||
// Conversion from Ticks to RF periods
|
||||
// 1 us = 1.5 ticks
|
||||
// 1RF Period = 8us = 12 Ticks
|
||||
#define TICKS_PER_FC 12
|
||||
|
||||
// Chip timing from datasheet
|
||||
// Converted into Ticks for timing functions
|
||||
#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period
|
||||
#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time
|
||||
#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time
|
||||
#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time
|
||||
#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time
|
||||
#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits
|
||||
#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0
|
||||
#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW
|
||||
#if 1 // Calculation of ticks for timing functions
|
||||
// Conversion from Ticks to RF periods
|
||||
// 1 us = 1.5 ticks
|
||||
// 1RF Period = 8us = 12 Ticks
|
||||
#define TICKS_PER_FC 12
|
||||
|
||||
#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_READ_HEADER_LEN 16 // Read header length (16 bit periods)
|
||||
// Chip timing from datasheet
|
||||
// Converted into Ticks for timing functions
|
||||
#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period
|
||||
#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time
|
||||
#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time
|
||||
#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time
|
||||
#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time
|
||||
#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits
|
||||
#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0
|
||||
#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW
|
||||
|
||||
#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_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_READ_HEADER_LEN 16 // Read header length (16 bit periods)
|
||||
|
||||
/**
|
||||
* These IDs are from the EM4170 datasheet
|
||||
* Some versions of the chip require a
|
||||
* (even) parity bit, others do not
|
||||
*/
|
||||
#define EM4X70_COMMAND_ID 0x01
|
||||
#define EM4X70_COMMAND_UM1 0x02
|
||||
#define EM4X70_COMMAND_AUTH 0x03
|
||||
#define EM4X70_COMMAND_PIN 0x04
|
||||
#define EM4X70_COMMAND_WRITE 0x05
|
||||
#define EM4X70_COMMAND_UM2 0x07
|
||||
#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command
|
||||
#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command
|
||||
#endif // Calculation of ticks for timing functions
|
||||
|
||||
#if 1 // EM4x70 Command IDs
|
||||
/**
|
||||
* These IDs are from the EM4170 datasheet.
|
||||
* Some versions of the chip require a
|
||||
* (even) parity bit, others do not.
|
||||
* The command is thus stored only in the
|
||||
* three least significant bits (mask 0x07).
|
||||
*/
|
||||
#define EM4X70_COMMAND_ID 0x01
|
||||
#define EM4X70_COMMAND_UM1 0x02
|
||||
#define EM4X70_COMMAND_AUTH 0x03
|
||||
#define EM4X70_COMMAND_PIN 0x04
|
||||
#define EM4X70_COMMAND_WRITE 0x05
|
||||
#define EM4X70_COMMAND_UM2 0x07
|
||||
#endif // EM4x70 Command IDs
|
||||
|
||||
// Constants used to determine high/low state of signal
|
||||
#define EM4X70_NOISE_THRESHOLD 13 // May depend on noise in environment
|
||||
@@ -80,9 +87,9 @@ static bool command_parity = true;
|
||||
#define IS_TIMEOUT(timeout_ticks) (GetTicks() > timeout_ticks)
|
||||
#define TICKS_ELAPSED(start_ticks) (GetTicks() - start_ticks)
|
||||
|
||||
static uint8_t bits2byte(const uint8_t *bits, int length);
|
||||
static void bits2bytes(const uint8_t *bits, int length, uint8_t *out);
|
||||
static int em4x70_receive(uint8_t *bits, size_t length);
|
||||
static uint8_t encoded_bit_array_to_byte(const uint8_t *bits, int count_of_bits);
|
||||
static void encoded_bit_array_to_bytes(const uint8_t *bits, int count_of_bits, uint8_t *out);
|
||||
static int em4x70_receive(uint8_t *bits, size_t maximum_bits_to_read);
|
||||
static bool find_listen_window(bool command);
|
||||
|
||||
static void init_tag(void) {
|
||||
@@ -207,9 +214,10 @@ static uint32_t get_pulse_length(edge_detection_t edge) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool check_pulse_length(uint32_t pl, uint32_t length) {
|
||||
// check if pulse length <pl> corresponds to given length <length>
|
||||
return ((pl >= (length - EM4X70_T_TAG_TOLERANCE)) && (pl <= (length + EM4X70_T_TAG_TOLERANCE)));
|
||||
static bool check_pulse_length(uint32_t pulse_tick_length, uint32_t target_tick_length) {
|
||||
// check if pulse tick length corresponds to target length (+/- tolerance)
|
||||
return ((pulse_tick_length >= (target_tick_length - EM4X70_T_TAG_TOLERANCE)) &&
|
||||
(pulse_tick_length <= (target_tick_length + EM4X70_T_TAG_TOLERANCE)));
|
||||
}
|
||||
|
||||
static void em4x70_send_bit(bool bit) {
|
||||
@@ -301,7 +309,7 @@ static bool check_ack(void) {
|
||||
// ACK 64 + 64
|
||||
// NAK 64 + 48
|
||||
if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) &&
|
||||
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||
// ACK
|
||||
return true;
|
||||
}
|
||||
@@ -344,7 +352,11 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon
|
||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Auth failed");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
bits2bytes(grnd, 24, response);
|
||||
// although only received 20 bits
|
||||
// ask for 24 bits converted because
|
||||
// this utility function requires
|
||||
// decoding in multiples of 8 bits
|
||||
encoded_bit_array_to_bytes(grnd, 24, response);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -455,12 +467,12 @@ static int send_pin(const uint32_t pin) {
|
||||
WaitTicks(EM4X70_T_TAG_WEE);
|
||||
// <-- Receive header + ID
|
||||
uint8_t tag_id[EM4X70_MAX_RECEIVE_LENGTH];
|
||||
int num = em4x70_receive(tag_id, 32);
|
||||
if (num < 32) {
|
||||
int count_of_bits_received = em4x70_receive(tag_id, 32);
|
||||
if (count_of_bits_received < 32) {
|
||||
Dbprintf("Invalid ID Received");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
bits2bytes(tag_id, num, &tag.data[4]);
|
||||
encoded_bit_array_to_bytes(tag_id, count_of_bits_received, &tag.data[4]);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -537,36 +549,38 @@ static bool find_listen_window(bool command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bits2bytes(const uint8_t *bits, int length, uint8_t *out) {
|
||||
// *bits == array of bytes, each byte storing a single bit.
|
||||
// *out == array of bytes, storing converted bits --> bytes.
|
||||
//
|
||||
// [in, bcount(count_of_bits) ] const uint8_t *bits
|
||||
// [out, bcount(count_of_bits/8)] uint8_t *out
|
||||
static void encoded_bit_array_to_bytes(const uint8_t *bits, int count_of_bits, uint8_t *out) {
|
||||
|
||||
if (length % 8 != 0) {
|
||||
Dbprintf("Should have a multiple of 8 bits, was sent %d", length);
|
||||
if (count_of_bits % 8 != 0) {
|
||||
Dbprintf("Should have a multiple of 8 bits, was sent %d", count_of_bits);
|
||||
}
|
||||
|
||||
int num_bytes = length / 8; // We should have a multiple of 8 here
|
||||
int num_bytes = count_of_bits / 8; // We should have a multiple of 8 here
|
||||
|
||||
for (int i = 1; i <= num_bytes; i++) {
|
||||
out[num_bytes - i] = bits2byte(bits, 8);
|
||||
out[num_bytes - i] = encoded_bit_array_to_byte(bits, 8);
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t bits2byte(const uint8_t *bits, int length) {
|
||||
static uint8_t encoded_bit_array_to_byte(const uint8_t *bits, int count_of_bits) {
|
||||
|
||||
// converts <length> separate bits into a single "byte"
|
||||
// converts <count_of_bits> separate bits into a single "byte"
|
||||
uint8_t byte = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
for (int i = 0; i < count_of_bits; i++) {
|
||||
byte <<= 1;
|
||||
byte |= bits[i];
|
||||
|
||||
if (i != length - 1)
|
||||
byte <<= 1;
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length) {
|
||||
static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t expected_byte_count) {
|
||||
|
||||
int retries = EM4X70_COMMAND_RETRIES;
|
||||
while (retries) {
|
||||
@@ -574,14 +588,14 @@ static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length
|
||||
|
||||
if (find_listen_window(true)) {
|
||||
uint8_t bits[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
||||
size_t out_length_bits = length * 8;
|
||||
size_t out_length_bits = expected_byte_count * 8;
|
||||
em4x70_send_nibble(command, command_parity);
|
||||
int len = em4x70_receive(bits, out_length_bits);
|
||||
if (len < out_length_bits) {
|
||||
Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits);
|
||||
return false;
|
||||
}
|
||||
bits2bytes(bits, len, bytes);
|
||||
encoded_bit_array_to_bytes(bits, len, bytes);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -629,7 +643,7 @@ static bool find_em4x70_tag(void) {
|
||||
return find_listen_window(false);
|
||||
}
|
||||
|
||||
static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||
static int em4x70_receive(uint8_t *bits, size_t maximum_bits_to_read) {
|
||||
|
||||
uint32_t pl;
|
||||
int bit_pos = 0;
|
||||
@@ -667,7 +681,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||
|
||||
// identify remaining bits based on pulse lengths
|
||||
// between listen windows only pulse lengths of 1, 1.5 and 2 are possible
|
||||
while (bit_pos < length) {
|
||||
while (bit_pos < maximum_bits_to_read) {
|
||||
|
||||
pl = get_pulse_length(edge);
|
||||
|
||||
@@ -681,13 +695,13 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||
// pulse length 1.5 -> 2 bits + flip edge detection
|
||||
if (edge == FALLING_EDGE) {
|
||||
bits[bit_pos++] = 0;
|
||||
if (bit_pos < length) {
|
||||
if (bit_pos < maximum_bits_to_read) {
|
||||
bits[bit_pos++] = 0;
|
||||
}
|
||||
edge = RISING_EDGE;
|
||||
} else {
|
||||
bits[bit_pos++] = 1;
|
||||
if (bit_pos < length) {
|
||||
if (bit_pos < maximum_bits_to_read) {
|
||||
bits[bit_pos++] = 1;
|
||||
}
|
||||
edge = FALLING_EDGE;
|
||||
@@ -698,12 +712,12 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||
// pulse length of 2 -> two bits
|
||||
if (edge == FALLING_EDGE) {
|
||||
bits[bit_pos++] = 0;
|
||||
if (bit_pos < length) {
|
||||
if (bit_pos < maximum_bits_to_read) {
|
||||
bits[bit_pos++] = 1;
|
||||
}
|
||||
} else {
|
||||
bits[bit_pos++] = 1;
|
||||
if (bit_pos < length) {
|
||||
if (bit_pos < maximum_bits_to_read) {
|
||||
bits[bit_pos++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -239,7 +239,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||
|
||||
|
||||
// We try 10 times, or if answer was received.
|
||||
int len = 50;
|
||||
int len = 25;
|
||||
do {
|
||||
// end-of-reception response packet data, wait approx. 501μs
|
||||
// end-of-transmission command packet data, wait approx. 197μs
|
||||
@@ -290,7 +290,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
||||
}
|
||||
}
|
||||
// 0. OK
|
||||
// 0. OK
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -544,16 +544,13 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||
|
||||
felica_command_t param = c->oldarg[0];
|
||||
size_t len = c->oldarg[1] & 0xffff;
|
||||
const uint8_t *cmd = c->data.asBytes;
|
||||
uint32_t arg0;
|
||||
|
||||
felica_card_select_t card;
|
||||
|
||||
if ((param & FELICA_CONNECT) == FELICA_CONNECT) {
|
||||
clear_trace();
|
||||
}
|
||||
|
||||
set_tracing(true);
|
||||
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
if ((param & FELICA_CONNECT) == FELICA_CONNECT) {
|
||||
@@ -562,6 +559,7 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||
// if failed selecting, turn off antenna and quite.
|
||||
if ((param & FELICA_NO_SELECT) != FELICA_NO_SELECT) {
|
||||
|
||||
felica_card_select_t card;
|
||||
arg0 = felica_select_card(&card);
|
||||
reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
|
||||
if (arg0) {
|
||||
@@ -582,7 +580,7 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||
buf[2] = len;
|
||||
|
||||
// copy command
|
||||
memcpy(buf + 2, cmd, len);
|
||||
memcpy(buf + 2, c->data.asBytes, len);
|
||||
|
||||
if ((param & FELICA_APPEND_CRC) == FELICA_APPEND_CRC) {
|
||||
// Don't append crc on empty bytearray...
|
||||
@@ -590,7 +588,7 @@ void felica_sendraw(const PacketCommandNG *c) {
|
||||
AddCrc(buf + 2, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
Dbprintf("Transmit Frame (no CRC shown):");
|
||||
Dbhexdump(len, buf, 0);
|
||||
@@ -631,7 +629,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
|
||||
int remFrames = (samplesToSkip) ? samplesToSkip : 0;
|
||||
int trigger_cnt = 0;
|
||||
uint32_t timeout = iso18092_get_timeout();
|
||||
bool isReaderFrame = true;
|
||||
bool isReaderFrame;
|
||||
|
||||
uint8_t flip = 0;
|
||||
uint16_t checker = 0;
|
||||
@@ -734,7 +732,7 @@ void felica_sim_lite(const uint8_t *uid) {
|
||||
|
||||
int retval = PM3_SUCCESS;
|
||||
int curlen = 0;
|
||||
uint8_t *curresp = NULL;
|
||||
const uint8_t *curresp = NULL;
|
||||
bool listenmode = true;
|
||||
// uint32_t frtm = GetCountSspClk();
|
||||
|
||||
@@ -884,7 +882,7 @@ void felica_dump_lite_s(void) {
|
||||
|
||||
dest[cnt++] = liteblks[blknum];
|
||||
|
||||
uint8_t *fb = FelicaFrame.framebytes;
|
||||
const uint8_t *fb = FelicaFrame.framebytes;
|
||||
dest[cnt++] = fb[12];
|
||||
dest[cnt++] = fb[13];
|
||||
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
#define DBG if (g_dbglevel >= DBG_EXTENDED)
|
||||
|
||||
#include "hitag2.h"
|
||||
#include "hitag2_crypto.h"
|
||||
#include "hitag2/hitag2_crypto.h"
|
||||
#include "string.h"
|
||||
#include "proxmark3_arm.h"
|
||||
#include "cmd.h"
|
||||
@@ -2718,7 +2718,7 @@ int ht2_tx_rx(uint8_t *tx, size_t txlen, uint8_t *rx, size_t *rxlen, bool ledcon
|
||||
|
||||
res = PM3_SUCCESS;
|
||||
|
||||
out:
|
||||
out:
|
||||
if (keep_field_up == false) {
|
||||
lf_finalize(false);
|
||||
}
|
||||
|
||||
+30
-30
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
#include "hitag2_crack.h"
|
||||
#include "hitag2_crypto.h"
|
||||
#include "hitag2/hitag2_crypto.h"
|
||||
#include "hitag2.h"
|
||||
#include "proxmark3_arm.h"
|
||||
#include "commonutil.h"
|
||||
@@ -168,7 +168,7 @@ static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e
|
||||
// send extended encrypted cmd
|
||||
uint8_t resp[4] = {0};
|
||||
if (hitag2crack_send_e_cmd(resp, nrar, e_ext_cmd, 40)) {
|
||||
|
||||
|
||||
// test if it was valid
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4)) {
|
||||
return true;
|
||||
@@ -324,10 +324,10 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks
|
||||
DbpString("ht2crack_consume_keystream: conlen < 10");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// calculate how many repeated commands to send in this extended command.
|
||||
int numcmds = conlen / 10;
|
||||
|
||||
|
||||
// xor extended cmd with keybits
|
||||
hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + *ksoffset, (numcmds * 10));
|
||||
|
||||
@@ -338,7 +338,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks
|
||||
Dbprintf("ht2crack_consume_keystream: tx/rx cmd failed, got %zu", n);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// test response
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4) == 0) {
|
||||
DbpString("ht2crack_consume_keystream: got error response from card");
|
||||
@@ -346,7 +346,7 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks
|
||||
}
|
||||
|
||||
// dont bother decrypting the response - we already know the keybits
|
||||
|
||||
|
||||
// update ksoffset with command length and response
|
||||
*ksoffset += (numcmds * 10) + 32;
|
||||
|
||||
@@ -363,14 +363,14 @@ static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ks
|
||||
//static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) {
|
||||
/*
|
||||
static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) {
|
||||
|
||||
|
||||
// calc number of command iterations to send
|
||||
int cmdlen = *kslen - ksoffset;
|
||||
if (cmdlen < 10) {
|
||||
DbpString("extend_keystream: cmdlen < 10");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int numcmds = cmdlen / 10;
|
||||
|
||||
// xor extended cmd with keybits
|
||||
@@ -388,7 +388,7 @@ static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int kso
|
||||
// test response
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// convert response to binarray
|
||||
uint8_t e_response[32];
|
||||
@@ -399,7 +399,7 @@ static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int kso
|
||||
|
||||
// update kslen
|
||||
*kslen = ksoffset + (numcmds * 10) + 32;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
@@ -469,8 +469,8 @@ out:
|
||||
void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
|
||||
lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t*)BigBuf_calloc(sizeof(lf_hitag_crack2_t));
|
||||
lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t*)BigBuf_calloc(sizeof(lf_hitag_crack_response_t));
|
||||
lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t *)BigBuf_calloc(sizeof(lf_hitag_crack2_t));
|
||||
lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t));
|
||||
|
||||
g_logging = false;
|
||||
LEDsoff();
|
||||
@@ -537,7 +537,7 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
}
|
||||
|
||||
// while we have at least 52 bits of keystream, consume it with
|
||||
// extended read page 0 commands.
|
||||
// extended read page 0 commands.
|
||||
// 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send)
|
||||
/*
|
||||
while ((kslen - ksoffset) >= 52) {
|
||||
@@ -549,7 +549,7 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
// send an extended command to retrieve more keystream,
|
||||
// send an extended command to retrieve more keystream,
|
||||
// updating kslen as we go
|
||||
if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) {
|
||||
DbpString("ht2crack_extend_keystream failed");
|
||||
@@ -576,7 +576,7 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
// convert response to binarray
|
||||
uint8_t e_response[32];
|
||||
hex2binarray((char*)e_response, (char*)resp);
|
||||
hex2binarray((char *)e_response, (char *)resp);
|
||||
|
||||
// recover keystream from encrypted response
|
||||
hitag2crack_xor(c2->keybits + kslen + 40, e_response, c2->uid, 32);
|
||||
@@ -587,13 +587,13 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen);
|
||||
}
|
||||
|
||||
/*
|
||||
uint8_t *keybitshex = BigBuf_calloc(64);
|
||||
for (int i = 0; i < 2048; i += 256) {
|
||||
binarray2hex(c2->keybits + i, 256, keybitshex);
|
||||
Dbhexdump(256, keybitshex, false);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
uint8_t *keybitshex = BigBuf_calloc(64);
|
||||
for (int i = 0; i < 2048; i += 256) {
|
||||
binarray2hex(c2->keybits + i, 256, keybitshex);
|
||||
Dbhexdump(256, keybitshex, false);
|
||||
}
|
||||
*/
|
||||
BigBuf_free();
|
||||
|
||||
// copy UID since we already have it...
|
||||
@@ -602,14 +602,14 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
out:
|
||||
|
||||
/*
|
||||
DbpString("keybits:");
|
||||
Dbhexdump(2080, c2->keybits, false);
|
||||
DbpString("uid:");
|
||||
Dbhexdump(32, c2->uid, false);
|
||||
DbpString("nrar:");
|
||||
Dbhexdump(64, c2->nrar, false);
|
||||
*/
|
||||
/*
|
||||
DbpString("keybits:");
|
||||
Dbhexdump(2080, c2->keybits, false);
|
||||
DbpString("uid:");
|
||||
Dbhexdump(32, c2->uid, false);
|
||||
DbpString("nrar:");
|
||||
Dbhexdump(64, c2->nrar, false);
|
||||
*/
|
||||
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t));
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,7 +29,7 @@
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "commonutil.h"
|
||||
#include "hitag2_crypto.h"
|
||||
#include "hitag2/hitag2_crypto.h"
|
||||
#include "lfadc.h"
|
||||
#include "crc.h"
|
||||
|
||||
@@ -1090,7 +1090,7 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||
// Dbprintf("RX0 %i:%02X.. err:%i resptime:%i", *rxlen, rx[0], errorCount, *resptime);
|
||||
}
|
||||
|
||||
static void sendReceiveHitagS(uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) {
|
||||
static void sendReceiveHitagS( const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) {
|
||||
|
||||
LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true);
|
||||
|
||||
@@ -1557,7 +1557,7 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
|
||||
break;
|
||||
default: {
|
||||
res = PM3_EINVARG;
|
||||
return;
|
||||
goto write_end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -764,7 +764,7 @@ bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait) {
|
||||
break;
|
||||
} else if (len == 1) {
|
||||
continue;
|
||||
} else if (len <= 0) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -937,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
||||
|
||||
bool isOK = true;
|
||||
uint16_t length = arg0, pos = 0;
|
||||
uint8_t *fwdata = BigBuf_get_addr();
|
||||
const uint8_t *fwdata = BigBuf_get_addr();
|
||||
uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE);
|
||||
|
||||
while (length) {
|
||||
|
||||
+1
-1
@@ -68,6 +68,6 @@ void SmartCardUpgrade(uint64_t arg0);
|
||||
void SmartCardSetBaud(uint64_t arg0);
|
||||
void SmartCardSetClock(uint64_t arg0);
|
||||
void I2C_print_status(void);
|
||||
int I2C_get_version(uint8_t *maj, uint8_t *min);
|
||||
int I2C_get_version(uint8_t *major, uint8_t *minor);
|
||||
|
||||
#endif
|
||||
|
||||
+5
-5
@@ -774,7 +774,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||
int cardSTATE = SIM_NOFIELD;
|
||||
int vHf = 0; // in mV
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
|
||||
@@ -1566,7 +1566,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len, bool framing) {
|
||||
* Convenience function to encode, transmit and trace iso 14443b comms
|
||||
*/
|
||||
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) {
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
CodeIso14443bAsReader(cmd, len, framing);
|
||||
TransmitFor14443b_AsReader(start_time);
|
||||
if (g_trigger) LED_A_ON();
|
||||
@@ -1582,7 +1582,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t
|
||||
/* Sends an APDU to the tag
|
||||
* TODO: check CRC and preamble
|
||||
*/
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *reponselen) {
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *responselen) {
|
||||
|
||||
uint8_t real_cmd[msg_len + 4];
|
||||
|
||||
@@ -1693,8 +1693,8 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
|
||||
}
|
||||
}
|
||||
|
||||
if (reponselen) {
|
||||
*reponselen = len;
|
||||
if (responselen) {
|
||||
*responselen = len;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
void iso14443b_setup(void);
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res, uint16_t *responselen);
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *responselen);
|
||||
|
||||
int iso14443b_select_card(iso14b_card_select_t *card);
|
||||
|
||||
|
||||
+14
-14
@@ -1009,7 +1009,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||
}
|
||||
|
||||
uint32_t dma_start_time = 0;
|
||||
uint16_t *upTo = dma->buf;
|
||||
const uint16_t *upTo = dma->buf;
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -1502,7 +1502,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting");
|
||||
return -4;
|
||||
}
|
||||
uint8_t *upTo = dma->buf;
|
||||
const uint8_t *upTo = dma->buf;
|
||||
|
||||
uint32_t dma_start_time = GetCountSspClk() & 0xfffffff8;
|
||||
|
||||
@@ -1603,7 +1603,7 @@ void AcquireRawAdcSamplesIso15693(void) {
|
||||
SpinDelay(250);
|
||||
|
||||
// Now send the command
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
|
||||
uint32_t start_time = 0;
|
||||
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
|
||||
@@ -1681,7 +1681,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla
|
||||
// Count of samples received so far, so that we can include timing
|
||||
int samples = 0;
|
||||
|
||||
uint16_t *upTo = dma->buf;
|
||||
const uint16_t *upTo = dma->buf;
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -1902,7 +1902,7 @@ static void BuildIdentifyRequest(uint8_t *cmd) {
|
||||
// If you do not need the answer use NULL for *recv[]
|
||||
// return: length of received data
|
||||
// logging enabled
|
||||
int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv,
|
||||
int SendDataTag(const uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv,
|
||||
uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, uint16_t *resp_len) {
|
||||
|
||||
if (init) {
|
||||
@@ -1918,7 +1918,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
|
||||
CodeIso15693AsReader256(send, sendlen);
|
||||
}
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
@@ -1941,7 +1941,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
|
||||
int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len) {
|
||||
|
||||
CodeIso15693AsReaderEOF();
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
|
||||
uint32_t end_time = start_time + 32 * (8 * ts->max - 4); // subtract the 4 padding bits after EOF
|
||||
LogTrace_ISO15693(NULL, 0, (start_time * 4), (end_time * 4), NULL, true);
|
||||
@@ -1959,9 +1959,9 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
|
||||
|
||||
// Decodes a message from a tag and displays its metadata and content
|
||||
#define DBD15STATLEN 48
|
||||
static void DbdecodeIso15693Answer(int len, uint8_t *d) {
|
||||
static void DbdecodeIso15693Answer(int n, const uint8_t *d) {
|
||||
|
||||
if (len > 3) {
|
||||
if (n > 3) {
|
||||
|
||||
char status[DBD15STATLEN + 1] = {0};
|
||||
|
||||
@@ -2007,7 +2007,7 @@ static void DbdecodeIso15693Answer(int len, uint8_t *d) {
|
||||
strncat(status, "No error ", DBD15STATLEN - strlen(status));
|
||||
}
|
||||
|
||||
if (CheckCrc15(d, len))
|
||||
if (CheckCrc15(d, n))
|
||||
strncat(status, "[+] crc ( " _GREEN_("ok") " )", DBD15STATLEN - strlen(status));
|
||||
else
|
||||
strncat(status, "[!] crc ( " _RED_("fail") " )", DBD15STATLEN - strlen(status));
|
||||
@@ -2127,7 +2127,7 @@ void EmlClearIso15693(void) {
|
||||
|
||||
// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
|
||||
// all demodulation performed in arm rather than host. - greg
|
||||
void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
||||
void SimTagIso15693(const uint8_t *uid, uint8_t block_size) {
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free_keep_EM();
|
||||
@@ -2581,7 +2581,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
||||
AddCrc15(recv, recvLen);
|
||||
recvLen += 2;
|
||||
CodeIso15693AsTag(recv, recvLen);
|
||||
tosend_t *ts = get_tosend();
|
||||
const tosend_t *ts = get_tosend();
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
if (tag->expectFsk) { // Not suppoted yet
|
||||
@@ -3028,7 +3028,7 @@ static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_ti
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, uint8_t *uid) {
|
||||
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) {
|
||||
|
||||
|
||||
uint8_t rnd[2];
|
||||
@@ -3141,7 +3141,7 @@ static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, c
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, const uint8_t *password, uint8_t *uid) {
|
||||
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, const uint8_t *password, const uint8_t *uid) {
|
||||
|
||||
uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
+3
-3
@@ -47,13 +47,13 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||
void AcquireRawAdcSamplesIso15693(void);
|
||||
void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader
|
||||
void EmlClearIso15693(void);
|
||||
void SimTagIso15693(uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag
|
||||
void SimTagIso15693(const uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag
|
||||
void BruteforceIso15693Afi(uint32_t flags); // find an AFI of a tag
|
||||
void SendRawCommand15693(iso15_raw_cmd_t *packet); // send arbitrary commands from CLI
|
||||
|
||||
void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool iclass);
|
||||
|
||||
int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv,
|
||||
int SendDataTag(const uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv,
|
||||
uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, uint16_t *resp_len);
|
||||
|
||||
int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len);
|
||||
@@ -68,5 +68,5 @@ void DisableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd);
|
||||
void EnableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd);
|
||||
void PassProtextEASSlixIso15693(const uint8_t *password);
|
||||
void PassProtectAFISlixIso15693(const uint8_t *password);
|
||||
void WriteAFIIso15693(const uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
||||
void WriteAFIIso15693(const uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
||||
#endif
|
||||
|
||||
+6
-2
@@ -518,7 +518,7 @@ int ReadLF_realtime(bool reader_field) {
|
||||
// Request USB transmission and change FIFO bank
|
||||
if (async_usb_write_requestWrite() == false) {
|
||||
return_value = PM3_EIO;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Reset sample
|
||||
@@ -535,10 +535,14 @@ int ReadLF_realtime(bool reader_field) {
|
||||
}
|
||||
}
|
||||
}
|
||||
LED_D_OFF();
|
||||
|
||||
return_value = async_usb_write_stop();
|
||||
|
||||
out:
|
||||
LED_D_OFF();
|
||||
|
||||
// DoAcquisition() end
|
||||
|
||||
StopTicks();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return return_value;
|
||||
|
||||
@@ -153,7 +153,7 @@ Definition 14. Define the rotate key function rk : (F 82 ) 8 × N → (F 82 ) 8
|
||||
rk(x [0] . . . x [7] , 0) = x [0] . . . x [7]
|
||||
rk(x [0] . . . x [7] , n + 1) = rk(rl(x [0] ) . . . rl(x [7] ), n)
|
||||
**/
|
||||
static void rk(uint8_t *key, uint8_t n, uint8_t *outp_key) {
|
||||
static void rk(const uint8_t *key, uint8_t n, uint8_t *outp_key) {
|
||||
memcpy(outp_key, key, 8);
|
||||
uint8_t j;
|
||||
while (n-- > 0) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user