mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
+8
-1
@@ -3,10 +3,17 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Changed `hf iclass dump` - now uses default AA1 key when called without a key or key index (@iceman1001)
|
||||
- Renamed `hf iclass trbl` to `hf iclass tear` (@iceman1001)
|
||||
- Changed `hw tearoff` - the device side message is now debug log controlled (@iceman1001)
|
||||
- Changed `pm3.sh` - Serial ports enumeration on Proxspace3.xx / MINGW environments, now using powershell.exe since wmic is deprecated (@iceman1001)
|
||||
- Fixed and updated `hf iclass trbl` to correctly use the credit key when passed and show partial tearoff results (@antiklesys)
|
||||
- Fixed `hf iclass legbrute` was not correctly parsin the index value
|
||||
- Fixed `hf mf ekeyprn` - failed to download emulator memory due to wrong size calculation (@iceman1001)
|
||||
- Fixed `hf mf fchk --mem` to actually use flash dict (@doegox)
|
||||
- Fixed `make install` on OSX thanks DaveItsLong (@doegox)
|
||||
- Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz)
|
||||
- Added `hf_mfu_ultra.lua` script enables restoring dump to ULTRA/UL-5 tags and clearing previously written ULTRA tags (@mak-42)
|
||||
|
||||
## [Blue Ice.4.20142][2025-03-25]
|
||||
- Added `des_talk.py` script for easier MIFARE DESFire handling (@trigat)
|
||||
@@ -44,7 +51,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Changed `hf mf cload` - now accepts MFC Ev1 sized dumps (@iceman1001)
|
||||
- Changed `hf mfu info` - now properly identify ULEv1 AES 50pF (@iceman1001)
|
||||
- Changed `hf mf info` - now differentiates between full USCUID and cut down ZUID chips (@nvx)
|
||||
- Changed `lf hitag chk` - added key counter, client side abort and minor delay (@iceman1001)
|
||||
- Changed `lf hitag chk` - added key counter, client side abort and minor delay (@iceman1001)
|
||||
- Added `hf seos sam` - Added support for HID SAM SEOS communications (@jkramarz)
|
||||
- Changed (extended) area accessible by spiffs into last page of FLASH (@piotrva)
|
||||
- Changed flash-stored key dictionaries (Mifare, iClass, T55XX) and T55XX configurations to SPIFFS files (@piotrva)
|
||||
|
||||
@@ -27,6 +27,10 @@ PLATFORM=PM3RDV4
|
||||
# Only available with PLATFORM=PM3GENERIC
|
||||
#LED_ORDER=PM3EASY
|
||||
|
||||
# Uncomment a line below to change default USART baud rate
|
||||
# defaults to 115200 used by HC-05 in Blueshark
|
||||
#USART_BAUD_RATE=19200
|
||||
|
||||
# Uncomment the lines below in order to make a 256KB image
|
||||
# and comment out the lines above
|
||||
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ void BigBuf_Clear_ext(bool verbose) {
|
||||
memset(BigBuf, 0, s_bigbuf_size);
|
||||
clear_trace();
|
||||
if (verbose) {
|
||||
Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ static void update_leds_mode(standalone_mode_t mode) {
|
||||
*/
|
||||
static void indicate_success(void) {
|
||||
// Blink Green LED (A) 3 times quickly for success
|
||||
for(int i=0; i<3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
LED_A_ON();
|
||||
SpinDelay(150);
|
||||
LED_A_OFF();
|
||||
@@ -265,7 +265,7 @@ static void indicate_success(void) {
|
||||
*/
|
||||
static void indicate_failure(void) {
|
||||
// Blink Red LED (B) 3 times quickly for failure
|
||||
for(int i=0; i<3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
LED_B_ON();
|
||||
SpinDelay(150);
|
||||
LED_B_OFF();
|
||||
@@ -291,7 +291,7 @@ static bool load_tags_from_flash(st25tb_data_t collection[MAX_SAVED_TAGS]) {
|
||||
// Verify file size
|
||||
uint32_t size = size_in_spiffs(HF_ST25TB_MULTI_SR_FILE);
|
||||
if (size != sizeof(g_stored_tags)) {
|
||||
Dbprintf(_RED_("Flash file size mismatch (expected %zu, got %u). Wiping old file."),
|
||||
Dbprintf(_RED_("Flash file size mismatch (expected %zu, got %u). Wiping old file."),
|
||||
sizeof(g_stored_tags), size);
|
||||
// Remove corrupted file
|
||||
rdv40_spiffs_remove(HF_ST25TB_MULTI_SR_FILE, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
@@ -299,8 +299,8 @@ static bool load_tags_from_flash(st25tb_data_t collection[MAX_SAVED_TAGS]) {
|
||||
}
|
||||
|
||||
// Read file contents
|
||||
int res = rdv40_spiffs_read(HF_ST25TB_MULTI_SR_FILE, (uint8_t *)collection,
|
||||
size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
int res = rdv40_spiffs_read(HF_ST25TB_MULTI_SR_FILE, (uint8_t *)collection,
|
||||
size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
if (res != SPIFFS_OK) {
|
||||
Dbprintf(_RED_("Failed to read tag collection from flash (err %d)"), res);
|
||||
@@ -319,8 +319,8 @@ static bool load_tags_from_flash(st25tb_data_t collection[MAX_SAVED_TAGS]) {
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
static bool save_tags_to_flash(const st25tb_data_t collection[MAX_SAVED_TAGS]) {
|
||||
int res = rdv40_spiffs_write(HF_ST25TB_MULTI_SR_FILE, (uint8_t *)collection,
|
||||
sizeof(g_stored_tags), RDV40_SPIFFS_SAFETY_SAFE);
|
||||
int res = rdv40_spiffs_write(HF_ST25TB_MULTI_SR_FILE, (uint8_t *)collection,
|
||||
sizeof(g_stored_tags), RDV40_SPIFFS_SAFETY_SAFE);
|
||||
return (res == SPIFFS_OK);
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ static int find_free_tag_slot(void) {
|
||||
//=============================================================================
|
||||
|
||||
/**
|
||||
* @brief Stripped version of "iso14443b_setup" that avoids unnecessary LED
|
||||
* @brief Stripped version of "iso14443b_setup" that avoids unnecessary LED
|
||||
* operations and uses shorter delays
|
||||
*/
|
||||
static void iso14443b_setup_light(void) {
|
||||
@@ -417,7 +417,7 @@ static bool st25tb_tag_read(st25tb_data_t *tag_data_slot) {
|
||||
|
||||
Dbprintf("Found ST tag. Reading %d blocks...", ST25TB_BLOCK_COUNT);
|
||||
tag_data_slot->uid = bytes_to_num_le(card_info.uid, sizeof(tag_data_slot->uid));
|
||||
|
||||
|
||||
// Read all data blocks
|
||||
for (uint8_t block_address = 0; block_address < ST25TB_BLOCK_COUNT; block_address++) {
|
||||
WDT_HIT();
|
||||
@@ -507,7 +507,7 @@ static bool st25tb_tag_restore(const st25tb_data_t *stored_data_slot) {
|
||||
}
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
Dbprintf("Counter Block %d: Stored=0x%08X, Current=0x%08X",
|
||||
Dbprintf("Counter Block %d: Stored=0x%08X, Current=0x%08X",
|
||||
block_address, stored_value, current_value);
|
||||
}
|
||||
|
||||
@@ -528,7 +528,7 @@ static bool st25tb_tag_restore(const st25tb_data_t *stored_data_slot) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Dbprintf("Counter block %d already has the target value (0x%08X). Skipping write.",
|
||||
Dbprintf("Counter block %d already has the target value (0x%08X). Skipping write.",
|
||||
block_address, stored_value);
|
||||
}
|
||||
} else {
|
||||
@@ -658,7 +658,7 @@ static void st25tb_tear_off_write_block(uint8_t block_address, uint32_t data, ui
|
||||
block[0] = (data & 0xFF);
|
||||
block[1] = (data >> 8) & 0xFF;
|
||||
block[2] = (data >> 16) & 0xFF;
|
||||
block[3] = (data >> 24) & 0xFF;
|
||||
block[3] = (data >> 24) & 0xFF;
|
||||
|
||||
iso14b_card_select_t card;
|
||||
int res = iso14443b_select_srx_card(&card);
|
||||
@@ -667,7 +667,7 @@ static void st25tb_tear_off_write_block(uint8_t block_address, uint32_t data, ui
|
||||
}
|
||||
|
||||
res = st25tb_cmd_write_block(block_address, block);
|
||||
|
||||
|
||||
// Tear off the communication at precise timing
|
||||
SpinDelayUsPrecision(tearoff_delay_us);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
@@ -685,9 +685,9 @@ out:
|
||||
* @param read_back_value Pointer to store read-back value
|
||||
* @return 0 for success, -1 for failure
|
||||
*/
|
||||
static int8_t st25tb_tear_off_retry_write_verify(uint8_t block_address, uint32_t target_value,
|
||||
uint32_t max_try_count, int sleep_time_ms,
|
||||
uint32_t *read_back_value) {
|
||||
static int8_t st25tb_tear_off_retry_write_verify(uint8_t block_address, uint32_t target_value,
|
||||
uint32_t max_try_count, int sleep_time_ms,
|
||||
uint32_t *read_back_value) {
|
||||
int i = 0;
|
||||
*read_back_value = ~target_value; // Initialize to ensure the loop runs at least once
|
||||
|
||||
@@ -711,9 +711,9 @@ static int8_t st25tb_tear_off_retry_write_verify(uint8_t block_address, uint32_t
|
||||
* @param read_value Pointer to store read value
|
||||
* @return 0 if consolidated, -1 otherwise
|
||||
*/
|
||||
static int8_t st25tb_tear_off_is_consolidated(const uint8_t block_address, uint32_t value,
|
||||
int repeat_read, int sleep_time_ms,
|
||||
uint32_t *read_value) {
|
||||
static int8_t st25tb_tear_off_is_consolidated(const uint8_t block_address, uint32_t value,
|
||||
int repeat_read, int sleep_time_ms,
|
||||
uint32_t *read_value) {
|
||||
int result;
|
||||
for (int i = 0; i < repeat_read; i++) {
|
||||
if (sleep_time_ms > 0) SpinDelayUsPrecision(sleep_time_ms * 1000);
|
||||
@@ -733,8 +733,8 @@ static int8_t st25tb_tear_off_is_consolidated(const uint8_t block_address, uint3
|
||||
* @param read_back_value Pointer to store read-back value
|
||||
* @return 0 for success, -1 for failure
|
||||
*/
|
||||
static int8_t st25tb_tear_off_consolidate_block(const uint8_t block_address, uint32_t current_value,
|
||||
uint32_t target_value, uint32_t *read_back_value) {
|
||||
static int8_t st25tb_tear_off_consolidate_block(const uint8_t block_address, uint32_t current_value,
|
||||
uint32_t target_value, uint32_t *read_back_value) {
|
||||
int8_t result;
|
||||
uint32_t consolidation_value;
|
||||
|
||||
@@ -746,8 +746,8 @@ static int8_t st25tb_tear_off_consolidate_block(const uint8_t block_address, uin
|
||||
}
|
||||
|
||||
// Try writing value - 1
|
||||
result = st25tb_tear_off_retry_write_verify(block_address, consolidation_value - 1,
|
||||
TEAR_OFF_WRITE_RETRY_COUNT, 0, read_back_value);
|
||||
result = st25tb_tear_off_retry_write_verify(block_address, consolidation_value - 1,
|
||||
TEAR_OFF_WRITE_RETRY_COUNT, 0, read_back_value);
|
||||
if (result != 0) {
|
||||
Dbprintf("Consolidation failed at step 1 (write 0x%08X)", consolidation_value - 1);
|
||||
return -1;
|
||||
@@ -755,8 +755,8 @@ static int8_t st25tb_tear_off_consolidate_block(const uint8_t block_address, uin
|
||||
|
||||
// If value is not FE or target is not FD, try writing value - 2
|
||||
if (*read_back_value != 0xFFFFFFFE || (*read_back_value == 0xFFFFFFFE && target_value == 0xFFFFFFFD)) {
|
||||
result = st25tb_tear_off_retry_write_verify(block_address, consolidation_value - 2,
|
||||
TEAR_OFF_WRITE_RETRY_COUNT, 0, read_back_value);
|
||||
result = st25tb_tear_off_retry_write_verify(block_address, consolidation_value - 2,
|
||||
TEAR_OFF_WRITE_RETRY_COUNT, 0, read_back_value);
|
||||
if (result != 0) {
|
||||
Dbprintf("Consolidation failed at step 2 (write 0x%08X)", consolidation_value - 2);
|
||||
return -1;
|
||||
@@ -765,12 +765,12 @@ static int8_t st25tb_tear_off_consolidate_block(const uint8_t block_address, uin
|
||||
|
||||
// Final checks for stability of unstable high values (due to internal dual counters)
|
||||
if (result == 0 && target_value > 0xFFFFFFFD && *read_back_value > 0xFFFFFFFD) {
|
||||
result = st25tb_tear_off_is_consolidated(block_address, *read_back_value,
|
||||
TEAR_OFF_CONSOLIDATE_READ_COUNT, 0, read_back_value);
|
||||
result = st25tb_tear_off_is_consolidated(block_address, *read_back_value,
|
||||
TEAR_OFF_CONSOLIDATE_READ_COUNT, 0, read_back_value);
|
||||
if (result == 0) {
|
||||
result = st25tb_tear_off_is_consolidated(block_address, *read_back_value,
|
||||
TEAR_OFF_CONSOLIDATE_WAIT_READ_COUNT,
|
||||
TEAR_OFF_CONSOLIDATE_WAIT_MS, read_back_value);
|
||||
result = st25tb_tear_off_is_consolidated(block_address, *read_back_value,
|
||||
TEAR_OFF_CONSOLIDATE_WAIT_READ_COUNT,
|
||||
TEAR_OFF_CONSOLIDATE_WAIT_MS, read_back_value);
|
||||
if (result != 0) {
|
||||
Dbprintf("Consolidation failed stability check (long wait)");
|
||||
return -1;
|
||||
@@ -861,8 +861,8 @@ static void st25tb_tear_off_log(int tear_off_us, char *color, uint32_t value) {
|
||||
* @param safety_value Safety threshold to prevent going below
|
||||
* @return 0 for success, non-zero for failure
|
||||
*/
|
||||
static int8_t st25tb_tear_off_write_counter(uint8_t block_address, uint32_t target_value,
|
||||
uint32_t tear_off_adjustment_us, uint32_t safety_value) {
|
||||
static int8_t st25tb_tear_off_write_counter(uint8_t block_address, uint32_t target_value,
|
||||
uint32_t tear_off_adjustment_us, uint32_t safety_value) {
|
||||
int result;
|
||||
bool trigger = true;
|
||||
|
||||
@@ -906,7 +906,7 @@ static int8_t st25tb_tear_off_write_counter(uint8_t block_address, uint32_t targ
|
||||
for (;;) {
|
||||
// Safety check: ensure we don't go below the safety threshold
|
||||
if (tear_off_value < safety_value) {
|
||||
Dbprintf("Stopped. Safety threshold reached (next value 0x%08X < safety 0x%08X)",
|
||||
Dbprintf("Stopped. Safety threshold reached (next value 0x%08X < safety 0x%08X)",
|
||||
tear_off_value, safety_value);
|
||||
return -1;
|
||||
}
|
||||
@@ -921,15 +921,15 @@ static int8_t st25tb_tear_off_write_counter(uint8_t block_address, uint32_t targ
|
||||
}
|
||||
|
||||
// Analyze the result and decide next action
|
||||
if (read_value > current_value) {
|
||||
if (read_value > current_value) {
|
||||
// Partial write succeeded (successful tear-off)
|
||||
if (read_value >= 0xFFFFFFFE ||
|
||||
(read_value - 2) > target_value ||
|
||||
read_value != last_consolidated_value ||
|
||||
((read_value & 0xF0000000) > (current_value & 0xF0000000))) { // Major bit flip
|
||||
|
||||
result = st25tb_tear_off_consolidate_block(block_address, read_value,
|
||||
target_value, ¤t_value);
|
||||
(read_value - 2) > target_value ||
|
||||
read_value != last_consolidated_value ||
|
||||
((read_value & 0xF0000000) > (current_value & 0xF0000000))) { // Major bit flip
|
||||
|
||||
result = st25tb_tear_off_consolidate_block(block_address, read_value,
|
||||
target_value, ¤t_value);
|
||||
if (result == 0 && current_value == target_value) {
|
||||
st25tb_tear_off_log(tear_off_us, GREEN, read_value);
|
||||
Dbprintf("Target value 0x%08X reached successfully!", target_value);
|
||||
@@ -1004,11 +1004,11 @@ static void run_learn_function(void) {
|
||||
} else {
|
||||
// Only increment if we are adding to a new slot, not overwriting
|
||||
if (!g_stored_tags[slot_index].data_valid) {
|
||||
g_valid_tag_count++;
|
||||
g_valid_tag_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Store tag data in collection
|
||||
memcpy(&g_stored_tags[slot_index], &temp_tag_data, sizeof(st25tb_data_t));
|
||||
g_stored_tags[slot_index].data_valid = true;
|
||||
@@ -1020,7 +1020,7 @@ static void run_learn_function(void) {
|
||||
} else {
|
||||
DbpString(_RED_("Failed to save collection to flash!"));
|
||||
}
|
||||
|
||||
|
||||
current_state = STATE_DONE; // Indicate success
|
||||
}
|
||||
}
|
||||
@@ -1052,8 +1052,8 @@ static void run_restore_function(void) {
|
||||
current_state = STATE_ERROR;
|
||||
}
|
||||
} else {
|
||||
// Tag found but not in collection, remain busy to scan again
|
||||
current_state = STATE_BUSY;
|
||||
// Tag found but not in collection, remain busy to scan again
|
||||
current_state = STATE_BUSY;
|
||||
}
|
||||
} else {
|
||||
// No tag found, remain busy to scan again
|
||||
@@ -1131,10 +1131,10 @@ void RunMod(void) {
|
||||
// --- Update Display (only if mode changed) ---
|
||||
if (mode_display_update) {
|
||||
if (g_current_mode == MODE_LEARN) {
|
||||
Dbprintf("Mode: " _YELLOW_("Learn") ". (Cnt: %d/%d)",
|
||||
Dbprintf("Mode: " _YELLOW_("Learn") ". (Cnt: %d/%d)",
|
||||
g_valid_tag_count, MAX_SAVED_TAGS);
|
||||
} else {
|
||||
Dbprintf("Mode: " _BLUE_("Restore") ". (Cnt: %d/%d)",
|
||||
Dbprintf("Mode: " _BLUE_("Restore") ". (Cnt: %d/%d)",
|
||||
g_valid_tag_count, MAX_SAVED_TAGS);
|
||||
}
|
||||
mode_display_update = false;
|
||||
@@ -1142,14 +1142,14 @@ void RunMod(void) {
|
||||
update_leds_mode(g_current_mode);
|
||||
|
||||
// Process according to current state
|
||||
if(current_state == STATE_BUSY) {
|
||||
if (current_state == STATE_BUSY) {
|
||||
// Run appropriate function based on mode
|
||||
if (g_current_mode == MODE_LEARN) {
|
||||
run_learn_function();
|
||||
} else { // MODE_RESTORE
|
||||
run_restore_function();
|
||||
}
|
||||
} else if(current_state == STATE_DONE) {
|
||||
} else if (current_state == STATE_DONE) {
|
||||
indicate_success();
|
||||
} else {
|
||||
indicate_failure();
|
||||
|
||||
+20
-17
@@ -104,7 +104,7 @@ int tearoff_hook(void) {
|
||||
SpinDelayUsPrecision(g_tearoff_delay_us);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
g_tearoff_enabled = false;
|
||||
Dbprintf(_YELLOW_("Tear-off triggered!"));
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf(_YELLOW_("Tear-off triggered!"));
|
||||
return PM3_ETEAROFF;
|
||||
} else {
|
||||
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
|
||||
@@ -254,7 +254,7 @@ static uint32_t MeasureAntennaTuningLfData(void) {
|
||||
void print_stack_usage(void) {
|
||||
for (uint32_t *p = _stack_start; ; ++p) {
|
||||
if (*p != 0xdeadbeef) {
|
||||
Dbprintf(" Max stack usage......... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
|
||||
Dbprintf(" Max stack usage..... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -365,7 +365,7 @@ static void print_debug_level(void) {
|
||||
sprintf(dbglvlstr, "extended");
|
||||
break;
|
||||
}
|
||||
Dbprintf(" Debug log level......... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
|
||||
Dbprintf(" Debug log level..... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
|
||||
}
|
||||
|
||||
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
|
||||
@@ -421,11 +421,11 @@ static void SendStatus(uint32_t wait) {
|
||||
print_debug_level();
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
Dbprintf(" ToSendMax............... %d", ts->max);
|
||||
Dbprintf(" ToSend BUFFERSIZE....... %d", TOSEND_BUFFER_SIZE);
|
||||
Dbprintf(" ToSendMax........... %d", ts->max);
|
||||
Dbprintf(" ToSend BUFFERSIZE... %d", TOSEND_BUFFER_SIZE);
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks
|
||||
Dbprintf(" Slow clock.............. %d Hz", (16 * MAINCK) / mainf);
|
||||
Dbprintf(" Slow clock.......... %d Hz", (16 * MAINCK) / mainf);
|
||||
uint32_t delta_time = 0;
|
||||
uint32_t start_time = GetTickCount();
|
||||
#define SLCK_CHECK_MS 50
|
||||
@@ -449,10 +449,11 @@ static void SendStatus(uint32_t wait) {
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Dbprintf(" Mifare.................. "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, MF_KEYS_FILE);
|
||||
Dbprintf(" Mifare... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MF_KEYS_FILE);
|
||||
} else {
|
||||
Dbprintf(" Mifare.................. "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, MF_KEYS_FILE);
|
||||
Dbprintf(" Mifare... "_RED_("%u")" keys - "_RED_("%s"), num, MF_KEYS_FILE);
|
||||
}
|
||||
|
||||
if (exists_in_spiffs(T55XX_KEYS_FILE)) {
|
||||
@@ -460,10 +461,11 @@ static void SendStatus(uint32_t wait) {
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Dbprintf(" T55xx................... "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, T55XX_KEYS_FILE);
|
||||
Dbprintf(" T55xx.... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, T55XX_KEYS_FILE);
|
||||
} else {
|
||||
Dbprintf(" T55xx................... "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, T55XX_KEYS_FILE);
|
||||
Dbprintf(" T55xx.... "_RED_("%u")" keys - "_RED_("%s"), num, T55XX_KEYS_FILE);
|
||||
}
|
||||
|
||||
if (exists_in_spiffs(ICLASS_KEYS_FILE)) {
|
||||
@@ -471,10 +473,11 @@ static void SendStatus(uint32_t wait) {
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Dbprintf(" iClass.................. "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, ICLASS_KEYS_FILE);
|
||||
Dbprintf(" iClass... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, ICLASS_KEYS_FILE);
|
||||
} else {
|
||||
Dbprintf(" iClass.................. "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, ICLASS_KEYS_FILE);
|
||||
Dbprintf(" iClass... "_RED_("%u")" keys - "_RED_("%s"), num, ICLASS_KEYS_FILE);
|
||||
}
|
||||
#endif
|
||||
DbpString("");
|
||||
@@ -2354,7 +2357,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
|
||||
uint16_t available;
|
||||
uint16_t pre_available = 0;
|
||||
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
|
||||
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
|
||||
uint32_t wait = payload->waittime;
|
||||
|
||||
StartTicks();
|
||||
@@ -2398,7 +2401,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
|
||||
uint16_t available;
|
||||
uint16_t pre_available = 0;
|
||||
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
|
||||
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
|
||||
uint32_t wait = payload->waittime;
|
||||
|
||||
StartTicks();
|
||||
@@ -2694,7 +2697,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
|
||||
uint32_t size = packet->oldarg[1];
|
||||
|
||||
uint8_t *buff = BigBuf_malloc(size);
|
||||
uint8_t *buff = BigBuf_calloc(size);
|
||||
if (buff == NULL) {
|
||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
|
||||
// Trigger a finish downloading signal with an PM3_EMALLOC
|
||||
@@ -2899,7 +2902,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
case CMD_FLASHMEM_DOWNLOAD: {
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *mem = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *mem = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
||||
uint32_t startidx = packet->oldarg[0];
|
||||
uint32_t numofbytes = packet->oldarg[1];
|
||||
// arg0 = startindex
|
||||
@@ -2931,7 +2934,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
case CMD_FLASHMEM_INFO: {
|
||||
|
||||
LED_B_ON();
|
||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_calloc(sizeof(rdv40_validation_t));
|
||||
|
||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||
|
||||
|
||||
+1
-1
@@ -748,7 +748,7 @@ void em4x50_chk(const char *filename, bool ledcontrol) {
|
||||
uint16_t pwd_count = 0;
|
||||
uint32_t size = size_in_spiffs(filename);
|
||||
pwd_count = size / 4;
|
||||
uint8_t *pwds = BigBuf_malloc(size);
|
||||
uint8_t *pwds = BigBuf_calloc(size);
|
||||
|
||||
rdv40_spiffs_read_as_filetype(filename, pwds, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
|
||||
+2
-2
@@ -857,7 +857,7 @@ void SmartCardRaw(const smart_card_raw_t *p) {
|
||||
LED_D_ON();
|
||||
|
||||
uint16_t len = 0;
|
||||
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
||||
@@ -937,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
||||
bool isOK = true;
|
||||
uint16_t length = arg0, pos = 0;
|
||||
const uint8_t *fwdata = BigBuf_get_addr();
|
||||
uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE);
|
||||
uint8_t *verfiydata = BigBuf_calloc(I2C_BLOCK_SIZE);
|
||||
|
||||
while (length) {
|
||||
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
LED_D_ON();
|
||||
|
||||
uint16_t len = 0;
|
||||
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
resp[0] = prepend;
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
||||
+18
-18
@@ -399,40 +399,40 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||
int trace_data_size;
|
||||
|
||||
// Respond SOF -- takes 1 bytes
|
||||
uint8_t *resp_sof = BigBuf_malloc(1);
|
||||
uint8_t resp_sof[1] = {0};
|
||||
int resp_sof_len;
|
||||
|
||||
// Anticollision CSN (rotated CSN)
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp_anticoll = BigBuf_malloc(22);
|
||||
uint8_t *resp_anticoll = BigBuf_calloc(22);
|
||||
int resp_anticoll_len;
|
||||
|
||||
// CSN (block 0)
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp_csn = BigBuf_malloc(22);
|
||||
uint8_t *resp_csn = BigBuf_calloc(22);
|
||||
int resp_csn_len;
|
||||
|
||||
// configuration (blk 1) PICOPASS 2ks
|
||||
uint8_t *resp_conf = BigBuf_malloc(22);
|
||||
uint8_t *resp_conf = BigBuf_calloc(22);
|
||||
int resp_conf_len;
|
||||
|
||||
// e-Purse (blk 2)
|
||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
||||
uint8_t *resp_cc = BigBuf_malloc(18);
|
||||
uint8_t *resp_cc = BigBuf_calloc(18);
|
||||
int resp_cc_len;
|
||||
|
||||
// Kd, Kc (blocks 3 and 4). Cannot be read. Always respond with 0xff bytes only
|
||||
uint8_t *resp_ff = BigBuf_malloc(22);
|
||||
uint8_t *resp_ff = BigBuf_calloc(22);
|
||||
int resp_ff_len;
|
||||
uint8_t ff_data[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
|
||||
AddCrc(ff_data, 8);
|
||||
|
||||
// Application Issuer Area (blk 5)
|
||||
uint8_t *resp_aia = BigBuf_malloc(22);
|
||||
uint8_t *resp_aia = BigBuf_calloc(22);
|
||||
int resp_aia_len;
|
||||
|
||||
// receive command
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
|
||||
// Prepare card messages
|
||||
tosend_t *ts = get_tosend();
|
||||
@@ -474,11 +474,11 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||
|
||||
//This is used for responding to READ-block commands or other data which is dynamically generated
|
||||
//First the 'trace'-data, not encoded for FPGA
|
||||
uint8_t *data_generic_trace = BigBuf_malloc(34); // 32 bytes data + 2byte CRC is max tag answer
|
||||
uint8_t *data_generic_trace = BigBuf_calloc(34); // 32 bytes data + 2byte CRC is max tag answer
|
||||
|
||||
//Then storage for the modulated data
|
||||
//Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
|
||||
uint8_t *data_response = BigBuf_malloc((34 * 2) + 3);
|
||||
uint8_t *data_response = BigBuf_calloc((34 * 2) + 3);
|
||||
|
||||
enum { IDLE, ACTIVATED, SELECTED, HALTED } chip_state = IDLE;
|
||||
|
||||
@@ -942,29 +942,29 @@ int do_iclass_simulation_nonsec(void) {
|
||||
int trace_data_size = 0;
|
||||
|
||||
// Respond SOF -- takes 1 bytes
|
||||
uint8_t *resp_sof = BigBuf_malloc(2);
|
||||
uint8_t resp_sof[2] = { 0 };
|
||||
int resp_sof_len;
|
||||
|
||||
// Anticollision CSN (rotated CSN)
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp_anticoll = BigBuf_malloc(28);
|
||||
uint8_t *resp_anticoll = BigBuf_calloc(28);
|
||||
int resp_anticoll_len;
|
||||
|
||||
// CSN
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp_csn = BigBuf_malloc(28);
|
||||
uint8_t *resp_csn = BigBuf_calloc(28);
|
||||
int resp_csn_len;
|
||||
|
||||
// configuration (blk 1) PICOPASS 2ks
|
||||
uint8_t *resp_conf = BigBuf_malloc(28);
|
||||
uint8_t *resp_conf = BigBuf_calloc(28);
|
||||
int resp_conf_len;
|
||||
|
||||
// Application Issuer Area (blk 5)
|
||||
uint8_t *resp_aia = BigBuf_malloc(28);
|
||||
uint8_t *resp_aia = BigBuf_calloc(28);
|
||||
int resp_aia_len;
|
||||
|
||||
// receive command
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
|
||||
// Prepare card messages
|
||||
tosend_t *ts = get_tosend();
|
||||
@@ -997,11 +997,11 @@ int do_iclass_simulation_nonsec(void) {
|
||||
|
||||
//This is used for responding to READ-block commands or other data which is dynamically generated
|
||||
//First the 'trace'-data, not encoded for FPGA
|
||||
uint8_t *data_generic_trace = BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
||||
uint8_t *data_generic_trace = BigBuf_calloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
||||
|
||||
//Then storage for the modulated data
|
||||
//Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
|
||||
uint8_t *data_response = BigBuf_malloc((32 + 2) * 2 + 2);
|
||||
uint8_t *data_response = BigBuf_calloc((32 + 2) * 2 + 2);
|
||||
|
||||
enum { IDLE, ACTIVATED, SELECTED, HALTED } chip_state = IDLE;
|
||||
|
||||
|
||||
+21
-21
@@ -190,35 +190,35 @@ struct Crypto1State crypto1_state = {0, 0};
|
||||
|
||||
void printHf14aConfig(void) {
|
||||
DbpString(_CYAN_("HF 14a config"));
|
||||
Dbprintf(" [a] Anticol override.............. %s%s%s",
|
||||
Dbprintf(" [a] Anticol override........... %s%s%s",
|
||||
(hf14aconfig.forceanticol == 0) ? _GREEN_("std") " ( follow standard )" : "",
|
||||
(hf14aconfig.forceanticol == 1) ? _RED_("force") " ( always do anticol )" : "",
|
||||
(hf14aconfig.forceanticol == 2) ? _RED_("skip") " ( always skip anticol )" : ""
|
||||
);
|
||||
Dbprintf(" [b] BCC override.................. %s%s%s",
|
||||
Dbprintf(" [b] BCC override............... %s%s%s",
|
||||
(hf14aconfig.forcebcc == 0) ? _GREEN_("std") " ( follow standard )" : "",
|
||||
(hf14aconfig.forcebcc == 1) ? _RED_("fix") " ( fix bad BCC )" : "",
|
||||
(hf14aconfig.forcebcc == 2) ? _RED_("ignore") " ( ignore bad BCC, always use card BCC )" : ""
|
||||
);
|
||||
Dbprintf(" [2] CL2 override.................. %s%s%s",
|
||||
Dbprintf(" [2] CL2 override............... %s%s%s",
|
||||
(hf14aconfig.forcecl2 == 0) ? _GREEN_("std") " ( follow standard )" : "",
|
||||
(hf14aconfig.forcecl2 == 1) ? _RED_("force") " ( always do CL2 )" : "",
|
||||
(hf14aconfig.forcecl2 == 2) ? _RED_("skip") " ( always skip CL2 )" : ""
|
||||
);
|
||||
Dbprintf(" [3] CL3 override.................. %s%s%s",
|
||||
Dbprintf(" [3] CL3 override............... %s%s%s",
|
||||
(hf14aconfig.forcecl3 == 0) ? _GREEN_("std") " ( follow standard )" : "",
|
||||
(hf14aconfig.forcecl3 == 1) ? _RED_("force") " ( always do CL3 )" : "",
|
||||
(hf14aconfig.forcecl3 == 2) ? _RED_("skip") " ( always skip CL3 )" : ""
|
||||
);
|
||||
Dbprintf(" [r] RATS override................. %s%s%s",
|
||||
Dbprintf(" [r] RATS override.............. %s%s%s",
|
||||
(hf14aconfig.forcerats == 0) ? _GREEN_("std") " ( follow standard )" : "",
|
||||
(hf14aconfig.forcerats == 1) ? _RED_("force") " ( always do RATS )" : "",
|
||||
(hf14aconfig.forcerats == 2) ? _RED_("skip") " ( always skip RATS )" : ""
|
||||
);
|
||||
Dbprintf(" [m] Magsafe polling............... %s",
|
||||
Dbprintf(" [m] Magsafe polling............ %s",
|
||||
(hf14aconfig.magsafe == 1) ? _GREEN_("enabled") : _YELLOW_("disabled")
|
||||
);
|
||||
Dbprintf(" [p] Polling loop annotation....... %s %*D",
|
||||
Dbprintf(" [p] Polling loop annotation.... %s %*D",
|
||||
(hf14aconfig.polling_loop_annotation.frame_length <= 0) ? _YELLOW_("disabled") : _GREEN_("enabled"),
|
||||
hf14aconfig.polling_loop_annotation.frame_length,
|
||||
hf14aconfig.polling_loop_annotation.frame,
|
||||
@@ -524,6 +524,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
|
||||
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Uart.bitCount = 0;
|
||||
Uart.shiftReg = 0;
|
||||
|
||||
// Every 8 data bytes, store 8 parity bits into a parity byte
|
||||
if ((Uart.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
@@ -804,12 +805,12 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
set_tracing(true);
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *receivedResp = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedRespPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0, dataLen;
|
||||
@@ -1496,6 +1497,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
// "precompiled" responses.
|
||||
// These exist for speed reasons. There are no time in the anti collision phase to calculate responses.
|
||||
// There are 12 predefined responses with a total of 84 bytes data to transmit.
|
||||
//
|
||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||
// 85 * 8 data bits, 85 * 1 parity bits, 12 start bits, 12 stop bits, 12 correction bits
|
||||
// 85 * 8 + 85 + 12 + 12 + 12 == 801
|
||||
@@ -2681,9 +2683,9 @@ void iso14443a_antifuzz(uint32_t flags) {
|
||||
int len = 0;
|
||||
|
||||
// allocate buffers:
|
||||
uint8_t *received = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *resp = BigBuf_malloc(20);
|
||||
uint8_t *received = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
uint8_t *resp = BigBuf_calloc(20);
|
||||
|
||||
memset(received, 0x00, MAX_FRAME_SIZE);
|
||||
memset(received, 0x00, MAX_PARITY_SIZE);
|
||||
@@ -2771,19 +2773,19 @@ static void iso14a_set_ATS_times(const uint8_t *ats) {
|
||||
|
||||
|
||||
static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const iso14a_polling_parameters_t *polling_parameters) {
|
||||
#define RETRY_TIMEOUT 10
|
||||
#define RETRY_TIMEOUT 10
|
||||
|
||||
uint32_t save_iso14a_timeout = iso14a_get_timeout();
|
||||
iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer.
|
||||
|
||||
// refactored to use local pointer, now no modification of polling_parameters pointer is done
|
||||
// I don't think the intention was to modify polling_parameters when sending in WUPA_POLLING_PARAMETERS etc.
|
||||
// I don't think the intention was to modify polling_parameters when sending in WUPA_POLLING_PARAMETERS etc.
|
||||
// Modify polling_params, if null use default values.
|
||||
iso14a_polling_parameters_t p;
|
||||
memcpy(&p, (uint8_t*)polling_parameters, sizeof(iso14a_polling_parameters_t));
|
||||
memcpy(&p, (uint8_t *)polling_parameters, sizeof(iso14a_polling_parameters_t));
|
||||
|
||||
if (polling_parameters == NULL) {
|
||||
memcpy(&p, (uint8_t*)&hf14a_polling_parameters, sizeof(iso14a_polling_parameters_t));
|
||||
memcpy(&p, (uint8_t *)&hf14a_polling_parameters, sizeof(iso14a_polling_parameters_t));
|
||||
}
|
||||
|
||||
bool first_try = true;
|
||||
@@ -4068,9 +4070,7 @@ void DetectNACKbug(void) {
|
||||
// i = number of authentications sent. Not always 256, since we are trying to sync but close to it.
|
||||
FpgaDisableTracing();
|
||||
|
||||
uint8_t *data = BigBuf_malloc(4);
|
||||
data[0] = isOK;
|
||||
data[1] = num_nacks;
|
||||
uint8_t data[4] = {isOK, num_nacks, 0, 0};
|
||||
num_to_bytes(i, 2, data + 2);
|
||||
reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4);
|
||||
|
||||
|
||||
+9
-8
@@ -221,10 +221,11 @@ out:
|
||||
int sam_get_version(void) {
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_get_version");
|
||||
}
|
||||
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t payload[] = {
|
||||
@@ -252,8 +253,9 @@ int sam_get_version(void) {
|
||||
// 82 01
|
||||
// 01
|
||||
// 90 00
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_version");
|
||||
}
|
||||
|
||||
if (response[5] != 0xbd) {
|
||||
Dbprintf("Invalid SAM response");
|
||||
@@ -289,8 +291,9 @@ error:
|
||||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_version");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -350,12 +353,10 @@ void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type
|
||||
}
|
||||
|
||||
void sam_send_ack(void) {
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t payload[] = {
|
||||
0xa0, 0
|
||||
};
|
||||
uint8_t payload[] = { 0xa0, 0 };
|
||||
uint16_t payload_len = sizeof(payload);
|
||||
|
||||
sam_send_payload(
|
||||
|
||||
@@ -46,11 +46,12 @@
|
||||
*/
|
||||
static int sam_send_request_iso15(const uint8_t *const request, const uint8_t request_len, uint8_t *response, uint8_t *response_len, const bool shallow_mod, const bool break_on_nr_mac, const bool prevent_epurse_update) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_send_request_iso14a");
|
||||
}
|
||||
|
||||
uint8_t *buf1 = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf2 = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf1 = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf2 = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
if (buf1 == NULL || buf2 == NULL) {
|
||||
res = PM3_EMALLOC;
|
||||
goto out;
|
||||
@@ -255,10 +256,10 @@ out:
|
||||
*/
|
||||
static int sam_set_card_detected_picopass(const picopass_hdr_t *card_select) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_set_card_detected");
|
||||
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
}
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
// a0 12
|
||||
@@ -314,8 +315,9 @@ error:
|
||||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_set_card_detected");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -51,13 +51,14 @@
|
||||
*/
|
||||
static int sam_set_card_detected_seos(iso14a_card_select_t *card_select) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_set_card_detected");
|
||||
}
|
||||
|
||||
uint8_t *request = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *request = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t request_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
const uint8_t payload[] = {
|
||||
@@ -107,8 +108,9 @@ error:
|
||||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_set_card_detected");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -312,7 +312,7 @@ static int is_valid_filename(const char *filename) {
|
||||
*/
|
||||
static void copy_in_spiffs(const char *src, const char *dst) {
|
||||
uint32_t size = size_in_spiffs(src);
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
read_from_spiffs(src, (uint8_t *)mem, size);
|
||||
write_to_spiffs(dst, (uint8_t *)mem, size);
|
||||
}
|
||||
|
||||
@@ -3107,3 +3107,55 @@ AB921CF0752C
|
||||
265A5F32DE73
|
||||
567D734C403C
|
||||
2426217B3B3B
|
||||
#
|
||||
# Card keys from Andalusian public transport system (Consorcio de Transportes)
|
||||
1848A8D1E4C5
|
||||
16EE1FE134E4
|
||||
5246B8F4ACFC
|
||||
515A8209843C
|
||||
0EF7636AA829
|
||||
E59D0F78C413
|
||||
5AF68604DD6B
|
||||
B0BCB22DCBA3
|
||||
51B3EF60BF56
|
||||
99100225D83B
|
||||
63C88F562B97
|
||||
B30B6A5AD434
|
||||
D33E4A4A0041
|
||||
9C0A4CC89D61
|
||||
5204D83D8CD3
|
||||
A662F9DC0D3D
|
||||
#
|
||||
# Card keys from EMT Malaga (Spain) bus system
|
||||
41534E354936
|
||||
454D41343253
|
||||
4541444C4130
|
||||
46305234324E
|
||||
505444505232
|
||||
5239425A3546
|
||||
454449434631
|
||||
414F4544384C
|
||||
344E4F4E4937
|
||||
45444E413254
|
||||
3255534D3033
|
||||
4F554D523935
|
||||
3141544D3735
|
||||
494E47463539
|
||||
32414F4E3341
|
||||
41534C473637
|
||||
534E41395430
|
||||
41364C38364F
|
||||
525241414D39
|
||||
41304532334F
|
||||
4D4545494F35
|
||||
4E324C453045
|
||||
394143494E32
|
||||
5352554E3245
|
||||
324553553036
|
||||
444D414E3539
|
||||
324745413232
|
||||
4E4E41455236
|
||||
394C52493639
|
||||
4D4941413236
|
||||
414D504F3243
|
||||
434C414E3639
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
local ansicolors = require('ansicolors')
|
||||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
|
||||
-- globals
|
||||
copyright = ''
|
||||
author = 'Dmitry Malenok'
|
||||
version = 'v1.0.0'
|
||||
desc = [[
|
||||
The script provides functionality for writing Mifare Ultralight Ultra/UL-5 tags.
|
||||
]]
|
||||
example = [[
|
||||
-- restpre (write) dump to tag
|
||||
]]..ansicolors.yellow..[[script run hf_mfu_ultra -f hf-mfu-3476FF1514D866-dump.bin -k ffffffff -r]]..ansicolors.reset..[[
|
||||
|
||||
-- wipe tag (]]..ansicolors.red..[[Do not use it with UL-5!]]..ansicolors.reset..[[)
|
||||
]]..ansicolors.yellow..[[script run hf_mfu_ultra -k 1d237f76 -w ]]..ansicolors.reset..[[
|
||||
]]
|
||||
usage = [[
|
||||
script run hf_mfu_ultra -h -f <dump filename> -k <passwd> -w -r
|
||||
]]
|
||||
arguments = [[
|
||||
-h this help
|
||||
-f filename for the datadump to read (bin)
|
||||
-k pwd to use with the restore and wipe operations
|
||||
-r restore a binary dump to tag
|
||||
-w wipe tag (]]..ansicolors.red..[[Do not use it with UL-5!]]..ansicolors.reset..[[)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
local _password = nil
|
||||
local _defaultPassword = 'FFFFFFFF'
|
||||
local _dumpstart = 0x38*2 + 1
|
||||
---
|
||||
|
||||
--- Handles errors
|
||||
local function error(err)
|
||||
print(ansicolors.red.."ERROR:"..ansicolors.reset, err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
|
||||
-- sets the global password variable
|
||||
local function setPassword(password)
|
||||
if password == nil or #password == 0 then
|
||||
_password = nil;
|
||||
elseif #password ~= 8 then
|
||||
return false, 'Password must be 4 hex bytes'
|
||||
else
|
||||
_password = password
|
||||
end
|
||||
return true, 'Sets'
|
||||
end
|
||||
|
||||
|
||||
--- Parses response data
|
||||
local function parseResponse(rawResponse)
|
||||
local resp = Command.parse(rawResponse)
|
||||
local len = tonumber(resp.arg1) * 2
|
||||
return string.sub(tostring(resp.data), 0, len);
|
||||
end
|
||||
---
|
||||
|
||||
--- Sends raw data to PM3 and returns raw response if any
|
||||
local function sendRaw(rawdata, options)
|
||||
|
||||
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
|
||||
|
||||
if options.keep_signal then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
||||
end
|
||||
|
||||
if options.connect then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_CONNECT
|
||||
end
|
||||
|
||||
if options.no_select then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_SELECT
|
||||
end
|
||||
|
||||
if options.append_crc then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
|
||||
end
|
||||
|
||||
local arg2 = #rawdata / 2
|
||||
if options.bits7 then
|
||||
arg2 = arg2 | tonumber(bit32.lshift(7, 16))
|
||||
end
|
||||
|
||||
local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
|
||||
arg1 = flags,
|
||||
arg2 = arg2,
|
||||
data = rawdata}
|
||||
return command:sendMIX(options.ignore_response)
|
||||
end
|
||||
---
|
||||
|
||||
--- Sends raw data to PM3 and returns parsed response
|
||||
local function sendWithResponse(payload, options)
|
||||
local opts;
|
||||
if options then
|
||||
opts = options
|
||||
else
|
||||
opts = {ignore_response = false, keep_signal = true, append_crc = true}
|
||||
end
|
||||
local rawResp, err = sendRaw(payload, opts)
|
||||
if err then return err end
|
||||
return parseResponse(rawResp)
|
||||
end
|
||||
---
|
||||
|
||||
-- Authenticates if password is provided
|
||||
local function authenticate(password)
|
||||
if password then
|
||||
local resp, err = sendWithResponse('1B'..password)
|
||||
if err then return err end
|
||||
-- looking for 2 bytes (4 symbols) of PACK and 2 bytes (4 symbols) of CRC
|
||||
if not resp or #resp ~=8 then return false, 'It seems that password is wrong' end
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- selects tag and authenticates if password is provided
|
||||
local function connect()
|
||||
core.clearCommandBuffer()
|
||||
local info, err = lib14a.read(true, true)
|
||||
if err then
|
||||
lib14a.disconnect()
|
||||
return false, err
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
|
||||
return authenticate(_password)
|
||||
end
|
||||
--
|
||||
|
||||
-- reconnects and selects tag again
|
||||
local function reconnect()
|
||||
lib14a.disconnect()
|
||||
utils.Sleep(1)
|
||||
local info, err = connect()
|
||||
if not info then return false, "Unable to select tag: "..err end
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- checks tag version
|
||||
local function checkTagVersion()
|
||||
local resp, err = sendWithResponse('60');
|
||||
if err or resp == nil then return false, err end
|
||||
if string.find(resp, '0034210101000E03') ~= 1 then return false, 'Wrong tag version: '..string.sub(resp,1,-5) end
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- sends magic wakeup command
|
||||
local function magicWakeup()
|
||||
io.write('Sending magic wakeup command...')
|
||||
local resp, err = sendRaw('5000', {ignore_response = false, append_crc = true})
|
||||
if err or resp == nil then return false, "Unable to send first magic wakeup command: "..err end
|
||||
resp, err = sendRaw('40', {connect = true, no_select = true, ignore_response = false, keep_signal = true, append_crc = false, bits7 = true})
|
||||
if err or resp == nil then return false, "Unable to send first magic wakeup command: "..err end
|
||||
resp, err = sendRaw('43', {ignore_response = false, keep_signal = true, append_crc = false})
|
||||
if err or resp == nil then return false, "Unable to send second magic wakeup command: "..err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- Writes dump to tag
|
||||
local function writeDump(filename)
|
||||
print(string.rep('--',20))
|
||||
local info, err = connect()
|
||||
if not info then return false, "Unable to select tag: "..err end
|
||||
info, err = checkTagVersion()
|
||||
if not info then return info, err end
|
||||
|
||||
-- load dump from file
|
||||
if not filename then return false, 'No dump filename provided' end
|
||||
io.write('Loading dump from file '..filename..'...')
|
||||
local dump
|
||||
dump, err = utils.ReadDumpFile(filename)
|
||||
if not dump then return false, err end
|
||||
if #dump ~= _dumpstart - 1 + 0xa4*2 then return false, 'Invalid dump file' end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
|
||||
local resp
|
||||
for i = 3, 0x23 do
|
||||
local blockStart = i * 8 + _dumpstart
|
||||
local block = string.sub(dump, blockStart, blockStart + 7)
|
||||
local cblock = string.format('%02x',i)
|
||||
io.write('Writing block 0x'..cblock..'...')
|
||||
resp, err = sendWithResponse('A2'..cblock..block)
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
end
|
||||
|
||||
-- set password
|
||||
io.write('Setting password and pack ')
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
local passwordStart = 0x27*8 + _dumpstart
|
||||
local password = string.sub(dump, passwordStart, passwordStart + 7)
|
||||
local packBlock = string.sub(dump, passwordStart+8, passwordStart + 15)
|
||||
io.write('(password: '..password..') (pack block: '..packBlock..')...')
|
||||
resp, err = sendWithResponse('A227'..password)
|
||||
if err ~= nil then return false, err end
|
||||
resp, err = sendWithResponse('A228'..packBlock)
|
||||
if err ~= nil then return false, err end
|
||||
if not setPassword(password) then return false, 'Unable to set password' end
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
|
||||
-- set configs and locks
|
||||
for i = 0x24, 0x26 do
|
||||
local blockStart = i * 8 + _dumpstart
|
||||
local block = string.sub(dump, blockStart, blockStart + 7)
|
||||
local cblock = string.format('%02x',i)
|
||||
io.write('Writing block 0x'..cblock..'...')
|
||||
resp, err = sendWithResponse('A2'..cblock..block)
|
||||
if err ~= nil then return false, err end
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
end
|
||||
|
||||
info, err = magicWakeup()
|
||||
if not info then return false, err end
|
||||
-- set uid and locks
|
||||
for i = 0x2, 0x0, -1 do
|
||||
local blockStart = i * 8 + _dumpstart
|
||||
local block = string.sub(dump, blockStart, blockStart + 7)
|
||||
local cblock = string.format('%02x',i)
|
||||
io.write('Writing block 0x'..cblock..'...')
|
||||
resp, err = sendWithResponse('A2'..cblock..block, {connect = i == 0x2, ignore_response = false, keep_signal = i ~= 0, append_crc = true})
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
end
|
||||
|
||||
print(ansicolors.green..'The dump has been written to the tag.'..ansicolors.reset)
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- Wipes tag
|
||||
local function wipe()
|
||||
print(string.rep('--',20))
|
||||
print('Wiping tag')
|
||||
|
||||
local info, err = connect()
|
||||
if not info then return false, "Unable to select tag: "..err end
|
||||
info, err = checkTagVersion()
|
||||
if not info then return info, err end
|
||||
|
||||
|
||||
local resp
|
||||
-- clear lock bytes on page 0x02
|
||||
resp, err = sendWithResponse('3000')
|
||||
if err or resp == nil then return false, err end
|
||||
local currentLowLockPage = string.sub(resp,17,24)
|
||||
if(string.sub(currentLowLockPage,5,8) ~= '0000') then
|
||||
info, err = magicWakeup()
|
||||
if not info then return false, err end
|
||||
local newLowLockPage = string.sub(currentLowLockPage,1,4)..'0000'
|
||||
io.write('Clearing lock bytes on page 0x02...')
|
||||
resp, err = sendWithResponse('A202'..newLowLockPage, {connect = true, ignore_response = false, keep_signal = true, append_crc = true})
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
end
|
||||
|
||||
-- clear lock bytes on page 0x24
|
||||
io.write('Clearing lock bytes on page 0x24...')
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
resp, err = sendWithResponse('A224000000BD')
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
|
||||
-- clear configs
|
||||
io.write('Clearing cfg0 and cfg1...')
|
||||
resp, err = sendWithResponse('A225000000FF')
|
||||
if err ~= nil then return false, err end
|
||||
resp, err = sendWithResponse('A22600050000')
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
|
||||
-- clear password
|
||||
io.write('Reseting password (and pack) to default ('.._defaultPassword..') and 0000...')
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
resp, err = sendWithResponse('A227'.._defaultPassword)
|
||||
if err ~= nil then return false, err end
|
||||
resp, err = sendWithResponse('A22800000000')
|
||||
if err ~= nil then return false, err end
|
||||
if not setPassword(_defaultPassword) then return false, 'Unable to set password' end
|
||||
info, err = reconnect()
|
||||
if not info then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
|
||||
-- clear other blocks
|
||||
for i = 3, 0x23 do
|
||||
local cblock = string.format('%02x',i)
|
||||
io.write('Clearing block 0x'..cblock..'...')
|
||||
resp, err = sendWithResponse('A2'..cblock..'00000000')
|
||||
if err ~= nil then return false, err end
|
||||
print(ansicolors.green..'done'..ansicolors.reset..'.')
|
||||
end
|
||||
|
||||
print(ansicolors.green..'The tag has been wiped.'..ansicolors.reset)
|
||||
|
||||
lib14a.disconnect()
|
||||
return true
|
||||
end
|
||||
--
|
||||
|
||||
-- Prints help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print(ansicolors.cyan..'Usage'..ansicolors.reset)
|
||||
print(usage)
|
||||
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
|
||||
print(arguments)
|
||||
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
|
||||
print(example)
|
||||
end
|
||||
---
|
||||
|
||||
-- The main entry point
|
||||
local function main(args)
|
||||
if #args == 0 then return help() end
|
||||
|
||||
local dumpFilename = nil
|
||||
|
||||
for opt, value in getopt.getopt(args, 'hf:k:rw') do
|
||||
local res, err
|
||||
res = true
|
||||
if opt == "h" then return help() end
|
||||
if opt == "f" then dumpFilename = value end
|
||||
if opt == 'k' then res, err = setPassword(value) end
|
||||
if opt == 'r' then res, err = writeDump(dumpFilename) end
|
||||
if opt == 'w' then res, err = wipe() end
|
||||
if not res then return error(err) end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
main(args)
|
||||
@@ -90,13 +90,14 @@ def lprint(s='', end='\n', flush=False, prompt="[" + color("=", fg="yellow") +
|
||||
- logfile (R)
|
||||
"""
|
||||
s = f"{prompt}" + f"\n{prompt}".join(s.split('\n'))
|
||||
print(s, end=end, flush=flush)
|
||||
safe_s = s.encode('utf-8', errors='ignore').decode('utf-8')
|
||||
print(safe_s, end=end, flush=flush)
|
||||
|
||||
if log is True:
|
||||
global logbuffer
|
||||
if logfile is not None:
|
||||
with open(logfile, 'a', encoding='utf-8') as f:
|
||||
f.write(s + end)
|
||||
f.write(safe_s + end)
|
||||
else:
|
||||
# buffering
|
||||
logbuffer += s + end
|
||||
|
||||
+1
-1
@@ -600,7 +600,7 @@ static command_t CommandTable[] = {
|
||||
{"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"},
|
||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"vas", CmdHFVAS, AlwaysAvailable, "{ Apple Value Added Service }"},
|
||||
{"vas", CmdHFVAS, AlwaysAvailable, "{ Apple Value Added Service... }"},
|
||||
#ifdef HAVE_GD
|
||||
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
|
||||
#endif
|
||||
|
||||
@@ -914,7 +914,7 @@ int CmdHF14ASim(const char *Cmd) {
|
||||
bool keypress = kbd_enter_pressed();
|
||||
while (keypress == false) {
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0)
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false)
|
||||
continue;
|
||||
|
||||
if (resp.status != PM3_SUCCESS)
|
||||
@@ -1403,10 +1403,10 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
|
||||
bool extendedAPDU = arg_get_lit(ctx, 6);
|
||||
int le = arg_get_int_def(ctx, 7, 0);
|
||||
|
||||
|
||||
uint8_t data[PM3_CMD_DATA_SIZE];
|
||||
int datalen = 0;
|
||||
|
||||
@@ -4037,7 +4037,7 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
||||
bool keypress = kbd_enter_pressed();
|
||||
while (keypress == false) {
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0) {
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -3029,7 +3029,9 @@ int infoHF14B(bool verbose, bool do_aid_search) {
|
||||
|
||||
// try unknown 14b read commands (to be identified later)
|
||||
// could be read of calypso, CEPAS, moneo, or pico pass.
|
||||
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found");
|
||||
if (verbose) {
|
||||
PrintAndLogEx(FAILED, "no 14443-B tag found");
|
||||
}
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user