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.
// 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();
char fn[SPIFFS_OBJ_NAME_LEN];
if (filename == NULL){
sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin",
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]
);
if (filename == NULL) {
sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin",
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]
);
} else {
int name_len = SPIFFS_OBJ_NAME_LEN;
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
name_len = (name_len >= SPIFFS_OBJ_NAME_LEN) ? SPIFFS_OBJ_NAME_LEN : filename_len;
memcpy(fn, filename, name_len);
}
}
int res;
if (exists_in_spiffs(fn) == false) {
@ -558,12 +558,12 @@ static int dump_sim_mode(void) {
}
}
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);
Dbprintf("%u bytes saved", (start_block + dumped) * 8);
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) {
Dbprintf("loaded " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN) " (%u bytes)", fsize);
}
Dbprintf("simming " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN));
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) {
if(edge == RISING_EDGE)
if (edge == RISING_EDGE)
return get_rising_pulse_length();
else if(edge == FALLING_EDGE)
else if (edge == FALLING_EDGE)
return get_falling_pulse_length();
return 0;
@ -292,11 +292,11 @@ static bool check_ack(void) {
// ACK 64 + 64
// NACK 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;
}
}
// Othewise it was a NACK or Listen Window
return false;
}
@ -426,10 +426,10 @@ static bool find_listen_window(bool command) {
96 ( 64 + 32 )
64 ( 32 + 16 +16 )*/
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(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))) {
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(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))) {
if (command) {
/* 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
*/
WaitTicks( 4 * EM4X70_T_TAG_QUARTER_PERIOD );
WaitTicks(4 * EM4X70_T_TAG_QUARTER_PERIOD);
// Send RM Command
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);
// 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);
if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) {
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
for (int i = 0; i < 3; i++) {
// 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;
}
}
@ -745,8 +745,8 @@ void em4x70_write_pin(em4x70_data_t *etd) {
if (em4x70_read_id()) {
// Write new PIN
if( (write( etd->pin & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) &&
(write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) {
if ((write(etd->pin & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) &&
(write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) {
// 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
if (em4x70_read_id()) {
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
if (write(key_word, 9-i) != PM3_SUCCESS) {
if (write(key_word, 9 - i) != PM3_SUCCESS) {
status = 0;
break;
}

View file

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

View file

@ -82,7 +82,7 @@ if (NOT SKIPREADLINE EQUAL 1)
endif (APPLE)
if (EMBED_READLINE)
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
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
@ -94,7 +94,7 @@ if (NOT SKIPREADLINE EQUAL 1)
ExternalProject_Add_StepTargets(ncurses configure build install)
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
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

View file

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

View file

@ -82,9 +82,9 @@ static void hf14b_aid_search(bool verbose) {
bool activate_field = true;
for (elmindx = 0; elmindx < json_array_size(root); elmindx++) {
if (kbd_enter_pressed()) {
break;
}
if (kbd_enter_pressed()) {
break;
}
json_t *data = AIDSearchGetElm(root, elmindx);
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
filelist[filelistlen++] = 0x77;
// 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]);
if (dg == NULL) {
PrintAndLogEx(INFO, "File tag not found, skipping: %02X", filelist[i]);

View file

@ -15,7 +15,7 @@
#include <inttypes.h>
#include <stdlib.h>
#include <ctype.h> // tolower
#include "cliparser.h"
#include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN
#include "comms.h" // clearCommandBuffer
@ -24,35 +24,28 @@
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
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));
if (cmdp == 'h') return usage_epa_collect();
void *argtable[] = {
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
m = m > 0 ? m : 1;
@ -99,54 +92,51 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
// perform the PACE protocol by replaying APDUs
static int CmdHFEPAPACEReplay(const char *Cmd) {
// the 4 APDUs which are replayed + their lengths
uint8_t msesa_apdu[41] = {0}, gn_apdu[8] = {0}, map_apdu[75] = {0};
uint8_t pka_apdu[75] = {0}, ma_apdu[18] = {0}, apdu_lengths[5] = {0};
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf epa preplay",
"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
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
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
uint8_t data[PM3_CMD_DATA_SIZE];
// fast push mode
@ -205,8 +195,8 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
static command_t CommandTable[] = {
{"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"},
{"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs"},
{"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"},
{"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"},
{NULL, NULL, NULL, NULL}
};

View file

@ -48,10 +48,18 @@ static int cmd_hf_fido_list(const char *Cmd) {
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)
PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n");
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
// info about 14a part
infoHF14A(false, false, false);

View file

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

View file

@ -306,7 +306,7 @@ static int CmdLFTune(const char *Cmd) {
uint32_t max = 71000;
bool first = true;
print_progress(0, max, style);
print_progress(0, max, style);
// loop forever (till button pressed) if iter = 0 (default)
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];
if (first) {
max = (volt * 1.03);
max = (volt * 1.03);
first = false;
}
if ( volt > max) {
max = (volt * 1.03);
if (volt > max) {
max = (volt * 1.03);
}
print_progress(volt, max, style);
}

View file

@ -286,7 +286,7 @@ int CmdEM4x50EView(const char *Cmd) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
return PM3_ETIMEOUT;
}
// valid em4x50 data?
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);

View file

@ -175,7 +175,7 @@ int CmdRem(const char *Cmd) {
};
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 len = 0;
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)
session.supports_colors = (bool)b1;
// bar mode
// bar mode
if (json_unpack_ex(root, &up_error, 0, "{s:s}", "show.bar.mode", &s1) == 0) {
strncpy(tempStr, s1, sizeof(tempStr) - 1);
str_lower(tempStr);

View file

@ -14,7 +14,9 @@
#if !defined(_WIN32)
#define _POSIX_C_SOURCE 200112L
#endif
#ifdef HAVE_READLINE
#include <readline/readline.h>
#endif
#include "ui.h"
#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) {
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))
/*
typedef struct smooth_s {
const char *bar;
} smooth_t;
static smooth_t smoothtable[] = {
{"\xe2\x96\x8F"},
{"\xe2\x96\x8E"},
{"\xe2\x96\x8D"},
{"\xe2\x96\x8C"},
{"\xe2\x96\x8B"},
{"\xe2\x96\x8A"},
{"\xe2\x96\x89"},
{"\xe2\x96\x88"},
const char *smoothtable[] = {
"\xe2\x80\x80",
"\xe2\x96\x8F",
"\xe2\x96\x8E",
"\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
char *bar = calloc(100 + 1, sizeof(uint8_t));
char *bar = calloc(unit * width + 1, sizeof(uint8_t));
uint8_t value = PERCENTAGE(count, max);
int i = 0;
// 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
memset(bar + strlen(bar), 0x2E, 100 - value);
for (; i < unit * width; i += unit) {
memcpy(bar + i, space[mode], unit);
}
// color buffer
uint8_t collen = 100 + 1 + 40;
size_t collen = strlen(bar) + 40;
char *cbar = calloc(collen, sizeof(uint8_t));
// Add colors
snprintf(cbar, collen, _GREEN_("%.*s"), 60, bar);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _CYAN_("%.*s"), 20, bar + 60);
snprintf(cbar + strlen(cbar), collen - strlen(cbar), _YELLOW_("%.*s"), 20, bar + 80);
int p60 = unit * (width * 60 / 100);
int p20 = unit * (width * 20 / 100);
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));
switch(style) {
switch (style) {
case STYLE_BAR: {
sprintf(buffer, "%s", cbar);
sprintf(buffer, "%s", cbar);
printf("\b%c[2K\r[" _YELLOW_("=")"] %s", 27, buffer);
break;
}
case STYLE_MIXED: {
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;
}
case STYLE_VALUE: {
@ -685,8 +713,8 @@ void print_progress(size_t count, uint64_t max, barMode_t style) {
}
}
fflush(stdout);
free(buffer);
fflush(stdout);
free(buffer);
free(bar);
free(cbar);
}

View file

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

View file

@ -126,7 +126,7 @@ Check column "offline" for their availability.
### hf 14a
{ ISO14443A RFIDs... }
{ ISO14443A RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -147,7 +147,7 @@ Check column "offline" for their availability.
### hf 14b
{ ISO14443B RFIDs... }
{ ISO14443B RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -167,7 +167,7 @@ Check column "offline" for their availability.
### hf 15
{ ISO15693 RFIDs... }
{ ISO15693 RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -193,7 +193,7 @@ Check column "offline" for their availability.
### hf epa
{ German Identification Card... }
{ German Identification Card... }
|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 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
{ ISO18092 / FeliCa RFIDs... }
{ ISO18092 / FeliCa RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -229,7 +241,7 @@ Check column "offline" for their availability.
### hf fido
{ FIDO and FIDO2 authenticators... }
{ FIDO and FIDO2 authenticators... }
|command |offline |description
|------- |------- |-----------
@ -244,7 +256,7 @@ Check column "offline" for their availability.
### hf iclass
{ ICLASS RFIDs... }
{ ICLASS RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -275,7 +287,7 @@ Check column "offline" for their availability.
### hf legic
{ LEGIC RFIDs... }
{ LEGIC RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -296,7 +308,7 @@ Check column "offline" for their availability.
### hf lto
{ LTO Cartridge Memory RFIDs... }
{ LTO Cartridge Memory RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -311,7 +323,7 @@ Check column "offline" for their availability.
### hf mf
{ MIFARE RFIDs... }
{ MIFARE RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -363,7 +375,7 @@ Check column "offline" for their availability.
### hf mfp
{ MIFARE Plus RFIDs... }
{ MIFARE Plus RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -383,7 +395,7 @@ Check column "offline" for their availability.
### hf mfu
{ MIFARE Ultralight RFIDs... }
{ MIFARE Ultralight RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -406,7 +418,7 @@ Check column "offline" for their availability.
### hf mfdes
{ MIFARE Desfire RFIDs... }
{ MIFARE Desfire RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -436,7 +448,7 @@ Check column "offline" for their availability.
### hf st
{ ST Rothult RFIDs... }
{ ST Rothult RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -451,7 +463,7 @@ Check column "offline" for their availability.
### hf thinfilm
{ Thinfilm RFIDs... }
{ Thinfilm RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -463,7 +475,7 @@ Check column "offline" for their availability.
### hf topaz
{ TOPAZ (NFC Type 1) RFIDs... }
{ TOPAZ (NFC Type 1) RFIDs... }
|command |offline |description
|------- |------- |-----------
@ -478,7 +490,7 @@ Check column "offline" for their availability.
### hf waveshare
{ Waveshare NFC ePaper... }
{ Waveshare NFC ePaper... }
|command |offline |description
|------- |------- |-----------