From 1a5a73abaeeac821208e676b003571ece7725212 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Oct 2015 00:24:55 -0400 Subject: [PATCH] Add mifare crypto trace decryption utility allows manual decryption of hf 14a snoop traces of a mf card. someday we should fix hf mf sniff... --- client/cmdhfmf.c | 8 ++++++++ client/mifarehost.c | 20 ++++++++++++++++++++ client/mifarehost.h | 1 + client/util.c | 21 +++++++++++++++++++++ client/util.h | 1 + 5 files changed, 51 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 16612cba..c4a0aeeb 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1949,6 +1949,13 @@ int CmdHF14AMfSniff(const char *Cmd){ return 0; } +//needs nt, ar, at, Data to decrypt +int CmdDecryptTraceCmds(const char *Cmd){ + uint8_t data[50]; + int len = 0; + param_gethex_ex(Cmd,3,data,&len); + return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2); +} static command_t CommandTable[] = { @@ -1977,6 +1984,7 @@ static command_t CommandTable[] = {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"}, {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"}, {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"}, + {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, {NULL, NULL, 0, NULL} }; diff --git a/client/mifarehost.c b/client/mifarehost.c index eb145123..4abb1137 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -619,3 +619,23 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { return 0; } + +int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){ + /* + uint32_t nt; // tag challenge + uint32_t ar_enc; // encrypted reader response + uint32_t at_enc; // encrypted tag response + */ + if (traceCrypto1) { + crypto1_destroy(traceCrypto1); + } + ks2 = ar_enc ^ prng_successor(nt, 64); + ks3 = at_enc ^ prng_successor(nt, 96); + traceCrypto1 = lfsr_recovery64(ks2, ks3); + + mf_crypto1_decrypt(traceCrypto1, data, len, 0); + + PrintAndLog("Decrypted data: [%s]", sprint_hex(data,len) ); + crypto1_destroy(traceCrypto1); + return 0; +} diff --git a/client/mifarehost.h b/client/mifarehost.h index f6ffab3f..9ccb8960 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -67,3 +67,4 @@ int isBlockEmpty(int blockN); int isBlockTrailer(int blockN); int loadTraceCard(uint8_t *tuid); int saveTraceCard(void); +int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); diff --git a/client/util.c b/client/util.c index 9f2142c6..5e9fce85 100644 --- a/client/util.c +++ b/client/util.c @@ -333,7 +333,28 @@ int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt) return 0; } +int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt) +{ + int bg, en, temp, i; + + //if (hexcnt % 2) + // return 1; + + if (param_getptr(line, &bg, &en, paramnum)) return 1; + + *hexcnt = en - bg + 1; + if (*hexcnt % 2) //error if not complete hex bytes + return 1; + for(i = 0; i < *hexcnt; i += 2) { + if (!(isxdigit(line[bg + i]) && isxdigit(line[bg + i + 1])) ) return 1; + + sscanf((char[]){line[bg + i], line[bg + i + 1], 0}, "%X", &temp); + data[i / 2] = temp & 0xff; + } + + return 0; +} int param_getstr(const char *line, int paramnum, char * str) { int bg, en; diff --git a/client/util.h b/client/util.h index 2d2beaf4..19c34604 100644 --- a/client/util.h +++ b/client/util.h @@ -54,6 +54,7 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base); uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination); uint8_t param_isdec(const char *line, int paramnum); int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt); +int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt); int param_getstr(const char *line, int paramnum, char * str); int hextobinarray( char *target, char *source); -- 2.39.2