Merge remote-tracking branch 'origin/master' into emrtd

This commit is contained in:
Ave 2020-12-23 22:29:21 +03:00
commit fab5092c03
18 changed files with 208 additions and 174 deletions

View file

@ -158,17 +158,17 @@ static void download_instructions(uint8_t t) {
// Save to flash if file doesn't exist. // Save to flash if file doesn't exist.
// Write over file if size of flash file is less than new datalen // Write over file if size of flash file is less than new datalen
static void save_to_flash(uint8_t *data, uint16_t datalen, char * filename) { static void save_to_flash(uint8_t *data, uint16_t datalen, char *filename) {
rdv40_spiffs_lazy_mount(); rdv40_spiffs_lazy_mount();
char fn[SPIFFS_OBJ_NAME_LEN]; char fn[SPIFFS_OBJ_NAME_LEN];
if (filename == NULL){ if (filename == NULL) {
sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin", sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin",
data[0], data[1], data[2], data[3], data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7] data[4], data[5], data[6], data[7]
); );
} else { } else {
int name_len = SPIFFS_OBJ_NAME_LEN; int name_len = SPIFFS_OBJ_NAME_LEN;
int filename_len = strlen(filename); int filename_len = strlen(filename);
@ -176,7 +176,7 @@ static void save_to_flash(uint8_t *data, uint16_t datalen, char * filename) {
// if the given name len longer than buffer allows, cut it down to size // if the given name len longer than buffer allows, cut it down to size
name_len = (name_len >= SPIFFS_OBJ_NAME_LEN) ? SPIFFS_OBJ_NAME_LEN : filename_len; name_len = (name_len >= SPIFFS_OBJ_NAME_LEN) ? SPIFFS_OBJ_NAME_LEN : filename_len;
memcpy(fn, filename, name_len); memcpy(fn, filename, name_len);
} }
int res; int res;
if (exists_in_spiffs(fn) == false) { if (exists_in_spiffs(fn) == false) {
@ -558,12 +558,12 @@ static int dump_sim_mode(void) {
} }
} }
switch_off(); switch_off();
char * temp_file = HF_ICALSSS_READSIM_TEMP_BIN; char *temp_file = HF_ICALSSS_READSIM_TEMP_BIN;
save_to_flash(card_data, (start_block + dumped) * 8, temp_file); save_to_flash(card_data, (start_block + dumped) * 8, temp_file);
Dbprintf("%u bytes saved", (start_block + dumped) * 8); Dbprintf("%u bytes saved", (start_block + dumped) * 8);
if (((start_block + dumped) * 8) > 0) { if (((start_block + dumped) * 8) > 0) {
break; //switch to sim mode break; //switch to sim mode
} }
} }
@ -577,7 +577,7 @@ static int dump_sim_mode(void) {
if (res == SPIFFS_OK) { if (res == SPIFFS_OK) {
Dbprintf("loaded " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN) " (%u bytes)", fsize); Dbprintf("loaded " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN) " (%u bytes)", fsize);
} }
Dbprintf("simming " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN)); Dbprintf("simming " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN));
iclass_simulate(ICLASS_SIM_MODE_FULL, 0, false, NULL, NULL, NULL); iclass_simulate(ICLASS_SIM_MODE_FULL, 0, false, NULL, NULL, NULL);

View file

@ -190,9 +190,9 @@ static uint32_t get_rising_pulse_length(void) {
static uint32_t get_pulse_length(edge_detection_t edge) { static uint32_t get_pulse_length(edge_detection_t edge) {
if(edge == RISING_EDGE) if (edge == RISING_EDGE)
return get_rising_pulse_length(); return get_rising_pulse_length();
else if(edge == FALLING_EDGE) else if (edge == FALLING_EDGE)
return get_falling_pulse_length(); return get_falling_pulse_length();
return 0; return 0;
@ -292,11 +292,11 @@ static bool check_ack(void) {
// ACK 64 + 64 // ACK 64 + 64
// NACK 64 + 48 // NACK 64 + 48
if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) && 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 // ACK
return true; return true;
} }
// Othewise it was a NACK or Listen Window // Othewise it was a NACK or Listen Window
return false; return false;
} }
@ -426,10 +426,10 @@ static bool find_listen_window(bool command) {
96 ( 64 + 32 ) 96 ( 64 + 32 )
64 ( 32 + 16 +16 )*/ 64 ( 32 + 16 +16 )*/
if (check_pulse_length(get_pulse_length(RISING_EDGE), (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD) && if (check_pulse_length(get_pulse_length(RISING_EDGE), (2 * EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD) &&
check_pulse_length(get_pulse_length(RISING_EDGE), (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD) && check_pulse_length(get_pulse_length(RISING_EDGE), (2 * EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD) &&
check_pulse_length(get_pulse_length(FALLING_EDGE), (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_FULL_PERIOD) && check_pulse_length(get_pulse_length(FALLING_EDGE), (2 * EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_FULL_PERIOD) &&
check_pulse_length(get_pulse_length(FALLING_EDGE), EM4X70_T_TAG_FULL_PERIOD + (2*EM4X70_T_TAG_HALF_PERIOD))) { check_pulse_length(get_pulse_length(FALLING_EDGE), EM4X70_T_TAG_FULL_PERIOD + (2 * EM4X70_T_TAG_HALF_PERIOD))) {
if (command) { if (command) {
/* Here we are after the 64 duration edge. /* Here we are after the 64 duration edge.
@ -438,7 +438,7 @@ static bool find_listen_window(bool command) {
* *
* I've found between 4-5 quarter periods (32-40) works best * I've found between 4-5 quarter periods (32-40) works best
*/ */
WaitTicks( 4 * EM4X70_T_TAG_QUARTER_PERIOD ); WaitTicks(4 * EM4X70_T_TAG_QUARTER_PERIOD);
// Send RM Command // Send RM Command
em4x70_send_bit(0); em4x70_send_bit(0);
em4x70_send_bit(0); em4x70_send_bit(0);
@ -559,7 +559,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
WaitTicks(6 * EM4X70_T_TAG_FULL_PERIOD); WaitTicks(6 * EM4X70_T_TAG_FULL_PERIOD);
// wait until we get the transition from 1's to 0's which is 1.5 full windows // wait until we get the transition from 1's to 0's which is 1.5 full windows
for(int i = 0; i < EM4X70_T_READ_HEADER_LEN; i++) { for (int i = 0; i < EM4X70_T_READ_HEADER_LEN; i++) {
pl = get_pulse_length(edge); pl = get_pulse_length(edge);
if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) { if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
foundheader = true; foundheader = true;
@ -575,7 +575,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
// Skip next 3 0's, header check consumes the first 0 // Skip next 3 0's, header check consumes the first 0
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// If pulse length is not 1 bit, then abort early // If pulse length is not 1 bit, then abort early
if(!check_pulse_length(get_pulse_length(edge), EM4X70_T_TAG_FULL_PERIOD)) { if (!check_pulse_length(get_pulse_length(edge), EM4X70_T_TAG_FULL_PERIOD)) {
return 0; return 0;
} }
} }
@ -745,8 +745,8 @@ void em4x70_write_pin(em4x70_data_t *etd) {
if (em4x70_read_id()) { if (em4x70_read_id()) {
// Write new PIN // Write new PIN
if( (write( etd->pin & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) && if ((write(etd->pin & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) &&
(write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) { (write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) {
// Now Try to authenticate using the new PIN // Now Try to authenticate using the new PIN
@ -784,13 +784,13 @@ void em4x70_write_key(em4x70_data_t *etd) {
// Read ID to ensure we can write to card // Read ID to ensure we can write to card
if (em4x70_read_id()) { if (em4x70_read_id()) {
status = 1; status = 1;
// Write each crypto block
for(int i = 0; i < 6; i++) {
uint16_t key_word = (etd->crypt_key[(i*2)+1] << 8) + etd->crypt_key[i*2]; // Write each crypto block
for (int i = 0; i < 6; i++) {
uint16_t key_word = (etd->crypt_key[(i * 2) + 1] << 8) + etd->crypt_key[i * 2];
// Write each word, abort if any failure occurs // Write each word, abort if any failure occurs
if (write(key_word, 9-i) != PM3_SUCCESS) { if (write(key_word, 9 - i) != PM3_SUCCESS) {
status = 0; status = 0;
break; break;
} }

View file

@ -20,7 +20,7 @@ typedef struct {
typedef enum { typedef enum {
RISING_EDGE, RISING_EDGE,
FALLING_EDGE FALLING_EDGE
}edge_detection_t; } edge_detection_t;
void em4x70_info(em4x70_data_t *etd); void em4x70_info(em4x70_data_t *etd);
void em4x70_write(em4x70_data_t *etd); void em4x70_write(em4x70_data_t *etd);

View file

@ -82,7 +82,7 @@ if (NOT SKIPREADLINE EQUAL 1)
endif (APPLE) endif (APPLE)
if (EMBED_READLINE) if (EMBED_READLINE)
ExternalProject_Add(ncurses ExternalProject_Add(ncurses
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz
PREFIX deps/ncurses PREFIX deps/ncurses
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib
@ -94,7 +94,7 @@ if (NOT SKIPREADLINE EQUAL 1)
ExternalProject_Add_StepTargets(ncurses configure build install) ExternalProject_Add_StepTargets(ncurses configure build install)
ExternalProject_Add(readline ExternalProject_Add(readline
URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz
PREFIX deps/readline PREFIX deps/readline
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static

View file

@ -53,7 +53,7 @@ int CmdHFSearch(const char *Cmd) {
"Will try to find a HF read out of the unknown tag.\n" "Will try to find a HF read out of the unknown tag.\n"
"Continues to search for all different HF protocols.", "Continues to search for all different HF protocols.",
"hf sniff" "hf sniff"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_param_end arg_param_end
@ -219,7 +219,7 @@ int CmdHFTune(const char *Cmd) {
uint32_t max = 0xFFFF; uint32_t max = 0xFFFF;
bool first = true; bool first = true;
print_progress(0, max, style); print_progress(0, max, style);
// loop forever (till button pressed) if iter = 0 (default) // loop forever (till button pressed) if iter = 0 (default)
for (uint8_t i = 0; iter == 0 || i < iter; i++) { for (uint8_t i = 0; iter == 0 || i < iter; i++) {
@ -244,7 +244,7 @@ int CmdHFTune(const char *Cmd) {
max = (volt * 1.03); max = (volt * 1.03);
first = false; first = false;
} }
if ( volt > max) { if (volt > max) {
max = (volt * 1.03); max = (volt * 1.03);
} }
print_progress(volt, max, style); print_progress(volt, max, style);
@ -274,7 +274,7 @@ int CmdHFSniff(const char *Cmd) {
"Press button to quit the sniffing.", "Press button to quit the sniffing.",
"hf sniff\n" "hf sniff\n"
"hf sniff --sp 1000 --st 0 -> skip 1000 pairs, skip 0 triggers" "hf sniff --sp 1000 --st 0 -> skip 1000 pairs, skip 0 triggers"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_u64_0(NULL, "sp", "<dec>", "skip sample pairs"), arg_u64_0(NULL, "sp", "<dec>", "skip sample pairs"),

View file

@ -2001,7 +2001,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
if (do_aid_search) { if (do_aid_search) {
PrintAndLogEx(INFO, "-------------------- " _CYAN_("AID Search") " --------------------"); PrintAndLogEx(INFO, "-------------------- " _CYAN_("AID Search") " --------------------");
bool found = false; bool found = false;

View file

@ -82,9 +82,9 @@ static void hf14b_aid_search(bool verbose) {
bool activate_field = true; bool activate_field = true;
for (elmindx = 0; elmindx < json_array_size(root); elmindx++) { for (elmindx = 0; elmindx < json_array_size(root); elmindx++) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
break; break;
} }
json_t *data = AIDSearchGetElm(root, elmindx); json_t *data = AIDSearchGetElm(root, elmindx);
uint8_t vaid[200] = {0}; uint8_t vaid[200] = {0};

View file

@ -1017,7 +1017,7 @@ int dumpHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab
// Add EF_SOD to the list // Add EF_SOD to the list
filelist[filelistlen++] = 0x77; filelist[filelistlen++] = 0x77;
// Dump all files in the file list // Dump all files in the file list
for (size_t i = 0; i < filelistlen; i++) { for (int i = 0; i < filelistlen; i++) {
emrtd_dg_t *dg = emrtd_tag_to_dg(filelist[i]); emrtd_dg_t *dg = emrtd_tag_to_dg(filelist[i]);
if (dg == NULL) { if (dg == NULL) {
PrintAndLogEx(INFO, "File tag not found, skipping: %02X", filelist[i]); PrintAndLogEx(INFO, "File tag not found, skipping: %02X", filelist[i]);

View file

@ -15,7 +15,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> // tolower #include <ctype.h> // tolower
#include "cliparser.h"
#include "cmdparser.h" // command_t #include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "comms.h" // clearCommandBuffer #include "comms.h" // clearCommandBuffer
@ -24,35 +24,28 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static int usage_epa_collect(void) {
PrintAndLogEx(NORMAL, "Tries to collect nonces when doing part of PACE protocol.\n"
"\n"
"Usage: hf epa cnonces <m> <n> <d>\n"
"Options:\n"
"\t<m> nonce size\n"
"\t<n> number of nonces to collect\n"
"\t<d> delay between\n"
"\n"
"Example:\n"
_YELLOW_("\thf epa cnonces 4 4 1")
);
return PM3_SUCCESS;
}
// Perform (part of) the PACE protocol // Perform (part of) the PACE protocol
static int CmdHFEPACollectPACENonces(const char *Cmd) { static int CmdHFEPACollectPACENonces(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf epa cnonces",
"Tries to collect nonces when doing part of PACE protocol.",
"hf epa cnonces --size 4 --num 4 --delay 1");
char cmdp = tolower(param_getchar(Cmd, 0)); void *argtable[] = {
if (cmdp == 'h') return usage_epa_collect(); arg_param_begin,
arg_int1(NULL, "size", "<dec>", "nonce size"),
arg_int1(NULL, "num", "<dec>", "number of nonces to collect"),
arg_int1("d", "delay", "<dec>", "delay between attempts"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
// requested nonce size
uint32_t m = 0;
// requested number of Nonces
uint32_t n = 0;
// delay between requests
uint32_t d = 0;
sscanf(Cmd, "%u %u %u", &m, &n, &d); int m = arg_get_int_def(ctx, 1, 0);
int n = arg_get_int_def(ctx, 2, 0);
int d = arg_get_int_def(ctx, 3, 0);
CLIParserFree(ctx);
// values are expected to be > 0 // values are expected to be > 0
m = m > 0 ? m : 1; m = m > 0 ? m : 1;
@ -99,54 +92,51 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
// perform the PACE protocol by replaying APDUs // perform the PACE protocol by replaying APDUs
static int CmdHFEPAPACEReplay(const char *Cmd) { static int CmdHFEPAPACEReplay(const char *Cmd) {
// the 4 APDUs which are replayed + their lengths CLIParserContext *ctx;
uint8_t msesa_apdu[41] = {0}, gn_apdu[8] = {0}, map_apdu[75] = {0}; CLIParserInit(&ctx, "hf epa preplay",
uint8_t pka_apdu[75] = {0}, ma_apdu[18] = {0}, apdu_lengths[5] = {0}; "Perform PACE protocol by replaying given APDUs",
"hf epa preplay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D");
void *argtable[] = {
arg_param_begin,
arg_str1(NULL, "mse", "<hex>", "msesa APDU"),
arg_str1(NULL, "get", "<hex>", "gn APDU"),
arg_str1(NULL, "map", "<hex>", "map APDU"),
arg_str1(NULL, "pka", "<hex>", "pka APDU"),
arg_str1(NULL, "ma", "<hex>", "ma APDU"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int msesa_len = 0;
uint8_t msesa_apdu[41] = {0};
CLIGetHexWithReturn(ctx, 1, msesa_apdu, &msesa_len);
int gn_len = 0;
uint8_t gn_apdu[8] = {0};
CLIGetHexWithReturn(ctx, 2, gn_apdu, &gn_len);
int map_len = 0;
uint8_t map_apdu[75] = {0};
CLIGetHexWithReturn(ctx, 3, map_apdu, &map_len);
int pka_len = 0;
uint8_t pka_apdu[75] = {0};
CLIGetHexWithReturn(ctx, 4, pka_apdu, &pka_len);
int ma_len = 0;
uint8_t ma_apdu[18] = {0};
CLIGetHexWithReturn(ctx, 5, ma_apdu, &ma_len);
CLIParserFree(ctx);
uint8_t apdu_lengths[5] = {msesa_len, gn_len, map_len, pka_len, ma_len};
// pointers to the arrays to be able to iterate // pointers to the arrays to be able to iterate
uint8_t *apdus[] = {msesa_apdu, gn_apdu, map_apdu, pka_apdu, ma_apdu}; uint8_t *apdus[] = {msesa_apdu, gn_apdu, map_apdu, pka_apdu, ma_apdu};
// usage message
static const char *usage_msg =
"Please specify 5 APDUs separated by spaces. "
"Example:\n preplay 0022C1A4 1068000000 1086000002 1234ABCDEF 1A2B3C4D";
// Proxmark response // Proxmark response
PacketResponseNG resp; PacketResponseNG resp;
int skip = 0, skip_add = 0, scan_return;
// for each APDU
for (int i = 0; i < ARRAYLEN(apdu_lengths); i++) {
// scan to next space or end of string
while (Cmd[skip] != ' ' && Cmd[skip] != '\0') {
// convert
scan_return = sscanf(Cmd + skip,
"%2" SCNx8 "%n",
apdus[i] + apdu_lengths[i],
&skip_add
);
if (scan_return < 1) {
PrintAndLogEx(INFO, (char *)usage_msg);
PrintAndLogEx(WARNING, "Not enough APDUs! Try again!");
return PM3_SUCCESS;
}
skip += skip_add;
apdu_lengths[i]++;
}
// break on EOF
if (Cmd[skip] == '\0') {
if (i < ARRAYLEN(apdu_lengths) - 1) {
PrintAndLogEx(INFO, (char *)usage_msg);
return PM3_SUCCESS;
}
break;
}
// skip the space
skip++;
}
// transfer the APDUs to the Proxmark // transfer the APDUs to the Proxmark
uint8_t data[PM3_CMD_DATA_SIZE]; uint8_t data[PM3_CMD_DATA_SIZE];
// fast push mode // fast push mode
@ -205,8 +195,8 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "<m> <n> <d> Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses"}, {"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"},
{"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs"}, {"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -48,10 +48,18 @@ static int cmd_hf_fido_list(const char *Cmd) {
return CmdTraceList(args); return CmdTraceList(args);
} }
static int cmd_hf_fido_info(const char *cmd) { static int cmd_hf_fido_info(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf fido info",
"Get info from Fido tags",
"hf fido info");
if (cmd && strlen(cmd) > 0) void *argtable[] = {
PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n"); arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
// info about 14a part // info about 14a part
infoHF14A(false, false, false); infoHF14A(false, false, false);

View file

@ -18,7 +18,6 @@
#include "cmdparser.h" // command_t #include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "cmdtrace.h" #include "cmdtrace.h"
#include "cliparser.h"
#include "util_posix.h" #include "util_posix.h"
#include "comms.h" #include "comms.h"
#include "des.h" #include "des.h"

View file

@ -306,7 +306,7 @@ static int CmdLFTune(const char *Cmd) {
uint32_t max = 71000; uint32_t max = 71000;
bool first = true; bool first = true;
print_progress(0, max, style); print_progress(0, max, style);
// loop forever (till button pressed) if iter = 0 (default) // loop forever (till button pressed) if iter = 0 (default)
for (uint8_t i = 0; iter == 0 || i < iter; i++) { for (uint8_t i = 0; iter == 0 || i < iter; i++) {
@ -328,11 +328,11 @@ static int CmdLFTune(const char *Cmd) {
uint32_t volt = resp.data.asDwords[0]; uint32_t volt = resp.data.asDwords[0];
if (first) { if (first) {
max = (volt * 1.03); max = (volt * 1.03);
first = false; first = false;
} }
if ( volt > max) { if (volt > max) {
max = (volt * 1.03); max = (volt * 1.03);
} }
print_progress(volt, max, style); print_progress(volt, max, style);
} }

View file

@ -286,7 +286,7 @@ int CmdEM4x50EView(const char *Cmd) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
// valid em4x50 data? // valid em4x50 data?
uint32_t serial = bytes_to_num(data + 4 * EM4X50_DEVICE_SERIAL, 4); uint32_t serial = bytes_to_num(data + 4 * EM4X50_DEVICE_SERIAL, 4);
uint32_t device_id = bytes_to_num(data + 4 * EM4X50_DEVICE_ID, 4); uint32_t device_id = bytes_to_num(data + 4 * EM4X50_DEVICE_ID, 4);

View file

@ -175,7 +175,7 @@ int CmdRem(const char *Cmd) {
}; };
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
struct arg_str* foo = arg_get_str(ctx, 1); struct arg_str *foo = arg_get_str(ctx, 1);
size_t count = 0; size_t count = 0;
size_t len = 0; size_t len = 0;
do { do {

View file

@ -314,7 +314,7 @@ void preferences_load_callback(json_t *root) {
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0) if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0)
session.supports_colors = (bool)b1; session.supports_colors = (bool)b1;
// bar mode // bar mode
if (json_unpack_ex(root, &up_error, 0, "{s:s}", "show.bar.mode", &s1) == 0) { if (json_unpack_ex(root, &up_error, 0, "{s:s}", "show.bar.mode", &s1) == 0) {
strncpy(tempStr, s1, sizeof(tempStr) - 1); strncpy(tempStr, s1, sizeof(tempStr) - 1);
str_lower(tempStr); str_lower(tempStr);

View file

@ -14,7 +14,9 @@
#if !defined(_WIN32) #if !defined(_WIN32)
#define _POSIX_C_SOURCE 200112L #define _POSIX_C_SOURCE 200112L
#endif #endif
#ifdef HAVE_READLINE
#include <readline/readline.h>
#endif
#include "ui.h" #include "ui.h"
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
@ -625,58 +627,84 @@ void iceSimple_Filter(int *data, const size_t len, uint8_t k) {
} }
void print_progress(size_t count, uint64_t max, barMode_t style) { void print_progress(size_t count, uint64_t max, barMode_t style) {
int cols = 100 + 35;
#ifdef HAVE_READLINE
static int prev_cols = 0;
int rows;
rl_reset_screen_size(); // refresh Readline idea of the actual screen width
rl_get_screen_size(&rows, &cols);
(void) rows;
if (prev_cols > cols) {
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ "");
}
prev_cols = cols;
#endif
int width = cols - 35;
#define PERCENTAGE(V, T) ((V * width) / T)
// x/8 fractional part of the percentage
#define PERCENTAGEFRAC(V, T) ((int)(((((float)V * width) / T) - ((V * width) / T)) * 8))
#define PERCENTAGE(V, T) (100 - (((T - V) * 100) / T)) const char *smoothtable[] = {
"\xe2\x80\x80",
/* "\xe2\x96\x8F",
typedef struct smooth_s { "\xe2\x96\x8E",
const char *bar; "\xe2\x96\x8D",
} smooth_t; "\xe2\x96\x8C",
"\xe2\x96\x8B",
static smooth_t smoothtable[] = { "\xe2\x96\x8A",
{"\xe2\x96\x8F"}, "\xe2\x96\x89",
{"\xe2\x96\x8E"}, "\xe2\x96\x88",
{"\xe2\x96\x8D"},
{"\xe2\x96\x8C"},
{"\xe2\x96\x8B"},
{"\xe2\x96\x8A"},
{"\xe2\x96\x89"},
{"\xe2\x96\x88"},
}; };
*/
uint8_t mode = session.emoji_mode == EMOJI;
const char *block[] = {"#", "\xe2\x96\x88"};
// use a 3-byte space in emoji mode to ease computations
const char *space[] = {" ", "\xe2\x80\x80"};
uint8_t unit = strlen(block[mode]);
// +1 for \0 // +1 for \0
char *bar = calloc(100 + 1, sizeof(uint8_t)); char *bar = calloc(unit * width + 1, sizeof(uint8_t));
uint8_t value = PERCENTAGE(count, max); uint8_t value = PERCENTAGE(count, max);
int i = 0;
// prefix is added already. // prefix is added already.
memset(bar + strlen(bar), 0x23, value); for (; i < unit * value; i += unit) {
memcpy(bar + i, block[mode], unit);
}
// add last block
if (mode == 1) {
memcpy(bar + i, smoothtable[PERCENTAGEFRAC(count, max)], unit);
} else {
memcpy(bar + i, space[mode], unit);
}
i += unit;
// add spaces // add spaces
memset(bar + strlen(bar), 0x2E, 100 - value); for (; i < unit * width; i += unit) {
memcpy(bar + i, space[mode], unit);
}
// color buffer // color buffer
uint8_t collen = 100 + 1 + 40; size_t collen = strlen(bar) + 40;
char *cbar = calloc(collen, sizeof(uint8_t)); char *cbar = calloc(collen, sizeof(uint8_t));
// Add colors // Add colors
snprintf(cbar, collen, _GREEN_("%.*s"), 60, bar); int p60 = unit * (width * 60 / 100);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), 20, bar + 60); int p20 = unit * (width * 20 / 100);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), 20, bar + 80); snprintf(cbar, collen, _GREEN_("%.*s"), p60, bar);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), p20, bar + p60);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), unit * width - p60 - p20, bar + p60 + p20);
uint8_t len = collen + 1 + 1 + 30; size_t len = strlen(cbar) + 32;
char *buffer = calloc(len, sizeof(uint8_t)); char *buffer = calloc(len, sizeof(uint8_t));
switch(style) { switch (style) {
case STYLE_BAR: { case STYLE_BAR: {
sprintf(buffer, "%s", cbar); sprintf(buffer, "%s", cbar);
printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, buffer); printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, buffer);
break; break;
} }
case STYLE_MIXED: { case STYLE_MIXED: {
sprintf(buffer, "%s [ %zu mV / %3u V ]", cbar, count, (uint32_t)(count / 1000)); sprintf(buffer, "%s [ %zu mV / %3u V ]", cbar, count, (uint32_t)(count / 1000));
printf("\b%c[2K\r[" _YELLOW_("=")"] %s ", 27, buffer); printf("\b%c[2K\r[" _YELLOW_("=")"] %s ", 27, buffer);
break; break;
} }
case STYLE_VALUE: { case STYLE_VALUE: {
@ -685,8 +713,8 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
} }
} }
fflush(stdout); fflush(stdout);
free(buffer); free(buffer);
free(bar); free(bar);
free(cbar); free(cbar);
} }

View file

@ -56,8 +56,6 @@ hf 15 restore
hf 15 wrbl hf 15 wrbl
hf 15 writeafi hf 15 writeafi
hf 15 writedsfid hf 15 writedsfid
hf epa cnonces
hf epa preplay
hf felica reader hf felica reader
hf felica sniff hf felica sniff
hf felica raw hf felica raw
@ -73,7 +71,6 @@ hf felica rqspecver
hf felica resetmode hf felica resetmode
hf felica litesim hf felica litesim
hf felica litedump hf felica litedump
hf fido info
hf mf darkside hf mf darkside
hf mf nested hf mf nested
hf mf hardnested hf mf hardnested

View file

@ -126,7 +126,7 @@ Check column "offline" for their availability.
### hf 14a ### hf 14a
{ ISO14443A RFIDs... } { ISO14443A RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -147,7 +147,7 @@ Check column "offline" for their availability.
### hf 14b ### hf 14b
{ ISO14443B RFIDs... } { ISO14443B RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -167,7 +167,7 @@ Check column "offline" for their availability.
### hf 15 ### hf 15
{ ISO15693 RFIDs... } { ISO15693 RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -193,7 +193,7 @@ Check column "offline" for their availability.
### hf epa ### hf epa
{ German Identification Card... } { German Identification Card... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -202,9 +202,21 @@ Check column "offline" for their availability.
|`hf epa preplay `|N |`<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs` |`hf epa preplay `|N |`<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs`
### hf emrtd
{ Machine Readable Travel Document... }
|command |offline |description
|------- |------- |-----------
|`hf emrtd help `|Y |`This help`
|`hf emrtd dump `|N |`Dump eMRTD files to binary files`
|`hf emrtd info `|Y |`Display info about an eMRTD`
|`hf emrtd list `|Y |`List ISO 14443A/7816 history`
### hf felica ### hf felica
{ ISO18092 / FeliCa RFIDs... } { ISO18092 / FeliCa RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -229,7 +241,7 @@ Check column "offline" for their availability.
### hf fido ### hf fido
{ FIDO and FIDO2 authenticators... } { FIDO and FIDO2 authenticators... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -244,7 +256,7 @@ Check column "offline" for their availability.
### hf iclass ### hf iclass
{ ICLASS RFIDs... } { ICLASS RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -275,7 +287,7 @@ Check column "offline" for their availability.
### hf legic ### hf legic
{ LEGIC RFIDs... } { LEGIC RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -296,7 +308,7 @@ Check column "offline" for their availability.
### hf lto ### hf lto
{ LTO Cartridge Memory RFIDs... } { LTO Cartridge Memory RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -311,7 +323,7 @@ Check column "offline" for their availability.
### hf mf ### hf mf
{ MIFARE RFIDs... } { MIFARE RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -363,7 +375,7 @@ Check column "offline" for their availability.
### hf mfp ### hf mfp
{ MIFARE Plus RFIDs... } { MIFARE Plus RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -383,7 +395,7 @@ Check column "offline" for their availability.
### hf mfu ### hf mfu
{ MIFARE Ultralight RFIDs... } { MIFARE Ultralight RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -406,7 +418,7 @@ Check column "offline" for their availability.
### hf mfdes ### hf mfdes
{ MIFARE Desfire RFIDs... } { MIFARE Desfire RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -436,7 +448,7 @@ Check column "offline" for their availability.
### hf st ### hf st
{ ST Rothult RFIDs... } { ST Rothult RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -451,7 +463,7 @@ Check column "offline" for their availability.
### hf thinfilm ### hf thinfilm
{ Thinfilm RFIDs... } { Thinfilm RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -463,7 +475,7 @@ Check column "offline" for their availability.
### hf topaz ### hf topaz
{ TOPAZ (NFC Type 1) RFIDs... } { TOPAZ (NFC Type 1) RFIDs... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
@ -478,7 +490,7 @@ Check column "offline" for their availability.
### hf waveshare ### hf waveshare
{ Waveshare NFC ePaper... } { Waveshare NFC ePaper... }
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------