From e567b74fa035f23c48a76988cac33975bde1cdae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 19 Dec 2018 08:57:59 +0100 Subject: [PATCH 001/320] chg... --- client/default_keys.dic | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index f764596ce..3fb8f07bf 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -708,4 +708,7 @@ E56AC127DD45, EA0FD73CB149, FC0001877BF7, FD8705E721B0, -00ada2cd516d, \ No newline at end of file +00ada2cd516d, +# +# +D3F7D3F7D3F7 \ No newline at end of file From f0c34827991b014c4e42ecad2294abab3efc2483 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 19 Dec 2018 20:31:20 +0200 Subject: [PATCH 002/320] add T=0 to `sc raw` command --- client/cmdsmartcard.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 8408b03ce..953526284 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -15,14 +15,15 @@ int usage_sm_raw(void) { PrintAndLogEx(NORMAL, "Usage: sc raw [h|r|c] d <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " r : do not read response"); - PrintAndLogEx(NORMAL, " a : active smartcard without select"); - PrintAndLogEx(NORMAL, " s : active smartcard with select"); + PrintAndLogEx(NORMAL, " a : active smartcard without select (reset sc module)"); + PrintAndLogEx(NORMAL, " s : active smartcard with select (get ATR)"); PrintAndLogEx(NORMAL, " t : executes TLV decoder if it possible"); + PrintAndLogEx(NORMAL, " 0 : use protocol T=0"); PrintAndLogEx(NORMAL, " d : bytes to send"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " sc raw d 00a404000e315041592e5359532e444446303100 - `1PAY.SYS.DDF01` PPSE directory"); - PrintAndLogEx(NORMAL, " sc raw d 00a404000e325041592e5359532e444446303100 - `2PAY.SYS.DDF01` PPSE directory"); + PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e444446303100 - `1PAY.SYS.DDF01` PPSE directory with get ATR"); + PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e444446303100 - `2PAY.SYS.DDF01` PPSE directory"); return 0; } int usage_sm_reader(void) { @@ -362,6 +363,7 @@ int CmdSmartRaw(const char *Cmd) { int hexlen = 0; bool active = false; bool active_select = false; + bool useT0 = false; uint8_t cmdp = 0; bool errors = false, reply = true, decodeTLV = false, breakloop = false; uint8_t data[USB_CMD_DATA_SIZE] = {0x00}; @@ -385,6 +387,10 @@ int CmdSmartRaw(const char *Cmd) { decodeTLV = true; cmdp++; break; + case '0': + useT0 = true; + cmdp++; + break; case 'd': { switch (param_gethex_to_eol(Cmd, cmdp+1, data, sizeof(data), &hexlen)) { case 1: @@ -425,7 +431,10 @@ int CmdSmartRaw(const char *Cmd) { } if (hexlen > 0) { - c.arg[0] |= SC_RAW; + if (useT0) + c.arg[0] |= SC_RAW_T0; + else + c.arg[0] |= SC_RAW; } memcpy(c.d.asBytes, data, hexlen ); From 0143d3f0e0a240005251f985a3beebbbe7063bca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 19 Dec 2018 22:50:32 +0100 Subject: [PATCH 003/320] chg: 'sc raw' - some more love --- client/cmdsmartcard.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 953526284..11988c98b 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -22,8 +22,8 @@ int usage_sm_raw(void) { PrintAndLogEx(NORMAL, " d : bytes to send"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e444446303100 - `1PAY.SYS.DDF01` PPSE directory with get ATR"); - PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e444446303100 - `2PAY.SYS.DDF01` PPSE directory"); + PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e4444463031 - `1PAY.SYS.DDF01` PPSE directory with get ATR"); + PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e4444463031 - `2PAY.SYS.DDF01` PPSE directory"); return 0; } int usage_sm_reader(void) { @@ -289,7 +289,7 @@ static bool smart_select(bool silent) { static int smart_wait(uint8_t *data) { UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { - PrintAndLogEx(WARNING, "smart card response failed"); + PrintAndLogEx(WARNING, "smart card response timeout"); return -1; } @@ -299,11 +299,12 @@ static int smart_wait(uint8_t *data) { return -2; } memcpy(data, resp.d.asBytes, len); - PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 32)); - if (len >= 2) { PrintAndLogEx(SUCCESS, "%02X%02X | %s", data[len - 2], data[len - 1], GetAPDUCodeDescription(data[len - 2], data[len - 1])); + } else { + PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 8)); } + return len; } @@ -466,7 +467,7 @@ int CmdSmartRaw(const char *Cmd) { } if (decodeTLV && len > 4) - TLVPrintFromBuffer(buf+1, len-3); + TLVPrintFromBuffer(buf, len-2); free(buf); } @@ -478,7 +479,8 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave if (activateCard) smart_select(false); - printf("* APDU SC\n"); + + PrintAndLogEx(DEBUG, "APDU SC"); UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, datainlen, 0}}; if (activateCard) { @@ -806,8 +808,8 @@ int CmdSmartBruteforceSFI(const char *Cmd) { } PrintAndLogEx(INFO, "Selecting PPSE aid"); - CmdSmartRaw("d 00a404000e325041592e5359532e444446303100"); - CmdSmartRaw("d 00a4040007a000000004101000"); + CmdSmartRaw("s 0 d 00a404000e325041592e5359532e4444463031"); + CmdSmartRaw("0 d 00a4040007a000000004101000"); PrintAndLogEx(INFO, "starting"); From a9b3fd71382f4eec34aa7f5d83bd930ca8572129 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 19 Dec 2018 23:21:59 +0100 Subject: [PATCH 004/320] chg: 'sc brute' - now works :) --- client/cmdsmartcard.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 11988c98b..e21704fb3 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -323,7 +323,7 @@ static int smart_response(uint8_t *data) { if (needGetData) { int len = data[datalen - 1]; - PrintAndLogEx(INFO, "Requesting response. len=0x%x", len); + PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len}; UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}}; memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) ); @@ -341,7 +341,7 @@ static int smart_response(uint8_t *data) { // data with ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK if (data[0] != ISO7816_GETSTATUS) { - PrintAndLogEx(ERR, "GetResponse ACK error. len=0x%x data[0]=%02x", len, data[0]); + PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); datalen = 0; goto out; } @@ -350,7 +350,7 @@ static int smart_response(uint8_t *data) { memmove(data, &data[1], datalen); } else { // wrong length - PrintAndLogEx(WARNING, "GetResponse wrong length. Must be: 0x%02x but: 0x%02x", len, datalen - 3); + PrintAndLogEx(WARNING, "GetResponse wrong length. Must be 0x%02X got 0x%02X", len, datalen - 3); } } } @@ -808,8 +808,9 @@ int CmdSmartBruteforceSFI(const char *Cmd) { } PrintAndLogEx(INFO, "Selecting PPSE aid"); - CmdSmartRaw("s 0 d 00a404000e325041592e5359532e4444463031"); - CmdSmartRaw("0 d 00a4040007a000000004101000"); + CmdSmartRaw("s 0 t d 00a404000e325041592e5359532e4444463031"); + CmdSmartRaw("0 t d 00a4040007a000000004101000"); // mastercard +// CmdSmartRaw("0 t d 00a4040007a0000000031010"); // visa PrintAndLogEx(INFO, "starting"); @@ -830,7 +831,6 @@ int CmdSmartBruteforceSFI(const char *Cmd) { smart_response(buf); - // if 0x6C if ( buf[0] == 0x6C ) { data[4] = buf[1]; From d4b32f30509911f06a617c990cf5a029ab851e2b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 19 Dec 2018 23:28:01 +0100 Subject: [PATCH 005/320] ADD: Sim module firmware upgrade file. v3.10 --- common/i2c.c | 2 +- tools/simmodule/SIM010.BIN | Bin 0 -> 719 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tools/simmodule/SIM010.BIN diff --git a/common/i2c.c b/common/i2c.c index ea830a1bd..99f8b6e12 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -575,7 +575,7 @@ void I2C_print_status(void) { I2C_Reset_EnterMainProgram(); uint8_t len = I2C_BufferRead(resp, sizeof(resp), I2C_DEVICE_CMD_GETVERSION, I2C_DEVICE_ADDRESS_MAIN); if ( len > 0 ) - Dbprintf(" version.................v%x.%02x", resp[0], resp[1]); + Dbprintf(" version.................v%x.%02d", resp[0], resp[1]); else DbpString(" version.................FAILED"); } diff --git a/tools/simmodule/SIM010.BIN b/tools/simmodule/SIM010.BIN new file mode 100644 index 0000000000000000000000000000000000000000..dea57a7d8608a34020f7d9e5e40a5b6e915be6fa GIT binary patch literal 719 zcmbVJO=uHA6rS1L$-l5DLa~?K$zPi&EQ<%hi&CM-7^G)Cc=O`ri3c%jCH{bwbYmf* z2XzZliW1uHp@&G~bZdKD268JV2XpY2OEJ|ZaaU8USKl1o_kF{A?|VD}ucL7&IpOTI zGD})h0x#>wDni)!i+zOG{^kG6Sf3s0az&D>s?L!joojZ8)vXrkJUqrdLW$*eSQ(}+ zl9bMadb87X!JVjmY@jfA*tX&f)Jo%)%uI%v$OsFt5DTkj!?>s59LL?d9h7*~Ahr-= zQAi?AAc0iV#;3RdDFhTj+~)y7eQisz`&mdM$VlAlVUuG@e5#rXi78=0HQ&`kB(0iU z^qkg<3C}6&kp!_w(i{9{lABssVqqT9#7j)%(upyRRlyJ&TdEc!PwFABV<5-_#Z+B2 ziB*jID|Zg+Bu*^0!yL|B*IRyD_e^C1kQLy(2p1yUtAj^-uyF;}M_}KC%`NzV;Qa`m zQ+R=3;Tt@ggWWaQots(2uqpq+Hx`G`yvASgGJI-6#f7H^^sj>xf}QX1c?3%WC Date: Wed, 19 Dec 2018 23:46:19 +0100 Subject: [PATCH 006/320] CHG: 'sc info' - textual --- client/cmdsmartcard.c | 90 +++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index e21704fb3..1ed46b993 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -159,58 +159,46 @@ float GetATRF(uint8_t *atr, size_t atrlen) { } static int PrintATR(uint8_t *atr, size_t atrlen) { - uint8_t vxor = 0; - for (int i = 1; i < atrlen; i++) - vxor ^= atr[i]; - - if (vxor) - PrintAndLogEx(WARNING, "Check summ error. Must be 0 but: 0x%02x", vxor); - else - PrintAndLogEx(INFO, "Check summ OK."); - - if (atr[0] != 0x3b) - PrintAndLogEx(WARNING, "Not a direct convention: 0x%02x", atr[0]); uint8_t T0 = atr[1]; uint8_t K = T0 & 0x0F; - uint8_t TD1 = 0; - - uint8_t T1len = 0; - uint8_t TD1len = 0; - uint8_t TDilen = 0; + uint8_t TD1 = 0, T1len = 0, TD1len = 0, TDilen = 0; if (T0 & 0x10) { - PrintAndLog("TA1 (Maximum clock frequency, proposed bit duration): 0x%02x", atr[2 + T1len]); + PrintAndLog("\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]); T1len++; } + if (T0 & 0x20) { - PrintAndLog("TB1 (Deprecated: VPP requirements): 0x%02x", atr[2 + T1len]); + PrintAndLog("\t- TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr[2 + T1len]); T1len++; } + if (T0 & 0x40) { - PrintAndLog("TC1 (Extra delay between bytes required by card): 0x%02x", atr[2 + T1len]); + PrintAndLog("\t- TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr[2 + T1len]); T1len++; } + if (T0 & 0x80) { TD1 = atr[2 + T1len]; - PrintAndLog("TD1 (First offered transmission protocol, presence of TA2..TD2): 0x%02x. Protocol T=%d", TD1, TD1 & 0x0f); + PrintAndLog("\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1, TD1 & 0x0f); T1len++; if (TD1 & 0x10) { - PrintAndLog("TA2 (Specific protocol and parameters to be used after the ATR): 0x%02x", atr[2 + T1len + TD1len]); + PrintAndLog("\t- TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x20) { - PrintAndLog("TB2 (Deprecated: VPP precise voltage requirement): 0x%02x", atr[2 + T1len + TD1len]); + PrintAndLog("\t- TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x40) { - PrintAndLog("TC2 (Maximum waiting time for protocol T=0): 0x%02x", atr[2 + T1len + TD1len]); + PrintAndLog("\t- TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr[2 + T1len + TD1len]); TD1len++; } if (TD1 & 0x80) { uint8_t TDi = atr[2 + T1len + TD1len]; - PrintAndLog("TD2 (A supported protocol or more global parameters, presence of TA3..TD3): 0x%02x. Protocol T=%d", TDi, TDi & 0x0f); + PrintAndLog("\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi, TDi & 0x0f); TD1len++; bool nextCycle = true; @@ -218,20 +206,20 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { while (nextCycle) { nextCycle = false; if (TDi & 0x10) { - PrintAndLog("TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLog("\t- TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x20) { - PrintAndLog("TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLog("\t- TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x40) { - PrintAndLog("TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); + PrintAndLog("\t- TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]); TDilen++; } if (TDi & 0x80) { TDi = atr[2 + T1len + TD1len + TDilen]; - PrintAndLog("TD%d: 0x%02x. Protocol T=%d", vi, TDi, TDi & 0x0f); + PrintAndLog("\t- TD%d [ 0x%02x ] Protocol T%d", vi, TDi, TDi & 0x0f); TDilen++; nextCycle = true; @@ -240,26 +228,36 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { } } } + + uint8_t vxor = 0; + for (int i = 1; i < atrlen; i++) + vxor ^= atr[i]; + + if (vxor) + PrintAndLogEx(WARNING, "Check summ error. Must be 0 got 0x%02X", vxor); + else + PrintAndLogEx(INFO, "Check summ OK."); + + if (atr[0] != 0x3b) + PrintAndLogEx(WARNING, "Not a direct convention [ 0x%02x ]", atr[0]); + uint8_t calen = 2 + T1len + TD1len + TDilen + K; if (atrlen != calen && atrlen != calen + 1) // may be CRC PrintAndLogEx(ERR, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); - else - PrintAndLogEx(INFO, "ATR length OK."); - PrintAndLog("Historical bytes len: 0x%02x", K); if (K > 0) - PrintAndLog("The format of historical bytes: %02x", atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); + if (K > 1) { - PrintAndLog("Historical bytes:"); + PrintAndLogEx(INFO, "\tHistorical bytes"); dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1); } return 0; } - static bool smart_select(bool silent) { UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; clearCommandBuffer(); @@ -515,7 +513,6 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave return 0; } - int CmdSmartUpgrade(const char *Cmd) { PrintAndLogEx(WARNING, "WARNING - Smartcard socket firmware upgrade."); @@ -663,32 +660,31 @@ int CmdSmartInfo(const char *Cmd){ memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); // print header - PrintAndLogEx(INFO, "\n--- Smartcard Information ---------"); + PrintAndLogEx(INFO, "--- Smartcard Information ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PrintAndLogEx(INFO, "ISO76183 ATR : %s", sprint_hex(card.atr, card.atr_len)); - PrintAndLogEx(INFO, "look up ATR"); - PrintAndLogEx(INFO, "http://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) ); + PrintAndLogEx(INFO, "ISO7618-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); + PrintAndLogEx(INFO, "\nhttp://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) ); // print ATR PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "* ATR:"); + PrintAndLogEx(INFO, "ATR"); PrintATR(card.atr, card.atr_len); // print D/F (brom byte TA1 or defaults) PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "* D/F (TA1):"); + PrintAndLogEx(INFO, "D/F (TA1)"); int Di = GetATRDi(card.atr, card.atr_len); int Fi = GetATRFi(card.atr, card.atr_len); float F = GetATRF(card.atr, card.atr_len); if (GetATRTA1(card.atr, card.atr_len) == 0x11) PrintAndLogEx(INFO, "Using default values..."); - PrintAndLogEx(NORMAL, "Di=%d", Di); - PrintAndLogEx(NORMAL, "Fi=%d", Fi); - PrintAndLogEx(NORMAL, "F=%.1f MHz", F); - PrintAndLogEx(NORMAL, "Cycles/ETU=%d", Fi/Di); - PrintAndLogEx(NORMAL, "%.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di)); - PrintAndLogEx(NORMAL, "%.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F); + PrintAndLogEx(NORMAL, "\t- Di %d", Di); + PrintAndLogEx(NORMAL, "\t- Fi %d", Fi); + PrintAndLogEx(NORMAL, "\t- F %.1f MHz", F); + PrintAndLogEx(NORMAL, "\t- Cycles/ETU %d", Fi/Di); + PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at 4 MHz", (float)4000000 / (Fi/Di)); + PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at Fmax (%.1f MHz)", (F * 1000000) / (Fi/Di), F); return 0; } From f7a2af19f8660fe21c02aba86e700f5f02d6cdf0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Dec 2018 12:24:55 +0100 Subject: [PATCH 007/320] ADD: sha512, md5 hashes for firmware file. --- tools/simmodule/SIM010.md5.txt | 1 + tools/simmodule/SIM010.sha512.txt | 1 + tools/simmodule/readme.txt | 36 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 tools/simmodule/SIM010.md5.txt create mode 100644 tools/simmodule/SIM010.sha512.txt create mode 100644 tools/simmodule/readme.txt diff --git a/tools/simmodule/SIM010.md5.txt b/tools/simmodule/SIM010.md5.txt new file mode 100644 index 000000000..c790101f7 --- /dev/null +++ b/tools/simmodule/SIM010.md5.txt @@ -0,0 +1 @@ +136e157364609e5c395540dc8dadbfd6 *SIM010.BIN diff --git a/tools/simmodule/SIM010.sha512.txt b/tools/simmodule/SIM010.sha512.txt new file mode 100644 index 000000000..b7bab7246 --- /dev/null +++ b/tools/simmodule/SIM010.sha512.txt @@ -0,0 +1 @@ +e6ac5e6f1d7cc86d56f2128f2a495f1395fe044bf6ff3b6ca24ce90d1e361ae835fe273a206f2fc90e4344a13b37b180dd017a2c7f23312f1ed163f10c01ea5a *SIM010.BIN diff --git a/tools/simmodule/readme.txt b/tools/simmodule/readme.txt new file mode 100644 index 000000000..7efa40205 --- /dev/null +++ b/tools/simmodule/readme.txt @@ -0,0 +1,36 @@ + +2018-12-20 Iceman + +======================================= + +The latest firmware for the SIM MODULE is : SIM010.bin + + +You can use it to upgrade you sim module via the pm3 client. + + +pm3 --> sc upgrade -h +pm3 --> sc upgrade f ../tools/simmodule/SIM010.bin + + + +Even its a quite fast command you should be warned. You may brick it if you interrupt it. + + + +Run hw status command to verify that the upgrade went well. + +pm3 --> hw status + + + +If you didn't download this file from the RRG Repo be aware that it might be corrupt or faulty. + +You find to hash text files in this folder. They were generated with the following linux commands. + + +md5sum -b SIM010.bin > SIM010.md5.txt +sha512sum -b SIM010.bin > SIM010.sha512.txt + + +You should validate the SIM010.bin file against these hash files in order to be sure the file is not corrupt or faulty. \ No newline at end of file From d64a48b7fcf218da33f97cba9ec3339e78902e76 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 20 Dec 2018 23:05:02 +0200 Subject: [PATCH 008/320] added check Fi and Di --- client/cmdsmartcard.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 8408b03ce..e4c161153 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -675,10 +675,14 @@ int CmdSmartInfo(const char *Cmd){ PrintAndLogEx(NORMAL, "Di=%d", Di); PrintAndLogEx(NORMAL, "Fi=%d", Fi); PrintAndLogEx(NORMAL, "F=%.1f MHz", F); - PrintAndLogEx(NORMAL, "Cycles/ETU=%d", Fi/Di); - PrintAndLogEx(NORMAL, "%.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di)); - PrintAndLogEx(NORMAL, "%.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F); - + if (Di && Fi) { + PrintAndLogEx(NORMAL, "Cycles/ETU=%d", Fi/Di); + PrintAndLogEx(NORMAL, "%.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di)); + PrintAndLogEx(NORMAL, "%.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F); + } else { + PrintAndLogEx(WARNING, "Di or Fi is RFU."); + }; + return 0; } From acb41a7376ef20bf2ba728f3c661ac8bc07eefda Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Dec 2018 09:48:46 +0100 Subject: [PATCH 009/320] CHG: 'sc brute' - now is interruptable, optional tlv decode, --- client/aidlist.json | 1 + client/cmdhffido.c | 2 +- client/cmdsmartcard.c | 325 +++++++++++++++++++++++++++++++++--------- client/emv/cmdemv.c | 1 + client/emv/emv_tags.c | 47 +++--- client/emv/emvcore.c | 4 +- client/emv/emvcore.h | 2 +- 7 files changed, 291 insertions(+), 91 deletions(-) create mode 100644 client/aidlist.json diff --git a/client/aidlist.json b/client/aidlist.json new file mode 100644 index 000000000..7ec139d46 --- /dev/null +++ b/client/aidlist.json @@ -0,0 +1 @@ +[{"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "315041592E5359532E4444463031", "Type": "", "Name": "Visa Payment System Environment - PSE (1PAY.SYS.DDF01)"}, {"Vendor": "Visa International", "Description": "Visa payWave for Mobile", "Country": "United States", "AID": "325041592E5359532E4444463031", "Type": "", "Name": "Visa Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01)"}, {"Vendor": "DeviceFidelity", "Description": "http://www.nfcworld.com/2010/11/24/35207/devicefidelity-adds-nfc-support-for-android-and-mifare/", "Country": "United States", "AID": "44464D46412E44466172653234313031", "Type": "", "Name": "DeviceFidelity In2Pay DFare applet"}, {"Vendor": "PBS Danmnt A/S", "Description": "(Unlicensed use of this RID. Proposal to use A000000323 instead)", "Country": "Denmark", "AID": "A00000000101", "Type": "", "Name": "MUSCLE Card Applet"}, {"Vendor": "Visa International", "Description": "Used by most GP2.1.1 cards / Oberthur OP201 cards. Visa Proprietary Card Manager AID for OpenPlatform cards (visa.openplatform).", "Country": "United States", "AID": "A000000003000000", "Type": "GP", "Name": "(VISA) Card Manager"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A00000000300037561", "Type": "", "Name": "Bonuscard"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A00000000305076010", "Type": "EMV", "Name": "VISA ELO Credit"}, {"Vendor": "Visa International", "Description": "Standard/Gold VISA credit card", "Country": "United States", "AID": "A0000000031010", "Type": "EMV", "Name": "VISA Debit/Credit (Classic)"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003101001", "Type": "EMV", "Name": "VISA Credit"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003101002", "Type": "EMV", "Name": "VISA Debit"}, {"Vendor": "Visa International", "Description": "VISA Electron (Debit)", "Country": "United States", "AID": "A0000000032010", "Type": "EMV", "Name": "VISA Electron"}, {"Vendor": "Visa International", "Description": "V PAY", "Country": "United States", "AID": "A0000000032020", "Type": "EMV", "Name": "VISA"}, {"Vendor": "Visa International", "Description": "VISA Interlink", "Country": "United States", "AID": "A0000000033010", "Type": "EMV", "Name": "VISA Interlink"}, {"Vendor": "Visa International", "Description": "Visa Specific", "Country": "United States", "AID": "A0000000034010", "Type": "EMV", "Name": "VISA Specific"}, {"Vendor": "Visa International", "Description": "Visa Specific", "Country": "United States", "AID": "A0000000035010", "Type": "EMV", "Name": "VISA Specific"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003534441", "Type": "GP", "Name": "Schlumberger Security Domain"}, {"Vendor": "Visa International", "Description": "OCS Oberthur Card System Security Domain Package AID / VGP Card Manager (for ISD and ASD)", "Country": "United States", "AID": "A0000000035350", "Type": "GP", "Name": "Security Domain"}, {"Vendor": "Visa International", "Description": "OCS Oberthur Card System Security Domain Applet AID / VGP Card Manager (for ISD and ASD)", "Country": "United States", "AID": "A000000003535041", "Type": "GP", "Name": "Security Domain"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000036010", "Type": "EMV", "Name": "Domestic Visa Cash Stored Value"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000036020", "Type": "EMV", "Name": "International Visa Cash Stored Value"}, {"Vendor": "Visa International", "Description": "VISA Auth dynamic passcode authentication (DPA). Used by Barclays/HBOS", "Country": "United States", "AID": "A0000000038002", "Type": "EMV", "Name": "VISA Auth, VisaRemAuthen EMV-CAP (DPA)"}, {"Vendor": "Visa International", "Description": "VISA plus", "Country": "United States", "AID": "A0000000038010", "Type": "EMV", "Name": "VISA Plus"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A0000000039010", "Type": "EMV", "Name": "VISA Loyalty"}, {"Vendor": "Visa International", "Description": "", "Country": "United States", "AID": "A000000003999910", "Type": "EMV", "Name": "VISA Proprietary ATM"}, {"Vendor": "Mastercard International", "Description": "Security Domain", "Country": "United States", "AID": "A0000000040000", "Type": "GP", "Name": "MasterCard Card Manager"}, {"Vendor": "Mastercard International", "Description": "AEPM (Association Europenne Payez Mobile)", "Country": "United States", "AID": "A00000000401", "Type": "EMV", "Name": "MasterCard PayPass"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A0000000041010", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A00000000410101213", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Standard MasterCard", "Country": "United States", "AID": "A00000000410101215", "Type": "EMV", "Name": "MasterCard Credit"}, {"Vendor": "Mastercard International", "Description": "Some co-branded card?", "Country": "United States", "AID": "A0000000041010BB5449435301", "Type": "", "Name": "[UNKNOWN]"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000042010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard U.S. Maestro", "Country": "United States", "AID": "A0000000042203", "Type": "", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000043010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "Maestro (Debit) Card", "Country": "United States", "AID": "A0000000043060", "Type": "EMV", "Name": "Maestro (Debit)"}, {"Vendor": "Mastercard International", "Description": "Maestro (Debit) Card", "Country": "United States", "AID": "A000000004306001", "Type": "EMV", "Name": "Maestro (Debit)"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000044010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "MasterCard Specific", "Country": "United States", "AID": "A0000000045010", "Type": "EMV", "Name": "MasterCard Specific"}, {"Vendor": "Mastercard International", "Description": "AID on Cirrus Test Card", "Country": "United States", "AID": "A0000000045555", "Type": "", "Name": "APDULogger"}, {"Vendor": "Mastercard International", "Description": "Mastercard Cirrus (Interbank Network) ATM card only", "Country": "United States", "AID": "A0000000046000", "Type": "EMV", "Name": "Cirrus"}, {"Vendor": "Mastercard International", "Description": "Chip Authentication Protocol (CAP). Works with NatWest or SecureCode Aut", "Country": "United States", "AID": "A0000000048002", "Type": "EMV", "Name": "SecureCode Auth EMV-CAP"}, {"Vendor": "Mastercard International", "Description": "", "Country": "United States", "AID": "A0000000049999", "Type": "EMV", "Name": "MasterCard PayPass??"}, {"Vendor": "Switch Card Services Ltd.", "Description": "UK Domestic Maestro - Switch (debit card)", "Country": "United Kingdom", "AID": "A0000000050001", "Type": "EMV", "Name": "Maestro UK"}, {"Vendor": "Switch Card Services Ltd.", "Description": "UK Domestic Maestro - Switch (debit card)", "Country": "United Kingdom", "AID": "A0000000050002", "Type": "EMV", "Name": "Solo"}, {"Vendor": "ETSI", "Description": "Orange UK", "Country": "France", "AID": "A0000000090001FF44FF1289", "Type": "", "Name": "Orange"}, {"Vendor": "Europay International", "Description": "", "Country": "Belgium", "AID": "A0000000101030", "Type": "", "Name": "Maestro-CH"}, {"Vendor": "GEMPLUS", "Description": "", "Country": "France", "AID": "A00000001800", "Type": "", "Name": "Gemplus ?"}, {"Vendor": "GEMPLUS", "Description": "", "Country": "France", "AID": "A0000000181001", "Type": "", "Name": "com.gemplus.javacard.util packages"}, {"Vendor": "GEMPLUS", "Description": "434D = CM (ascii). Security domain for some GCX/GXP cards (GemXpresso Pro) (Gemalto)", "Country": "France", "AID": "A000000018434D", "Type": "GP", "Name": "Gemplus card manager"}, {"Vendor": "GEMPLUS", "Description": "(Gemalto)", "Country": "France", "AID": "A000000018434D00", "Type": "GP", "Name": "Gemplus Security Domain"}, {"Vendor": "Midland Bank Plc", "Description": "", "Country": "United Kingdom", "AID": "A00000002401", "Type": "EMV", "Name": "Self Service"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "American Express (Credit/Debit)", "Country": "United Kingdom", "AID": "A0000000250000", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "AEIPS-compliant (A-E contact EMV) payment application", "Country": "United Kingdom", "AID": "A00000002501", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010104", "Type": "", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010402", "Type": "EMV", "Name": "American Express"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010701", "Type": "EMV", "Name": "ExpressPay"}, {"Vendor": "American Express", "Description": "", "Country": "United Kingdom", "AID": "A000000025010801", "Type": "EMV", "Name": "American Express"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "Link (UK) ATM Network, or AMEX (Portugal?)", "Country": "United Kingdom", "AID": "A0000000291010", "Type": "EMV", "Name": "Link / American Express"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002945087510100000", "Type": "", "Name": "CO-OP"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002949034010100001", "Type": "", "Name": "HSBC"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A00000002949282010100000", "Type": "", "Name": "Barclay"}, {"Vendor": "LINK Interchange Network Ltd", "Description": "", "Country": "United Kingdom", "AID": "A000000029564182", "Type": "", "Name": "HAFX"}, {"Vendor": "Schlumberger Industries Identif d'Encarteur PR050", "Description": "Schlumberger (Gemalto) RID", "Country": "France", "AID": "A00000003029057000AD13100101FF", "Type": "", "Name": "BelPIC (Belgian Personal Identity Card) JavaCard Applet"}, {"Vendor": "Schlumberger Industries Identif d'Encarteur PR050", "Description": "", "Country": "France", "AID": "A0000000308000000000280101", "Type": "", "Name": "Gemalto .NET Card AID"}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "Groupement des Cartes Bancaires (France)", "Country": "France", "AID": "A0000000421010", "Type": "EMV", "Name": "Cartes Bancaire EMV Card"}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000422010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000423010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000424010", "Type": "EMV", "Name": ""}, {"Vendor": "Groupement des Cartes Bancaires \"CB\"", "Description": "", "Country": "France", "AID": "A0000000425010", "Type": "EMV", "Name": ""}, {"Vendor": "Zentraler Kreditausschuss (ZKA)", "Description": "", "Country": "Germany", "AID": "A00000005945430100", "Type": "", "Name": "Girocard Electronic Cash"}, {"Vendor": "RSA Laboratories", "Description": "RSA PKCS-15 PKI application (Predecessor to ISO7816-15) / ID-card in Finland", "Country": "United States", "AID": "A000000063504B43532D3135", "Type": "", "Name": "PKCS-15"}, {"Vendor": "RSA Laboratories", "Description": "WAP (Wireless Application Protocol) Identity Module / Wireless Identification Module", "Country": "United States", "AID": "A0000000635741502D57494D", "Type": "", "Name": "WAP-WIM"}, {"Vendor": "JCB CO., LTD.", "Description": "Japan Credit Bureau", "Country": "Japan", "AID": "A00000006510", "Type": "EMV", "Name": "JCB"}, {"Vendor": "JCB CO., LTD.", "Description": "Japan Credit Bureau", "Country": "Japan", "AID": "A0000000651010", "Type": "EMV", "Name": "JCB J Smart Credit"}, {"Vendor": "Socit Europenne de Monnaie Electronique SEME", "Description": "", "Country": "France", "AID": "A00000006900", "Type": "EMV", "Name": "Moneo"}, {"Vendor": "Oberthur Technologies", "Description": "", "Country": "France", "AID": "A000000077010000021000000000003B", "Type": "EMV", "Name": "Visa AEPN"}, {"Vendor": "Activcard Europe S.A.", "Description": "Identity Key", "Country": "France", "AID": "A0000000790100", "Type": "", "Name": "CACv2 PKI ID"}, {"Vendor": "Activcard Europe S.A.", "Description": "Digital Signature Key", "Country": "France", "AID": "A0000000790101", "Type": "", "Name": "CACv2 PKI Sign"}, {"Vendor": "Activcard Europe S.A.", "Description": "Key Management Key", "Country": "France", "AID": "A0000000790102", "Type": "", "Name": "CACv2 PKI Enc"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 PKI Identity key", "Country": "France", "AID": "A00000007901F0", "Type": "", "Name": "CACv1 PKI Identity Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 Digital Signature key", "Country": "France", "AID": "A00000007901F1", "Type": "", "Name": "CACv1 PKI Digital Signature Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "Re-directs to CACv2 Key Management key", "Country": "France", "AID": "A00000007901F2", "Type": "", "Name": "CACv1 PKI Key Management Key"}, {"Vendor": "Activcard Europe S.A.", "Description": "DoD Demographic", "Country": "France", "AID": "A0000000790200", "Type": "", "Name": "CACv2 DoD Person"}, {"Vendor": "Activcard Europe S.A.", "Description": "DoD Demographic", "Country": "France", "AID": "A0000000790201", "Type": "", "Name": "CACv2 DoD Personnel"}, {"Vendor": "Activcard Europe S.A.", "Description": "General Configuration", "Country": "France", "AID": "A00000007902FB", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "PKI Certificate Attributes", "Country": "France", "AID": "A00000007902FD", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "PKI Cert", "Country": "France", "AID": "A00000007902FE", "Type": "", "Name": "CACv1 BC"}, {"Vendor": "Activcard Europe S.A.", "Description": "CAC PIN / ID PIN Management Applet", "Country": "France", "AID": "A0000000790300", "Type": "", "Name": "CACv2 Access Control Applet"}, {"Vendor": "Activcard Europe S.A.", "Description": "Joint Data Model. BCAdmin", "Country": "France", "AID": "A0000000791201", "Type": "", "Name": "CAC JDM"}, {"Vendor": "Activcard Europe S.A.", "Description": "Joint Data Model. BCMedical", "Country": "France", "AID": "A0000000791202", "Type": "", "Name": "CAC JDM"}, {"Vendor": "Third Generation Partnership Project (3GPP)", "Description": "", "Country": "France", "AID": "A0000000871002FF49FF0589", "Type": "USIM", "Name": "Telenor USIM"}, {"Vendor": "Buypass AS", "Description": "Used by norwegian public betting company Norsk-Tipping?", "Country": "Norway", "AID": "A00000008810200105C100", "Type": "BuyPass", "Name": "BuyPass BIDA"}, {"Vendor": "Buypass AS", "Description": "", "Country": "Norway", "AID": "A000000088102201034221", "Type": "BuyPass", "Name": "BuyPass BEID (BuyPass Electronic ID?)"}, {"Vendor": "Buypass AS", "Description": "", "Country": "Norway", "AID": "A000000088102201034321", "Type": "BuyPass", "Name": "BuyPass BEID (BuyPass Electronic ID?)"}, {"Vendor": "Sa Proton World International N.V.", "Description": "Proton, which is owned in part by Visa International and American Express Co., is in three other European countries: the original Proton program in Belgium, Chipknip in the Netherlands, and Cash in Switzerland", "Country": "Belgium", "AID": "A0000000960200", "Type": "GP", "Name": "Proton World International Security Domain"}, {"Vendor": "Visa USA", "Description": "Bank of America Debit Card", "Country": "United States", "AID": "A000000098", "Type": "EMV", "Name": "Debit Card"}, {"Vendor": "Visa USA", "Description": "", "Country": "United States", "AID": "A0000000980840", "Type": "", "Name": "Visa Common Debit"}, {"Vendor": "Visa USA", "Description": "Schwab Bank Debit Card", "Country": "United States", "AID": "A0000000980848", "Type": "EMV", "Name": "Debit Card"}, {"Vendor": "Die Post Postfinance", "Description": "", "Country": "Switzerland", "AID": "A0000001110101", "Type": "", "Name": "Postcard"}, {"Vendor": "GSA - TFCS", "Description": "CHUID", "Country": "United States", "AID": "A0000001160300", "Type": "", "Name": "PIV CHUID"}, {"Vendor": "GSA - TFCS", "Description": "Fingerprints", "Country": "United States", "AID": "A0000001166010", "Type": "", "Name": "PIV Fingerprints"}, {"Vendor": "GSA - TFCS", "Description": "Facial Image", "Country": "United States", "AID": "A0000001166030", "Type": "", "Name": "PIV Facial Image"}, {"Vendor": "GSA - TFCS", "Description": "Security Object", "Country": "United States", "AID": "A0000001169000", "Type": "", "Name": "PIV Security Object"}, {"Vendor": "GSA - TFCS", "Description": "PIV Authentication Key", "Country": "United States", "AID": "A000000116A001", "Type": "", "Name": "PIV Authentication Key"}, {"Vendor": "GSA - TFCS", "Description": "Card Capability Container", "Country": "United States", "AID": "A000000116DB00", "Type": "", "Name": "CCC"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118010000", "Type": "", "Name": "DF_Verkehr"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118020000", "Type": "", "Name": "DF_Partner"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "A000000118030000", "Type": "", "Name": "DF_Schlerdaten"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.32)", "Country": "Austria", "AID": "A000000118040000", "Type": "", "Name": "DF_KEP_SIG"}, {"Vendor": "Austria Card", "Description": "Digital Signature Application", "Country": "Austria", "AID": "A0000001184543", "Type": "", "Name": "Digital Signature (SSCA)"}, {"Vendor": "Austria Card", "Description": "Encryption Application (Version 1.10)", "Country": "Austria", "AID": "A000000118454E", "Type": "", "Name": "Encryption Application"}, {"Vendor": "PBS Danmark A/S", "Description": "Danish domestic debit card", "Country": "Denmark", "AID": "A0000001211010", "Type": "EMV", "Name": "Dankort (VISA GEM Vision)"}, {"Vendor": "Java Card Forum", "Description": "", "Country": "United States", "AID": "A0000001320001", "Type": "", "Name": "org.javacardforum.javacard.biometry"}, {"Vendor": "TDS TODOS DATA SYSTEM AB", "Description": "", "Country": "Sweden", "AID": "A0000001408001", "Type": "", "Name": "eCode"}, {"Vendor": "Associazione Bancaria Italiana", "Description": "CoGeBan Consorzio BANCOMAT (Italian domestic debit card)", "Country": "Italy", "AID": "A0000001410001", "Type": "EMV", "Name": "PagoBANCOMAT"}, {"Vendor": "GlobalPlatform, Inc.", "Description": "GP Card Manager", "Country": "United States", "AID": "A0000001510000", "Type": "GP", "Name": "Global Platform Security Domain AID"}, {"Vendor": "GlobalPlatform, Inc.", "Description": "SPCASD", "Country": "United States", "AID": "A00000015153504341534400", "Type": "GP", "Name": "CASD_AID"}, {"Vendor": "Diners Club International Ltd.", "Description": "Discover Card", "Country": "United States", "AID": "A0000001523010", "Type": "EMV", "Name": "Discover, Pulse D Pas"}, {"Vendor": "Diners Club International Ltd.", "Description": "Discover Debit Common Card", "Country": "United States", "AID": "A0000001524010", "Type": "EMV", "Name": "Discover"}, {"Vendor": "Banrisul - Banco do Estado do Rio Grande do SUL - S.A.", "Description": "Banrisul (Brazil)", "Country": "Brazil", "AID": "A0000001544442", "Type": "EMV", "Name": "Banricompras Debito"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570010", "Type": "", "Name": "AMEX"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570020", "Type": "", "Name": "MasterCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570021", "Type": "", "Name": "Maestro"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570022", "Type": "", "Name": "Maestro"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570023", "Type": "", "Name": "CASH"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570030", "Type": "", "Name": "VISA"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570031", "Type": "", "Name": "VISA"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570040", "Type": "", "Name": "JCB"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570050", "Type": "", "Name": "Postcard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570051", "Type": "", "Name": "Postcard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570100", "Type": "", "Name": "MCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570104", "Type": "", "Name": "MyOne"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001570109", "Type": "", "Name": "Mediamarkt Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010A", "Type": "", "Name": "Gift Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010B", "Type": "", "Name": "Bonuscard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010C", "Type": "", "Name": "WIRCard"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A000000157010D", "Type": "", "Name": "Power Card"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001574443", "Type": "", "Name": "DINERS CLUB"}, {"Vendor": "Zhlke Engineering AG", "Description": "", "Country": "Switzerland", "AID": "A0000001574444", "Type": "", "Name": "Supercard Plus"}, {"Vendor": "IBM", "Description": "identify in JCOP-tools returns eg 27 34 01 2E 00 00 00 00 4E 58 37 35 31 41 00 03 28 62 B3 6A 82", "Country": "Germany", "AID": "A000000167413000FF", "Type": "JCOP", "Name": "JCOP Identify Applet"}, {"Vendor": "IBM", "Description": "?", "Country": "Germany", "AID": "A000000167413001", "Type": "", "Name": "FIPS 140-2"}, {"Vendor": "Financial Information Service Co. Ltd.", "Description": "The Bankers Association of the Republic of China", "Country": "Taiwan", "AID": "A000000172950001", "Type": "EMV", "Name": "BAROC Financial Application Taiwan"}, {"Vendor": "Ministre de L'Intrieur", "Description": "", "Country": "Belgium", "AID": "A000000177504B43532D3135", "Type": "", "Name": "BelPIC (Belgian Personal Identity Card)"}, {"Vendor": "Post Office Limited", "Description": "", "Country": "United Kingdom", "AID": "A0000001850002", "Type": "EMV", "Name": "UK Post Office Account card"}, {"Vendor": "Diners Club Switzerland Ltd", "Description": "", "Country": "Switzerland", "AID": "A0000001884443", "Type": "", "Name": "DINERS CLUB"}, {"Vendor": "Association for Payment Clearing Services", "Description": "", "Country": "United Kingdom", "AID": "A0000002040000", "Type": "", "Name": "?"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A0000002281010", "Type": "EMV", "Name": "SPAN (M/Chip)"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A0000002282010", "Type": "EMV", "Name": "SPAN (VIS)"}, {"Vendor": "Saudi Arabian Monetary Agency (SAMA)", "Description": "SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)", "Country": "Kingdom of Saudi Arabia", "AID": "A00000022820101010", "Type": "", "Name": "SPAN"}, {"Vendor": "ISO JTC1/SC17/WG3", "Description": "Electronic (Biometric) Passport. Issuer stored data application (The last three digits of the PIX shall be used to denote future version levels.)", "Country": "United Kingdom", "AID": "A0000002471001", "Type": "MRTD", "Name": "Machine Readable Travel Documents (MRTD)"}, {"Vendor": "ISO JTC1/SC17/WG3", "Description": "Electronic (Biometric) Passport. Application for hashes, digital signature, and certificate (The last three digits of the PIX shall be used to denote future version levels.)", "Country": "United Kingdom", "AID": "A0000002472001", "Type": "MRTD", "Name": "Machine Readable Travel Documents (MRTD)"}, {"Vendor": "Interac Association", "Description": "Canadian domestic credit/debit card", "Country": "Canada", "AID": "A0000002771010", "Type": "EMV", "Name": "INTERAC"}, {"Vendor": "PS/SC Workgroup", "Description": "Possibly not an application...", "Country": "United States", "AID": "A00000030600000000000000", "Type": "", "Name": "PC/SC Initial access data AID"}, {"Vendor": "National Institute of Standards and Technology", "Description": "PIV End Point Applet. Last 2 bytes designate version?", "Country": "United States", "AID": "A000000308000010000100", "Type": "", "Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO"}, {"Vendor": "Currence Holding/PIN BV", "Description": "", "Country": "The Netherlands", "AID": "A00000031510100528", "Type": "EMV", "Name": "Currence PuC"}, {"Vendor": "Currence Holding/PIN BV", "Description": "", "Country": "The Netherlands", "AID": "A0000003156020", "Type": "EMV", "Name": "Chipknip"}, {"Vendor": "Identity Alliance", "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", "Country": "United States", "AID": "A00000032301", "Type": "", "Name": "MUSCLE Applet Package"}, {"Vendor": "Identity Alliance", "Description": "http://osdir.com/ml/lib.muscle/2005-12/msg00066.html", "Country": "United States", "AID": "A0000003230101", "Type": "", "Name": "MUSCLE Applet Instance"}, {"Vendor": "Discover Financial Services LLC", "Description": "", "Country": "United States", "AID": "A0000003241010", "Type": "", "Name": "Discover Expresspay (ZIP)"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010101", "Type": "", "Name": "UnionPay Debit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010102", "Type": "", "Name": "UnionPay Credit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010103", "Type": "", "Name": "UnionPay Quasi Credit"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010106", "Type": "", "Name": "UnionPay Electronic Cash"}, {"Vendor": "China Unionpay Co. Ltd", "Description": "", "Country": "China", "AID": "A000000333010108", "Type": "", "Name": "U.S. UnionPay Common Debit AID"}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "Unknown", "Country": "Belgium", "AID": "A0000003591010", "Type": "", "Name": ""}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "ZKA (Germany)", "Country": "Belgium", "AID": "A0000003591010028001", "Type": "EMV", "Name": "Girocard EAPS"}, {"Vendor": "Euro Alliance of Payment Schemes s.c.r.l. - EAPS", "Description": "PagoBANCOMAT", "Country": "Belgium", "AID": "A00000035910100380", "Type": "", "Name": ""}, {"Vendor": "Poste Italiane S.P.A", "Description": "", "Country": "Italy", "AID": "A0000003660001", "Type": "", "Name": "Postamat"}, {"Vendor": "Poste Italiane S.P.A", "Description": "", "Country": "Italy", "AID": "A0000003660002", "Type": "", "Name": "Postamat VISA"}, {"Vendor": "Interswitch Limited", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000003710001", "Type": "EMV", "Name": "InterSwitch Verve Card"}, {"Vendor": "NXP Semiconductors Germany GmbH", "Description": "NXP Mf4M", "Country": "Germany", "AID": "A0000003964D66344D0002", "Type": "", "Name": "MIFARE4MOBILE"}, {"Vendor": "Microsoft Corporation", "Description": "Identity Device With Microsoft Generic Profile application. 2 bytes can be added at the end. This byte must be set to the IDMP specification revision number which is currently 0x01. The second byte (yy) is reserved for use by the card application.", "Country": "United States", "AID": "A00000039742544659", "Type": "", "Name": "Microsoft IDMP AID"}, {"Vendor": "Microsoft Corporation", "Description": "MS Plug and Play", "Country": "United States", "AID": "A0000003974349445F0100", "Type": "", "Name": "Microsoft PNP AID"}, {"Vendor": "Unibanco (Hipercard)", "Description": "", "Country": "Brazil", "AID": "A0000004271010", "Type": "", "Name": "Hiperchip"}, {"Vendor": "100", "Description": "", "Country": "Russia", "AID": "A0000004320001", "Type": "", "Name": "Universal Electronic Card"}, {"Vendor": "Edenred", "Description": "", "Country": "Belgium", "AID": "A0000004360100", "Type": "", "Name": "Ticket Restaurant"}, {"Vendor": "ACCEL/Exchange", "Description": "The Exchange Network ATM Network", "Country": "United States", "AID": "A0000004391010", "Type": "", "Name": "Exchange ATM card"}, {"Vendor": "eTranzact", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000004540010", "Type": "EMV", "Name": "Etranzact Genesis Card"}, {"Vendor": "eTranzact", "Description": "Nigerian local switch company", "Country": "Nigeria", "AID": "A0000004540011", "Type": "EMV", "Name": "Etranzact Genesis Card 2"}, {"Vendor": "Google", "Description": "GOOGLE_LOCKET_AID", "Country": "United States", "AID": "A0000004762010", "Type": "", "Name": "GOOGLE_CONTROLLER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A0000004763030", "Type": "", "Name": "GOOGLE_MIFARE_MANAGER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A0000004766C", "Type": "EMV", "Name": "GOOGLE_PAYMENT_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A000000476A010", "Type": "GP", "Name": "GSD_MANAGER_AID"}, {"Vendor": "Google", "Description": "", "Country": "United States", "AID": "A000000476A110", "Type": "GP", "Name": "GSD_MANAGER_AID"}, {"Vendor": "JVL Ventures, LLC (Softcard)", "Description": "", "Country": "United States", "AID": "A000000485", "Type": "", "Name": "Softcard SmartTap"}, {"Vendor": "RuPay", "Description": "RuPay (India)", "Country": "India", "AID": "A0000005241010", "Type": "EMV", "Name": "RuPay"}, {"Vendor": "Yubico", "Description": "Universal 2-Factor Proof-of-concept/Demo", "Country": "Sweden", "AID": "A0000005271002", "Type": "YKNEO", "Name": "Yubikey NEO U2F Demo applet"}, {"Vendor": "Yubico", "Description": "Javacard Applet AID", "Country": "Sweden", "AID": "A000000527200101", "Type": "YKNEO", "Name": "Yubikey NEO Yubikey2 applet interface"}, {"Vendor": "Yubico", "Description": "Javacard Applet AID", "Country": "Sweden", "AID": "A000000527210101", "Type": "YKNEO", "Name": "Yubikey NEO OATH Applet"}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000100", "Type": "", "Name": "ISD-R Application. Used as TAR."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000200", "Type": "", "Name": "ECASD Application. Used as TAR."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000D00", "Type": "", "Name": "ISD-P Executable Load File."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000E00", "Type": "", "Name": "ISD-P Executable Module."}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900000F00", "Type": "", "Name": "Reserved value for the Profile's ISD-P"}, {"Vendor": "GSMA (GSM Association)", "Description": "", "Country": "United Kingdom", "AID": "A0000005591010FFFFFFFF8900001000", "Type": "", "Name": "ISD-P Application ('1010FFFFFFFF89000010' to '1010FFFFFFFF8900FFFF'. Used as TAR. The value is allocated during the 'Profile Download and Installation procedure'"}, {"Vendor": "Fidesmo", "Description": "", "Country": "Sweden", "AID": "A00000061700", "Type": "", "Name": "Fidesmo javacard"}, {"Vendor": "Debit Network Alliance (DNA)", "Description": "Common U.S. Debit", "Country": "United States", "AID": "A0000006200620", "Type": "", "Name": "Debit Network Alliance (DNA)"}, {"Vendor": "MIR", "Description": "", "Country": "Russia", "AID": "A0000006581010", "Type": "", "Name": "MIR Credit"}, {"Vendor": "MIR", "Description": "", "Country": "Russia", "AID": "A0000006582010", "Type": "", "Name": "MIR Debit"}, {"Vendor": "TROY", "Description": "Turkey's Payment Method", "Country": "Turkey", "AID": "A0000006723010", "Type": "EMV", "Name": "TROY chip credit card"}, {"Vendor": "TROY", "Description": "Turkey's Payment Method", "Country": "Turkey", "AID": "A0000006723020", "Type": "EMV", "Name": "TROY chip debit card"}, {"Vendor": "Indian Oil Corporation Limited", "Description": "Indian Oils Pre Paid Program", "Country": "India", "AID": "A0000007705850", "Type": "EMV", "Name": "XTRAPOWER Fleet Card Program"}, {"Vendor": "MasterCard International", "Description": "Used for development", "Country": "United States", "AID": "B012345678", "Type": "EMV", "Name": "Maestro TEST"}, {"Vendor": "Paylife", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000001000002", "Type": "", "Name": "Paylife Quick (IEP). Preloaded Electronic Purse"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000002000002", "Type": "", "Name": "RFU"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000003000002", "Type": "", "Name": "POS"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D040000004000002", "Type": "", "Name": "ATM"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000B000002", "Type": "", "Name": "Retail"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000C000002", "Type": "", "Name": "Bank_Data"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.1)", "Country": "Austria", "AID": "D04000000D000002", "Type": "", "Name": "Shopping"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000013000001", "Type": "", "Name": "DF_UNI_Kepler1"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000013000001", "Type": "", "Name": "DF_Schler1"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000013000002", "Type": "", "Name": "DF_UNI_Kepler2"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000013000002", "Type": "", "Name": "DF_Schler2"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000014000001", "Type": "", "Name": "DF_Mensa"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 2.0)", "Country": "Austria", "AID": "D040000015000001", "Type": "", "Name": "DF_UNI_Ausweis"}, {"Vendor": "Austria Card", "Description": "Domestic Loyalty Program (Version 1.3)", "Country": "Austria", "AID": "D040000015000001", "Type": "", "Name": "DF_Ausweis"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190001", "Type": "", "Name": "EMV ATM Maestro"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190002", "Type": "", "Name": "EMV POS Maestro"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190003", "Type": "", "Name": "EMV ATM MasterCard"}, {"Vendor": "Austria Card", "Description": "Domestic EMV Application (Version 2.1)", "Country": "Austria", "AID": "D0400000190004", "Type": "", "Name": "EMV POS MasterCard"}, {"Vendor": "Austria Card", "Description": "Domestic Payment System (Version 2.1)", "Country": "Austria", "AID": "D0400000190010", "Type": "", "Name": "Digital ID"}, {"Vendor": "Ministry of Finance of Georgia", "Description": "Georgia Revenue Service application for fiscal cash registers", "Country": "Georgia", "AID": "D268000001", "Type": "", "Name": "Fiscal module application"}, {"Vendor": "Giesecke&Devrient", "Description": "Giesecke & Devrient", "Country": "Germany", "AID": "D276000005", "Type": "", "Name": ""}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA040360010410", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E00401", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E00501", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AA0503E0050101", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "Giesecke&Devrient", "Description": "", "Country": "Germany", "AID": "D276000005AB0503E0040101", "Type": "", "Name": "G D App Nokia 6212"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000001", "Type": "", "Name": "SCT LOYALTY"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000002", "Type": "", "Name": "BUSINESS CARD"}, {"Vendor": "IBM Laboratories", "Description": "IBM Test card from the book 'Smart Card Application Development Using Java'", "Country": "Germany", "AID": "D27600002200000060", "Type": "", "Name": "PKCS#11 Token"}, {"Vendor": "ZKA", "Description": "Girocard (Geldkarte) in Germany", "Country": "Germany", "AID": "D276000025", "Type": "", "Name": "Girocard"}, {"Vendor": "ZKA", "Description": "Unknown", "Country": "Germany", "AID": "D27600002545410100", "Type": "", "Name": ""}, {"Vendor": "ZKA", "Description": "ZKA Girocard (Geldkarte) (Germany)", "Country": "Germany", "AID": "D27600002545500100", "Type": "EMV", "Name": "Girocard"}, {"Vendor": "ZKA", "Description": "", "Country": "Germany", "AID": "D27600002547410100", "Type": "", "Name": "Girocard ATM"}, {"Vendor": "Wolfgang Rankl", "Description": "", "Country": "Germany", "AID": "D276000060", "Type": "", "Name": ""}, {"Vendor": "NXP Semiconductors / NFC Forum", "Description": "NFC Forum Type 4 Tag", "Country": "Germany", "AID": "D2760000850100", "Type": "", "Name": "NDEF Tag Application / Mifare DESFire Tag Application"}, {"Vendor": "NXP Semiconductors / NFC Forum", "Description": "NFC Tag type 4 tag", "Country": "Germany", "AID": "D2760000850101", "Type": "", "Name": "NDEF Tag Application"}, {"Vendor": "Giesecke&Devrient Java Card Telecommunikation", "Description": "", "Country": "Germany", "AID": "D276000118", "Type": "", "Name": ""}, {"Vendor": "Giesecke&Devrient Java Card Telecommunikation", "Description": "Devrient Test Applet?", "Country": "Germany", "AID": "D2760001180101", "Type": "", "Name": "Giesecke &"}, {"Vendor": "fsfEurope", "Description": "For selection when not knowing the exact full AID", "Country": "Germany", "AID": "D27600012401", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "Version 1", "Country": "Germany", "AID": "D276000124010101FFFF000000010000", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "Version 2", "Country": "Germany", "AID": "D2760001240102000000000000010000", "Type": "OpenPGP", "Name": "OpenPGP Card"}, {"Vendor": "fsfEurope", "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", "Country": "Germany", "AID": "D27600012402", "Type": "SmartChess", "Name": "SmartChess"}, {"Vendor": "fsfEurope", "Description": "http://smartchess.de/englisch/SmartChess_1.0.pdf", "Country": "Germany", "AID": "D2760001240200010000000000000000", "Type": "SmartChess", "Name": "SmartChess"}, {"Vendor": "", "Description": "", "Country": "Republic of Korea", "AID": "D4100000011010", "Type": "", "Name": ""}, {"Vendor": "", "Description": "(Netherlands)", "Country": "The Netherlands", "AID": "D5280050218002", "Type": "EMV", "Name": "?"}, {"Vendor": "Bankaxept", "Description": "Norwegian domestic debit card", "Country": "Norway", "AID": "D5780000021010", "Type": "EMV", "Name": "Bankaxept"}, {"Vendor": "Swiss Travel Fund (Reka)", "Description": "prepaid functional debit card", "Country": "Switzerland", "AID": "D7560000010101", "Type": "", "Name": "Reka Card"}, {"Vendor": "Migros (FCM, GE Money Bank and MasterCard)", "Description": "", "Country": "Switzerland", "AID": "D7560000300101", "Type": "", "Name": "M Budget"}, {"Vendor": "", "Description": "German eID", "Country": "", "AID": "E80704007F00070302", "Type": "", "Name": "nPA"}, {"Vendor": "", "Description": "", "Country": "", "AID": "E82881C11702", "Type": "", "Name": "AlphaCard application"}, {"Vendor": "", "Description": "Iso adoption of PKCS-15", "Country": "", "AID": "E828BD080F", "Type": "", "Name": "ISO-7816-15 EF.DIR"}, {"Vendor": "", "Description": "Brazilian Bank Banco Bradesco", "Country": "", "AID": "F0000000030001", "Type": "EMV", "Name": "BRADESCO"}] \ No newline at end of file diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 9ce554ce2..6d7741153 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -914,7 +914,7 @@ static command_t CommandTable[] = }; int CmdHFFido(const char *Cmd) { - (void)WaitForResponseTimeout(CMD_ACK,NULL,100); + (void)WaitForResponseTimeout(CMD_ACK, NULL, 100); CmdsParse(CommandTable, Cmd); return 0; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 1ba59dced..a5a20f5e2 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -8,6 +8,7 @@ // Proxmark3 RDV40 Smartcard module commands //----------------------------------------------------------------------------- #include "cmdsmartcard.h" +#include "../emv/emvjson.h" static int CmdHelp(const char *Cmd); @@ -24,6 +25,9 @@ int usage_sm_raw(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e4444463031 - `1PAY.SYS.DDF01` PPSE directory with get ATR"); PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e4444463031 - `2PAY.SYS.DDF01` PPSE directory"); + PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a000000004101000 - Mastercard"); + PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a0000000031010 - Visa"); + return 0; } int usage_sm_reader(void) { @@ -64,15 +68,48 @@ int usage_sm_setclock(void) { return 0; } int usage_sm_brute(void) { - PrintAndLogEx(NORMAL, "Tries to bruteforce SFI, "); + PrintAndLogEx(NORMAL, "Tries to bruteforce SFI, using a known list of AID's "); PrintAndLogEx(NORMAL, "Usage: sc brute [h]"); PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " t : executes TLV decoder if it possible"); +// PrintAndLogEx(NORMAL, " 0 : use protocol T=0"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " sc brute"); + PrintAndLogEx(NORMAL, " sc brute t"); return 0; } +static int smart_loadjson(const char *preferredName, const char *suffix, json_t **root) { + + json_error_t error; + + if ( preferredName == NULL ) return 1; + if ( suffix == NULL ) return 1; + + int retval = 0; + int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); + char * fileName = calloc(size, sizeof(char)); + sprintf(fileName, "%s.%s", preferredName, suffix); + + *root = json_load_file(fileName, 0, &error); + if (!*root) { + PrintAndLogEx(ERR, "json (%s) error on line %d: %s", fileName, error.line, error.text); + retval = 2; + goto out; + } + + if (!json_is_array(*root)) { + PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", fileName); + retval = 3; + goto out; + } + + PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", fileName); +out: + free(fileName); + return retval; +} + uint8_t GetATRTA1(uint8_t *atr, size_t atrlen) { if (atrlen > 2) { uint8_t T0 = atr[1]; @@ -142,19 +179,16 @@ float FArray[] = { int GetATRDi(uint8_t *atr, size_t atrlen) { uint8_t TA1 = GetATRTA1(atr, atrlen); - - return DiArray[TA1 & 0x0f]; // The 4 low-order bits of TA1 (4th MSbit to 1st LSbit) encode Di + return DiArray[TA1 & 0x0F]; // The 4 low-order bits of TA1 (4th MSbit to 1st LSbit) encode Di } int GetATRFi(uint8_t *atr, size_t atrlen) { uint8_t TA1 = GetATRTA1(atr, atrlen); - return FiArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi } float GetATRF(uint8_t *atr, size_t atrlen) { uint8_t TA1 = GetATRTA1(atr, atrlen); - return FArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi } @@ -284,31 +318,31 @@ static bool smart_select(bool silent) { return true; } -static int smart_wait(uint8_t *data) { +static int smart_wait(uint8_t *data, bool silent) { UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { - PrintAndLogEx(WARNING, "smart card response timeout"); + if (!silent) PrintAndLogEx(WARNING, "smart card response timeout"); return -1; } uint32_t len = resp.arg[0]; if ( !len ) { - PrintAndLogEx(WARNING, "smart card response failed"); + if (!silent) PrintAndLogEx(WARNING, "smart card response failed"); return -2; } memcpy(data, resp.d.asBytes, len); if (len >= 2) { - PrintAndLogEx(SUCCESS, "%02X%02X | %s", data[len - 2], data[len - 1], GetAPDUCodeDescription(data[len - 2], data[len - 1])); + if (!silent) PrintAndLogEx(SUCCESS, "%02X%02X | %s", data[len - 2], data[len - 1], GetAPDUCodeDescription(data[len - 2], data[len - 1])); } else { - PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 8)); + if (!silent) PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 8)); } return len; } -static int smart_response(uint8_t *data) { +static int smart_responseEx(uint8_t *data, bool silent) { - int datalen = smart_wait(data); + int datalen = smart_wait(data, silent); bool needGetData = false; if (datalen < 2 ) { @@ -321,14 +355,14 @@ static int smart_response(uint8_t *data) { if (needGetData) { int len = data[datalen - 1]; - PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); + if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len}; UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}}; memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) ); clearCommandBuffer(); SendCommand(&cStatus); - datalen = smart_wait(data); + datalen = smart_wait(data, silent); if (datalen < 2 ) { goto out; @@ -339,7 +373,9 @@ static int smart_response(uint8_t *data) { // data with ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK if (data[0] != ISO7816_GETSTATUS) { - PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); + if (!silent) { + PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); + } datalen = 0; goto out; } @@ -348,7 +384,9 @@ static int smart_response(uint8_t *data) { memmove(data, &data[1], datalen); } else { // wrong length - PrintAndLogEx(WARNING, "GetResponse wrong length. Must be 0x%02X got 0x%02X", len, datalen - 3); + if (!silent) { + PrintAndLogEx(WARNING, "GetResponse wrong length. Must be 0x%02X got 0x%02X", len, datalen - 3); + } } } } @@ -357,6 +395,10 @@ out: return datalen; } +static int smart_response(uint8_t *data) { + return smart_responseEx(data, false); +} + int CmdSmartRaw(const char *Cmd) { int hexlen = 0; @@ -488,7 +530,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave clearCommandBuffer(); SendCommand(&c); - int len = smart_response(dataout); + int len = smart_responseEx(dataout, true); if ( len < 0 ) { return 2; @@ -505,11 +547,10 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave clearCommandBuffer(); SendCommand(&c2); - len = smart_response(dataout); + len = smart_responseEx(dataout, true); } *dataoutlen = len; - return 0; } @@ -679,14 +720,14 @@ int CmdSmartInfo(const char *Cmd){ if (GetATRTA1(card.atr, card.atr_len) == 0x11) PrintAndLogEx(INFO, "Using default values..."); - PrintAndLogEx(NORMAL, "\t- Di=%d", Di); - PrintAndLogEx(NORMAL, "\t- Fi=%d", Fi); - PrintAndLogEx(NORMAL, "\t- F=%.1f MHz", F); + PrintAndLogEx(NORMAL, "\t- Di %d", Di); + PrintAndLogEx(NORMAL, "\t- Fi %d", Fi); + PrintAndLogEx(NORMAL, "\t- F %.1f MHz", F); if (Di && Fi) { - PrintAndLogEx(NORMAL, "\t- Cycles/ETU=%d", Fi/Di); + PrintAndLogEx(NORMAL, "\t- Cycles/ETU %d", Fi/Di); PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di)); - PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F); + PrintAndLogEx(NORMAL, "\t- %.1f bits/sec at Fmax (%.1fMHz)", (F * 1000000) / (Fi/Di), F); } else { PrintAndLogEx(WARNING, "\t- Di or Fi is RFU."); }; @@ -798,58 +839,210 @@ int CmdSmartList(const char *Cmd) { int CmdSmartBruteforceSFI(const char *Cmd) { - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_sm_brute(); - - uint8_t data[5] = {0x00, 0xB2, 0x00, 0x00, 0x00}; - - PrintAndLogEx(INFO, "Selecting card"); - if ( !smart_select(false) ) { - return 1; + uint8_t cmdp = 0; + bool errors = false, decodeTLV = false; //, useT0 = false; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': return usage_sm_brute(); + case 't': + decodeTLV = true; + cmdp++; + break; +/* + case '0': + useT0 = true; + cmdp++; + break; +*/ + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - PrintAndLogEx(INFO, "Selecting PPSE aid"); - CmdSmartRaw("s 0 t d 00a404000e325041592e5359532e4444463031"); - CmdSmartRaw("0 t d 00a4040007a000000004101000"); // mastercard -// CmdSmartRaw("0 t d 00a4040007a0000000031010"); // visa + //Validations + if (errors) return usage_sm_brute(); + + const char *SELECT = "00a40400%02x%s"; - PrintAndLogEx(INFO, "starting"); + uint8_t READ_RECORD[] = {0x00, 0xB2, 0x00, 0x00, 0x00}; + uint8_t GET_PROCESSING_OPTIONS[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00}; + +// uint8_t GENERATE_AC[] = {0x80, 0xAE}; +// uint8_t GET_CHALLENGE[] = {0x00, 0x84, 0x00}; +// uint8_t GET_DATA[] = {0x80, 0xCA, 0x00, 0x00, 0x00}; +// uint8_t SELECT[] = {0x00, 0xA4, 0x04, 0x00}; +// uint8_t UNBLOCK_PIN[] = {0x84, 0x24, 0x00, 0x00, 0x00}; +// uint8_t VERIFY[] = {0x00, 0x20, 0x00, 0x80}; - UsbCommand c = {CMD_SMART_RAW, {SC_RAW, sizeof(data), 0}}; + + // Select AID command + UsbCommand cAid = {CMD_SMART_RAW, {SC_RAW_T0, 0, 0}}; + + // Get processing options command + UsbCommand cOpt = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(GET_PROCESSING_OPTIONS), 0}}; + memcpy(cOpt.d.asBytes, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS) ); + + // READ RECORD + UsbCommand cSFI = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(READ_RECORD), 0}}; + + + PrintAndLogEx(INFO, "Importing AID list"); + json_t *root = NULL; + smart_loadjson("aidlist", "json", &root); + uint8_t* buf = malloc(USB_CMD_DATA_SIZE); if ( !buf ) return 1; - - for (uint8_t i=1; i < 4; i++) { - for (int p1=1; p1 < 5; p1++) { - - data[2] = p1; - data[3] = (i << 3) + 4; - memcpy(c.d.asBytes, data, sizeof(data) ); - clearCommandBuffer(); - SendCommand(&c); - - smart_response(buf); - - if ( buf[0] == 0x6C ) { - data[4] = buf[1]; - - memcpy(c.d.asBytes, data, sizeof(data) ); - clearCommandBuffer(); - SendCommand(&c); - uint8_t len = smart_response(buf); - - // TLV decoder - if (len > 4) - TLVPrintFromBuffer(buf+1, len-3); + uint8_t* sfibuf = malloc(USB_CMD_DATA_SIZE); + if ( !sfibuf ) + return 1; + + PrintAndLogEx(INFO, "Selecting card"); + if ( !smart_select(false) ) + return 1; + - data[4] = 0; - } - memset(buf, 0x00, USB_CMD_DATA_SIZE); + for (int i = 0; i < json_array_size(root); i++) { + json_t *data, *jaid; + + data = json_array_get(root, i); + if (!json_is_object(data)) { + PrintAndLogEx(ERR, "data %d is not an object\n", i + 1); + json_decref(root); + return 1; } - } + + jaid = json_object_get(data, "AID"); + if (!json_is_string(jaid)) { + PrintAndLogEx(ERR, "AID data [%d] is not a string", i + 1); + json_decref(root); + return 1; + } + + const char* aid = json_string_value(jaid); + if ( !aid ) continue; + + size_t aidlen = strlen(aid); + char* caid = calloc( 8+2+aidlen+1, sizeof(uint8_t)); + snprintf(caid, 8+2+aidlen+1, SELECT, aidlen >> 1, aid); + + int hexlen = 0; + int res = param_gethex_to_eol(caid, 0, cAid.d.asBytes, sizeof(cAid.d.asBytes), &hexlen); + if ( res ) continue; + + cAid.arg[1] = hexlen; + + clearCommandBuffer(); + SendCommand(&cAid); + + int len = smart_responseEx(buf, true); + if ( len < 3 ) { + free(caid); + continue; + } + + json_t *jvendor, *jname; + jvendor = json_object_get(data, "Vendor"); + if (!json_is_string(jvendor)) { + PrintAndLogEx(ERR, "Vendor data [%d] is not a string", i + 1); + continue; + } + + const char* vendor = json_string_value(jvendor); + if ( !vendor ) continue; + + jname = json_object_get(data, "Name"); + if (!json_is_string(jname)) { + PrintAndLogEx(ERR, "Name data [%d] is not a string", i + 1); + continue; + } + const char* name = json_string_value(jname); + if ( !name ) continue; + + PrintAndLogEx(SUCCESS, "AID %s | %s | %s", aid, vendor, name); + + // Get processing options + clearCommandBuffer(); + SendCommand(&cOpt); + + uint8_t optionslen = smart_responseEx(buf, true); + if ( optionslen > 4 ) { + PrintAndLogEx(SUCCESS, "Got processing options"); + if ( decodeTLV ) { + TLVPrintFromBuffer(buf, optionslen-2); + } + } else { + PrintAndLogEx(FAILED, "Getting processing options failed"); + } + + PrintAndLogEx(INFO, "Start SFI brute forcing"); + + for (uint8_t sfi=1; sfi <= 31; sfi++) { + + printf("."); fflush(stdout); + + for (uint16_t rec=1; rec <= 5; rec++) { + + if (ukbhit()) { + int gc = getchar(); (void)gc; + PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + free(caid); + goto out; + } + + READ_RECORD[2] = rec; + READ_RECORD[3] = (sfi << 3) | 4; + + memcpy(cSFI.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); + clearCommandBuffer(); + SendCommand(&cSFI); + + uint8_t sfilen = smart_responseEx(sfibuf, true); + + if ( sfibuf[0] == 0x6C ) { + READ_RECORD[4] = sfibuf[1]; + + memcpy(cSFI.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); + clearCommandBuffer(); + SendCommand(&cSFI); + sfilen = smart_responseEx(sfibuf, true); + + READ_RECORD[4] = 0; + } + + if ( sfilen > 4 ) { + + PrintAndLogEx(SUCCESS, "\n\t file %02d, record %02d found", sfi, rec); + + uint8_t modifier = (sfibuf[0] == 0xC0) ? 1 : 0; + + if ( decodeTLV ) { + if (!TLVPrintFromBuffer(sfibuf + modifier, sfilen-2-modifier)) { + PrintAndLogEx(SUCCESS, "\tHEX: %s", sprint_hex(sfibuf, sfilen)); + } + } + + } + memset(sfibuf, 0x00, USB_CMD_DATA_SIZE); + } + } + + free(sfibuf); + free(caid); + PrintAndLogEx(SUCCESS, "\nSFI brute force done\n"); + } +out: + if ( sfibuf ) + free(sfibuf); + free(buf); + json_decref(root); + + PrintAndLogEx(SUCCESS, "Search completed."); return 0; } diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 647123faf..13f64a616 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1464,6 +1464,7 @@ int CmdEMVGetrng(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'h' || cmdp == 'H') return usage_emv_getrnd(); + PrintAndLogEx(INFO, "Not implemented yet"); return 0; } diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index cc2897127..63397f19e 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -259,6 +259,21 @@ static const struct emv_tag emv_tags[] = { { 0x9f4c, "ICC Dynamic Number" }, { 0x9f4d, "Log Entry" }, { 0x9f4f, "Log Format", EMV_TAG_DOL }, + + { 0x9f50, "Offline Accumulator Balance" }, + { 0x9f51, "Application Currency Code" }, + { 0x9f51, "DRDOL" }, + { 0x9f52, "Application Default Action (ADA)" }, + { 0x9f52, "Terminal Compatibility Indicator" }, + { 0x9f55, "Issuer Authentication Flags" }, + { 0x9f56, "Issuer Authentication Indicator" }, + { 0x9f57, "Issuer Country Code" }, + { 0x9f58, "Consecutive Transaction Counter Limit (CTCL)" }, + { 0x9f59, "Consecutive Transaction Counter Upper Limit (CTCUL)" }, + { 0x9f5A, "Application Program Identifier" }, + { 0x9f5b, "Issuer Script Results" }, + { 0x9f5c, "Cumulative Total Transaction Amount Upper Limit (CTTAUL)" }, + { 0x9f60, "CVC3 (Track1)" }, { 0x9f61, "CVC3 (Track2)" }, { 0x9f62, "PCVC3(Track1)" }, @@ -278,21 +293,18 @@ static const struct emv_tag emv_tags[] = { { 0xdf20, "Issuer Proprietary Bitmap (IPB)" }, }; -static int emv_sort_tag(tlv_tag_t tag) -{ +static int emv_sort_tag(tlv_tag_t tag) { return (int)(tag >= 0x100 ? tag : tag << 8); } -static int emv_tlv_compare(const void *a, const void *b) -{ +static int emv_tlv_compare(const void *a, const void *b) { const struct tlv *tlv = a; const struct emv_tag *tag = b; return emv_sort_tag(tlv->tag) - (emv_sort_tag(tag->tag)); } -static const struct emv_tag *emv_get_tag(const struct tlv *tlv) -{ +static const struct emv_tag *emv_get_tag(const struct tlv *tlv) { struct emv_tag *tag = bsearch(tlv, emv_tags, sizeof(emv_tags)/sizeof(emv_tags[0]), sizeof(emv_tags[0]), emv_tlv_compare); @@ -310,8 +322,7 @@ static const char *bitstrings[] = { "1.......", }; -static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) -{ +static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { const struct emv_tag_bit *bits = tag->data; unsigned bit, byte; @@ -331,8 +342,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta } } -static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) -{ +static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { const unsigned char *buf = tlv->value; size_t left = tlv->len; @@ -353,7 +363,7 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F } } -static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level){ +static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { fprintf(f, "\tString value '"); fwrite(tlv->value, 1, tlv->len, f); fprintf(f, "'\n"); @@ -468,8 +478,6 @@ static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, F if (data[0] || data[1] || data[2] || data[3]) emv_tag_dump_bitmask(&bit_tlv, &bit_tag, f, level); - - return; } // EMV Book 3 @@ -512,12 +520,9 @@ static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, F break; } } - - return; } -static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) -{ +static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { uint32_t X, Y; int i; @@ -615,7 +620,7 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t } } -static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level){ +static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { if (tlv->len < 4 || tlv->len % 4) { PRINT_INDENT(level); fprintf(f, "\tINVALID!\n"); @@ -628,8 +633,7 @@ static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, F } } -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) -{ +bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) { if (!tlv) { fprintf(f, "NULL\n"); return false; @@ -682,8 +686,7 @@ bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) return true; } -char *emv_get_tag_name(const struct tlv *tlv) -{ +char *emv_get_tag_name(const struct tlv *tlv) { static char *defstr = ""; if (!tlv) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 058aefe50..0c3bb7626 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -120,7 +120,7 @@ static bool print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) return true; } -void TLVPrintFromBuffer(uint8_t *data, int datalen) { +bool TLVPrintFromBuffer(uint8_t *data, int datalen) { struct tlvdb *t = NULL; t = tlvdb_parse_multi(data, datalen); if (t) { @@ -128,9 +128,11 @@ void TLVPrintFromBuffer(uint8_t *data, int datalen) { tlvdb_visit(t, print_cb, NULL, 0); tlvdb_free(t); + return true; } else { PrintAndLogEx(WARNING, "TLV ERROR: Can't parse response as TLV tree."); } + return false; } void TLVPrintFromTLVLev(struct tlvdb *tlv, int level) { diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index c2b1746e1..1117c7f78 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -65,7 +65,7 @@ enum CardPSVendor { }; extern enum CardPSVendor GetCardPSVendor(uint8_t * AID, size_t AIDlen); -extern void TLVPrintFromBuffer(uint8_t *data, int datalen); +extern bool TLVPrintFromBuffer(uint8_t *data, int datalen); extern void TLVPrintFromTLV(struct tlvdb *tlv); extern void TLVPrintFromTLVLev(struct tlvdb *tlv, int level); extern void TLVPrintAIDlistFromSelectTLV(struct tlvdb *tlv); From 5140db2ac63a615b0cbd47486b99561480136ed2 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 25 Dec 2018 18:13:41 +0100 Subject: [PATCH 010/320] CHG: some more descriptions --- client/emv/emv_tags.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 63397f19e..47cc9e79d 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -198,6 +198,9 @@ static const struct emv_tag emv_tags[] = { { 0x61 , "Application Template" }, { 0x6f , "File Control Information (FCI) Template" }, { 0x70 , "READ RECORD Response Message Template" }, + { 0x71 , "Issues Script Template 1" }, + { 0x72 , "Issues Script Template 2" }, + { 0x73 , "Directory Discretionary Template" }, { 0x77 , "Response Message Template Format 2" }, { 0x80 , "Response Message Template Format 1" }, { 0x82 , "Application Interchange Profile", EMV_TAG_BITMASK, &EMV_AIP }, From ddfe58458255b5e8129170bdab4fabd4e4bb6c8e Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 25 Dec 2018 18:16:47 +0100 Subject: [PATCH 011/320] CHG: 'sc brute' - nicer output, rearrange code --- client/cmdsmartcard.c | 256 ++++++++++++++++++++++++++---------------- 1 file changed, 159 insertions(+), 97 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index a5a20f5e2..443833ac2 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -25,7 +25,7 @@ int usage_sm_raw(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc raw s 0 d 00a404000e315041592e5359532e4444463031 - `1PAY.SYS.DDF01` PPSE directory with get ATR"); PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e4444463031 - `2PAY.SYS.DDF01` PPSE directory"); - PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a000000004101000 - Mastercard"); + PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a0000000041010 - Mastercard"); PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a0000000031010 - Visa"); return 0; @@ -837,6 +837,137 @@ int CmdSmartList(const char *Cmd) { return 0; } +static void smart_brute_prim(){ + + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); + if ( !buf ) + return; + + int len = 0; + uint8_t get_card_data[] = { + 0x80, 0xCA, 0x9F, 0x13, 0x00, + 0x80, 0xCA, 0x9F, 0x17, 0x00, + 0x80, 0xCA, 0x9F, 0x36, 0x00, + 0x80, 0xCA, 0x9F, 0x4f, 0x00 + }; + + UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, 5, 0}}; + + PrintAndLogEx(INFO, "Reading primitives"); + + for (int i = 0; i < sizeof(get_card_data); i += 5) { + + memcpy(c.d.asBytes, get_card_data+i, 5 ); + clearCommandBuffer(); + SendCommand(&c); + + len = smart_responseEx(buf, true); + + if ( len > 2 ) { + + //if ( decodeTLV ) { + //if (!TLVPrintFromBuffer(buf, len-2)) { + PrintAndLogEx(SUCCESS, "\tHEX %d |: %s", len, sprint_hex(buf, len)); + //} + //} + } + len = 0; + } + free(buf); +} + +static int smart_brute_sfi(bool decodeTLV){ + + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); + if ( !buf ) + return 1; + + int len = 0; + // READ RECORD + uint8_t READ_RECORD[] = {0x00, 0xB2, 0x00, 0x00, 0x00}; + UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(READ_RECORD), 0}}; + + PrintAndLogEx(INFO, "Start SFI brute forcing"); + + for (uint8_t sfi=1; sfi <= 3; sfi++) { + + printf("."); fflush(stdout); + + for (uint16_t rec=1; rec <= 3; rec++) { + + if (ukbhit()) { + int gc = getchar(); (void)gc; + PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + free(buf); + return 1; + } + + READ_RECORD[2] = rec; + READ_RECORD[3] = (sfi << 3) | 4; + + memcpy(c.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); + clearCommandBuffer(); + SendCommand(&c); + + len = smart_responseEx(buf, true); + + if ( buf[0] == 0x6C ) { + READ_RECORD[4] = buf[1]; + + memcpy(c.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); + clearCommandBuffer(); + SendCommand(&c); + len = smart_responseEx(buf, true); + + READ_RECORD[4] = 0; + } + + if ( len > 4 ) { + + PrintAndLogEx(SUCCESS, "\n\t file %02d, record %02d found", sfi, rec); + + uint8_t modifier = (buf[0] == 0xC0) ? 1 : 0; + + if ( decodeTLV ) { + if (!TLVPrintFromBuffer(buf + modifier, len-2-modifier)) { + PrintAndLogEx(SUCCESS, "\tHEX: %s", sprint_hex(buf, len)); + } + } + } + memset(buf, 0x00, USB_CMD_DATA_SIZE); + } + } + free(buf); + return 0; +} + +static void smart_brute_options(bool decodeTLV){ + + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); + if ( !buf ) + return; + + uint8_t GET_PROCESSING_OPTIONS[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00}; + + // Get processing options command + UsbCommand c = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(GET_PROCESSING_OPTIONS), 0}}; + memcpy(c.d.asBytes, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS) ); + clearCommandBuffer(); + SendCommand(&c); + + int len = smart_responseEx(buf, true); + if ( len > 4 ) { + PrintAndLogEx(SUCCESS, "Got processing options"); + if ( decodeTLV ) { + TLVPrintFromBuffer(buf, len-2); + } + } else { + PrintAndLogEx(FAILED, "Getting processing options failed"); + } + + free(buf); +} + int CmdSmartBruteforceSFI(const char *Cmd) { uint8_t cmdp = 0; @@ -867,27 +998,15 @@ int CmdSmartBruteforceSFI(const char *Cmd) { const char *SELECT = "00a40400%02x%s"; - uint8_t READ_RECORD[] = {0x00, 0xB2, 0x00, 0x00, 0x00}; - uint8_t GET_PROCESSING_OPTIONS[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00}; - // uint8_t GENERATE_AC[] = {0x80, 0xAE}; // uint8_t GET_CHALLENGE[] = {0x00, 0x84, 0x00}; // uint8_t GET_DATA[] = {0x80, 0xCA, 0x00, 0x00, 0x00}; // uint8_t SELECT[] = {0x00, 0xA4, 0x04, 0x00}; // uint8_t UNBLOCK_PIN[] = {0x84, 0x24, 0x00, 0x00, 0x00}; // uint8_t VERIFY[] = {0x00, 0x20, 0x00, 0x80}; - - - // Select AID command - UsbCommand cAid = {CMD_SMART_RAW, {SC_RAW_T0, 0, 0}}; - // Get processing options command - UsbCommand cOpt = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(GET_PROCESSING_OPTIONS), 0}}; - memcpy(cOpt.d.asBytes, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS) ); - - // READ RECORD - UsbCommand cSFI = {CMD_SMART_RAW, {SC_RAW_T0, sizeof(READ_RECORD), 0}}; - + // Select AID command + UsbCommand cAid = {CMD_SMART_RAW, {SC_RAW_T0, 0, 0}}; PrintAndLogEx(INFO, "Importing AID list"); json_t *root = NULL; @@ -897,16 +1016,19 @@ int CmdSmartBruteforceSFI(const char *Cmd) { if ( !buf ) return 1; - uint8_t* sfibuf = malloc(USB_CMD_DATA_SIZE); - if ( !sfibuf ) - return 1; - PrintAndLogEx(INFO, "Selecting card"); if ( !smart_select(false) ) return 1; + char* caid = NULL; for (int i = 0; i < json_array_size(root); i++) { + + printf("+"); fflush(stdout); + + if (caid) + free(caid); + json_t *data, *jaid; data = json_array_get(root, i); @@ -924,7 +1046,8 @@ int CmdSmartBruteforceSFI(const char *Cmd) { } const char* aid = json_string_value(jaid); - if ( !aid ) continue; + if ( !aid ) + continue; size_t aidlen = strlen(aid); char* caid = calloc( 8+2+aidlen+1, sizeof(uint8_t)); @@ -932,7 +1055,8 @@ int CmdSmartBruteforceSFI(const char *Cmd) { int hexlen = 0; int res = param_gethex_to_eol(caid, 0, cAid.d.asBytes, sizeof(cAid.d.asBytes), &hexlen); - if ( res ) continue; + if ( res ) + continue; cAid.arg[1] = hexlen; @@ -940,10 +1064,8 @@ int CmdSmartBruteforceSFI(const char *Cmd) { SendCommand(&cAid); int len = smart_responseEx(buf, true); - if ( len < 3 ) { - free(caid); + if ( len < 3 ) continue; - } json_t *jvendor, *jname; jvendor = json_object_get(data, "Vendor"); @@ -953,96 +1075,36 @@ int CmdSmartBruteforceSFI(const char *Cmd) { } const char* vendor = json_string_value(jvendor); - if ( !vendor ) continue; - + if ( !vendor ) + continue; + jname = json_object_get(data, "Name"); if (!json_is_string(jname)) { PrintAndLogEx(ERR, "Name data [%d] is not a string", i + 1); continue; } const char* name = json_string_value(jname); - if ( !name ) continue; + if ( !name ) + continue; - PrintAndLogEx(SUCCESS, "AID %s | %s | %s", aid, vendor, name); + PrintAndLogEx(SUCCESS, "\nAID %s | %s | %s", aid, vendor, name); - // Get processing options - clearCommandBuffer(); - SendCommand(&cOpt); - - uint8_t optionslen = smart_responseEx(buf, true); - if ( optionslen > 4 ) { - PrintAndLogEx(SUCCESS, "Got processing options"); - if ( decodeTLV ) { - TLVPrintFromBuffer(buf, optionslen-2); - } - } else { - PrintAndLogEx(FAILED, "Getting processing options failed"); - } - - PrintAndLogEx(INFO, "Start SFI brute forcing"); - - for (uint8_t sfi=1; sfi <= 31; sfi++) { + smart_brute_options(decodeTLV); - printf("."); fflush(stdout); - - for (uint16_t rec=1; rec <= 5; rec++) { + smart_brute_prim(); - if (ukbhit()) { - int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); - free(caid); - goto out; - } - - READ_RECORD[2] = rec; - READ_RECORD[3] = (sfi << 3) | 4; + smart_brute_sfi(decodeTLV); - memcpy(cSFI.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); - clearCommandBuffer(); - SendCommand(&cSFI); - - uint8_t sfilen = smart_responseEx(sfibuf, true); - - if ( sfibuf[0] == 0x6C ) { - READ_RECORD[4] = sfibuf[1]; - - memcpy(cSFI.d.asBytes, READ_RECORD, sizeof(READ_RECORD) ); - clearCommandBuffer(); - SendCommand(&cSFI); - sfilen = smart_responseEx(sfibuf, true); - - READ_RECORD[4] = 0; - } - - if ( sfilen > 4 ) { - - PrintAndLogEx(SUCCESS, "\n\t file %02d, record %02d found", sfi, rec); - - uint8_t modifier = (sfibuf[0] == 0xC0) ? 1 : 0; - - if ( decodeTLV ) { - if (!TLVPrintFromBuffer(sfibuf + modifier, sfilen-2-modifier)) { - PrintAndLogEx(SUCCESS, "\tHEX: %s", sprint_hex(sfibuf, sfilen)); - } - } - - } - memset(sfibuf, 0x00, USB_CMD_DATA_SIZE); - } - } - - free(sfibuf); - free(caid); PrintAndLogEx(SUCCESS, "\nSFI brute force done\n"); } -out: - if ( sfibuf ) - free(sfibuf); + + if (caid) + free(caid); free(buf); json_decref(root); - PrintAndLogEx(SUCCESS, "Search completed."); + PrintAndLogEx(SUCCESS, "\nSearch completed."); return 0; } From ab9048f7c56c0626e470c62ced6548872fce62c8 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 25 Dec 2018 18:18:48 +0100 Subject: [PATCH 012/320] CHG: 'sc brute' loop 31, 255 --- client/cmdsmartcard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 443833ac2..a864e2358 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -889,11 +889,11 @@ static int smart_brute_sfi(bool decodeTLV){ PrintAndLogEx(INFO, "Start SFI brute forcing"); - for (uint8_t sfi=1; sfi <= 3; sfi++) { + for (uint8_t sfi=1; sfi <= 31; sfi++) { printf("."); fflush(stdout); - for (uint16_t rec=1; rec <= 3; rec++) { + for (uint16_t rec=1; rec <= 255; rec++) { if (ukbhit()) { int gc = getchar(); (void)gc; From 33f6439d38ed43172f782cc465d26aa44f1c21c1 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 26 Dec 2018 11:02:00 +0100 Subject: [PATCH 013/320] add 'emv roca' - new command, will be able to test for ROCA --- client/emv/cmdemv.c | 98 ++++++++++++++++++++++++++++++++++++++++---- client/emv/cmdemv.h | 1 + client/emv/emvcore.c | 8 ++-- client/emv/emvcore.h | 1 + 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 13f64a616..14616e0f0 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1382,7 +1382,7 @@ int CmdEMVScan(const char *cmd) { uint8_t SFIend = AFL->value[i * 4 + 2]; uint8_t SFIoffline = AFL->value[i * 4 + 3]; - PrintAndLog("--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); + PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) { PrintAndLogEx(ERR, "SFI ERROR! Skipped..."); continue; @@ -1476,6 +1476,89 @@ int CmdEMVTest(const char *cmd) { return ExecuteCryptoTests(true); } +int CmdEMVRoca(const char *cmd) { + + CLIParserInit("emv roca", + "Tries to extract public keys and run the ROCA test against them.\n", + "Usage:\n\temv roca -w -> select CONTACT card and run test\n\temv roca -> select CONTACTLESS card and run test\n"); + + void* argtable[] = { + arg_param_begin, + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + EMVCommandChannel channel = ECC_CONTACTLESS; + if (arg_get_lit(1)) + channel = ECC_CONTACT; + + // Init TLV tree + const char *alr = "Root terminal TLV tree"; + struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr); + + + + int res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot); + + // getting certificates + if (tlvdb_get(tlvRoot, 0x90, NULL)) { + PrintAndLogEx(INFO, "-->Recovering certificates."); + PKISetStrictExecution(false); + + struct emv_pk *pk = get_ca_pk(tlvRoot); + if (!pk) { + PrintAndLogEx(ERR, "ERROR: Key not found. Exit."); + goto out; + } + + struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlvRoot); + if (!issuer_pk) { + emv_pk_free(pk); + PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found. Exit."); + goto out; + } + + PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %s IDX %02hhx CSN %s", + sprint_hex(issuer_pk->rid, 5), + issuer_pk->index, + sprint_hex(issuer_pk->serial, 3) + ); + + + struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, NULL); + if (!icc_pk) { + emv_pk_free(pk); + emv_pk_free(issuer_pk); + PrintAndLogEx(WARNING, "WARNING: ICC certificate not found. Exit."); + goto out; + } + PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %s IDX %02hhx CSN %s\n", + sprint_hex(icc_pk->rid, 5), + icc_pk->index, + sprint_hex(icc_pk->serial, 3) + ); + +// icc_pk->exp, icc_pk->elen +// icc_pk->modulus, icc_pk->mlen + + + PKISetStrictExecution(true); + } + +out: + + // free tlv object + tlvdb_free(tlvRoot); + + if ( channel == ECC_CONTACTLESS) + DropField(); + + + return 0; +} + + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"exec", CmdEMVExec, 0, "Executes EMV contactless transaction."}, @@ -1490,13 +1573,14 @@ static command_t CommandTable[] = { {"scan", CmdEMVScan, 0, "Scan EMV card and save it contents to json file for emulator."}, {"test", CmdEMVTest, 0, "Crypto logic test."}, /* - {"getrng", CmdEMVGetrng, 0, "get random number from terminal"}, - {"eload", CmdEmvELoad, 0, "load EMV tag into device"}, - {"dump", CmdEmvDump, 0, "dump EMV tag values"}, - {"sim", CmdEmvSim, 0, "simulate EMV tag"}, - {"clone", CmdEmvClone, 0, "clone an EMV tag"}, + {"getrng", CmdEMVGetrng, 0, "get random number from terminal"}, + {"eload", CmdEmvELoad, 0, "load EMV tag into device"}, + {"dump", CmdEmvDump, 0, "dump EMV tag values"}, + {"sim", CmdEmvSim, 0, "simulate EMV tag"}, + {"clone", CmdEmvClone, 0, "clone an EMV tag"}, */ - {"list", CmdEMVList, 0, "[Deprecated] List ISO7816 history"}, + {"list", CmdEMVList, 0, "[Deprecated] List ISO7816 history"}, + {"roca", CmdEMVRoca, 0, "Extract public keys and run ROCA test"}, {NULL, NULL, 0, NULL} }; diff --git a/client/emv/cmdemv.h b/client/emv/cmdemv.h index b4397fd15..0b0419b07 100644 --- a/client/emv/cmdemv.h +++ b/client/emv/cmdemv.h @@ -34,5 +34,6 @@ extern int CmdEMVPPSE(const char *cmd); extern int CmdEMVExec(const char *cmd); extern int CmdEMVGetrng(const char *Cmd); extern int CmdEMVList(const char *Cmd); +extern int CmdEMVRoca(const char *Cmd); #endif diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 0c3bb7626..b67e7ac76 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -519,7 +519,7 @@ int MSCComputeCryptoChecksum(EMVCommandChannel channel, bool LeaveFieldON, uint8 } // Authentication -static struct emv_pk *get_ca_pk(struct tlvdb *db) { +struct emv_pk *get_ca_pk(struct tlvdb *db) { const struct tlv *df_tlv = tlvdb_get(db, 0x84, NULL); const struct tlv *caidx_tlv = tlvdb_get(db, 0x8f, NULL); @@ -900,7 +900,7 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) { PrintAndLog("WARNING: Issuer certificate not found. Exit."); return 2; } - PrintAndLog("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx", + PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx", issuer_pk->rid[0], issuer_pk->rid[1], issuer_pk->rid[2], @@ -923,10 +923,10 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) { if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLog("WARNING: ICC certificate not found. Exit."); + PrintAndLogEx(WARNING, "WARNING: ICC certificate not found. Exit."); return 2; } - printf("ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", + PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", icc_pk->rid[0], icc_pk->rid[1], icc_pk->rid[2], diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index 1117c7f78..829107126 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -102,6 +102,7 @@ extern int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_ extern int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root); +extern struct emv_pk *get_ca_pk(struct tlvdb *db); #endif From ed6806810749a93b23758b5a330eed8b205e7032 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 26 Dec 2018 12:50:11 +0100 Subject: [PATCH 014/320] chg: 'emv roca' -now compiles --- client/emv/cmdemv.c | 56 +++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 14616e0f0..1029d5a7e 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -306,7 +306,7 @@ int CmdEMVReadRecord(const char *cmd) { arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), - arg_strx1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -510,8 +510,11 @@ int CmdEMVInternalAuthenticate(const char *cmd) { int datalen = 0; CLIParserInit("emv intauth", - "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.", - "Usage:\n\temv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n" + "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n" + "Needs a EMV applet to be selected and GPO to be executed.", + + "Usage:\n" + "\temv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n" "\temv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n" "\temv intauth -pmt 9F 37 04 -> load params from file, make DDOL data from DDOL, Internal Authenticate with DDOL, show result in TLV"); @@ -680,7 +683,8 @@ int CmdEMVExec(const char *cmd) { CLIParserInit("emv exec", "Executes EMV contactless transaction", - "Usage:\n\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n" + "Usage:\n" + "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n" "\temv exec -satc -> select card, execute CDA transaction, show APDU and TLV\n"); void* argtable[] = { @@ -921,7 +925,7 @@ int CmdEMVExec(const char *cmd) { // transaction check // qVSDC - if (TrType == TT_QVSDCMCHIP|| TrType == TT_CDA){ + if (TrType == TT_QVSDCMCHIP || TrType == TT_CDA){ // 9F26: Application Cryptogram const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL); if (AC) { @@ -938,7 +942,7 @@ int CmdEMVExec(const char *cmd) { // print AC data PrintAndLogEx(NORMAL, "ATC: %s", sprint_hex(ATC->value, ATC->len)); PrintAndLogEx(NORMAL, "AC: %s", sprint_hex(AC->value, AC->len)); - if (IAD){ + if (IAD) { PrintAndLogEx(NORMAL, "IAD: %s", sprint_hex(IAD->value, IAD->len)); if (IAD->len >= IAD->value[0] + 1) { @@ -978,17 +982,18 @@ int CmdEMVExec(const char *cmd) { // ICC Dynamic Number struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf); tlvdb_add(tlvRoot, ICCDynN); - if (decodeTLV){ + if (decodeTLV) { PrintAndLogEx(NORMAL, "\n* * ICC Dynamic Number:"); TLVPrintFromTLV(ICCDynN); } PrintAndLogEx(NORMAL, "* * Calc CDOL1"); struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag - if (!cdol_data_tlv){ + if (!cdol_data_tlv) { PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV."); dreturn(6); } + PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); PrintAndLogEx(NORMAL, "* * AC1"); @@ -1010,6 +1015,7 @@ int CmdEMVExec(const char *cmd) { if (res) { PrintAndLogEx(NORMAL, "CDA error (%d)", res); } + free(ac_tlv); free(cdol_data_tlv); @@ -1073,7 +1079,7 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "Use default UDOL."); struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag - if (!udol_data_tlv){ + if (!udol_data_tlv) { PrintAndLogEx(WARNING, "Error: can't create UDOL TLV."); dreturn(8); } @@ -1448,25 +1454,6 @@ int CmdEMVScan(const char *cmd) { return 0; } -int usage_emv_getrnd(void){ - PrintAndLogEx(NORMAL, "retrieve the UN number from a terminal"); - PrintAndLogEx(NORMAL, "Usage: emv getrnd [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " emv getrnd"); - return 0; -} - -//retrieve the UN number from a terminal -int CmdEMVGetrng(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') return usage_emv_getrnd(); - - PrintAndLogEx(INFO, "Not implemented yet"); - return 0; -} int CmdEMVList(const char *Cmd) { return CmdTraceList("7816"); @@ -1480,7 +1467,8 @@ int CmdEMVRoca(const char *cmd) { CLIParserInit("emv roca", "Tries to extract public keys and run the ROCA test against them.\n", - "Usage:\n\temv roca -w -> select CONTACT card and run test\n\temv roca -> select CONTACTLESS card and run test\n"); + "Usage:\n" + "\temv roca -w -> select CONTACT card and run test\n\temv roca -> select CONTACTLESS card and run test\n"); void* argtable[] = { arg_param_begin, @@ -1497,9 +1485,12 @@ int CmdEMVRoca(const char *cmd) { const char *alr = "Root terminal TLV tree"; struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr); - - - int res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot); + // select card + uint8_t buf[APDU_RES_LEN] = {0}; + size_t len = 0; + uint16_t sw = 0; + uint8_t psenum = (channel == ECC_CONTACT) ? 1: 2; + int res = EMVSelectPSE(channel, true, true, psenum, buf, sizeof(buf), &len, &sw); // getting certificates if (tlvdb_get(tlvRoot, 0x90, NULL)) { @@ -1558,7 +1549,6 @@ out: return 0; } - static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"exec", CmdEMVExec, 0, "Executes EMV contactless transaction."}, From c6089d7fdb8a58e9cea445f9b9e783f4086f4ab6 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 26 Dec 2018 17:54:29 +0100 Subject: [PATCH 015/320] chg: more definitions --- client/emv/emv_tags.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 47cc9e79d..81cee89f3 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -237,6 +237,7 @@ static const struct emv_tag emv_tags[] = { { 0x9f17, "Personal Identification Number (PIN) Try Counter" }, { 0x9f1a, "Terminal Country Code" }, { 0x9f1f, "Track 1 Discretionary Data", EMV_TAG_STRING }, + { 0x9f20, "Track 2 Discretionary Data", EMV_TAG_STRING }, { 0x9f21, "Transaction Time" }, { 0x9f26, "Application Cryptogram" }, { 0x9f27, "Cryptogram Information Data", EMV_TAG_CID }, From 92fadc2a9f442ac31433f47bf7fd2e657aa8cbe6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 27 Dec 2018 19:45:53 +0100 Subject: [PATCH 016/320] ADD: 'amiitool' - Added @socram8888 's great tool for manipulating amiibo tags. The idea is to build it in the pm3 client. It compiles as is, but the hookup in client is not done. *WORK IN PROGRESS* --- client/amiitool/LICENSE | 21 ++++ client/amiitool/amiibo.c | 180 +++++++++++++++++++++++++++++++++ client/amiitool/amiibo.h | 32 ++++++ client/amiitool/amiitool.c | 175 ++++++++++++++++++++++++++++++++ client/amiitool/drbg.c | 78 ++++++++++++++ client/amiitool/drbg.h | 33 ++++++ client/amiitool/key_retail.bin | Bin 0 -> 160 bytes client/amiitool/keygen.c | 53 ++++++++++ client/amiitool/keygen.h | 34 +++++++ client/obj/amiitool/.dummy | 0 10 files changed, 606 insertions(+) create mode 100644 client/amiitool/LICENSE create mode 100644 client/amiitool/amiibo.c create mode 100644 client/amiitool/amiibo.h create mode 100644 client/amiitool/amiitool.c create mode 100644 client/amiitool/drbg.c create mode 100644 client/amiitool/drbg.h create mode 100644 client/amiitool/key_retail.bin create mode 100644 client/amiitool/keygen.c create mode 100644 client/amiitool/keygen.h create mode 100644 client/obj/amiitool/.dummy diff --git a/client/amiitool/LICENSE b/client/amiitool/LICENSE new file mode 100644 index 000000000..35627b40f --- /dev/null +++ b/client/amiitool/LICENSE @@ -0,0 +1,21 @@ +(c) 2015-2017 Marcos Del Sol Vives +(c) 2016 javiMaD +(c) 2016 Michael Armbruster + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/client/amiitool/amiibo.c b/client/amiitool/amiibo.c new file mode 100644 index 000000000..6391ae830 --- /dev/null +++ b/client/amiitool/amiibo.c @@ -0,0 +1,180 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * (c) 2016 javiMaD + * + * SPDX-License-Identifier: MIT + */ + +#include "amiibo.h" +#include "mbedtls/md.h" +#include "mbedtls/aes.h" + +#define HMAC_POS_DATA 0x008 +#define HMAC_POS_TAG 0x1B4 + +void nfc3d_amiibo_calc_seed(const uint8_t * dump, uint8_t * key) { + memcpy(key + 0x00, dump + 0x029, 0x02); + memset(key + 0x02, 0x00, 0x0E); + memcpy(key + 0x10, dump + 0x1D4, 0x08); + memcpy(key + 0x18, dump + 0x1D4, 0x08); + memcpy(key + 0x20, dump + 0x1E8, 0x20); +} + +void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys * masterKeys, const uint8_t * dump, nfc3d_keygen_derivedkeys * derivedKeys) { + uint8_t seed[NFC3D_KEYGEN_SEED_SIZE]; + + nfc3d_amiibo_calc_seed(dump, seed); + nfc3d_keygen(masterKeys, seed, derivedKeys); +} + +void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys * keys, const uint8_t * in, uint8_t * out) { + mbedtls_aes_context aes; + size_t nc_off = 0; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; + + mbedtls_aes_setkey_enc( &aes, keys->aesKey, 128 ); + memset(nonce_counter, 0, sizeof(nonce_counter)); + memset(stream_block, 0, sizeof(stream_block)); + memcpy(nonce_counter, keys->aesIV, sizeof(nonce_counter)); + mbedtls_aes_crypt_ctr( &aes, 0x188, &nc_off, nonce_counter, stream_block, in + 0x02C, out + 0x02C ); + + memcpy(out + 0x000, in + 0x000, 0x008); + // Data signature NOT copied + memcpy(out + 0x028, in + 0x028, 0x004); + // Tag signature NOT copied + memcpy(out + 0x1D4, in + 0x1D4, 0x034); +} + +void nfc3d_amiibo_tag_to_internal(const uint8_t * tag, uint8_t * intl) { + memcpy(intl + 0x000, tag + 0x008, 0x008); + memcpy(intl + 0x008, tag + 0x080, 0x020); + memcpy(intl + 0x028, tag + 0x010, 0x024); + memcpy(intl + 0x04C, tag + 0x0A0, 0x168); + memcpy(intl + 0x1B4, tag + 0x034, 0x020); + memcpy(intl + 0x1D4, tag + 0x000, 0x008); + memcpy(intl + 0x1DC, tag + 0x054, 0x02C); +} + +void nfc3d_amiibo_internal_to_tag(const uint8_t * intl, uint8_t * tag) { + memcpy(tag + 0x008, intl + 0x000, 0x008); + memcpy(tag + 0x080, intl + 0x008, 0x020); + memcpy(tag + 0x010, intl + 0x028, 0x024); + memcpy(tag + 0x0A0, intl + 0x04C, 0x168); + memcpy(tag + 0x034, intl + 0x1B4, 0x020); + memcpy(tag + 0x000, intl + 0x1D4, 0x008); + memcpy(tag + 0x054, intl + 0x1DC, 0x02C); +} + +bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * tag, uint8_t * plain) { + uint8_t internal[NFC3D_AMIIBO_SIZE]; + nfc3d_keygen_derivedkeys dataKeys; + nfc3d_keygen_derivedkeys tagKeys; + + // Convert format + nfc3d_amiibo_tag_to_internal(tag, internal); + + // Generate keys + nfc3d_amiibo_keygen(&amiiboKeys->data, internal, &dataKeys); + nfc3d_amiibo_keygen(&amiiboKeys->tag, internal, &tagKeys); + + // Decrypt + nfc3d_amiibo_cipher(&dataKeys, internal, plain); + + // Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC! + mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey), + plain + 0x1D4, 0x34, plain + HMAC_POS_TAG ); + + // Regenerate data HMAC + mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), dataKeys.hmacKey, sizeof(dataKeys.hmacKey), + plain + 0x029, 0x1DF, plain + HMAC_POS_DATA ); + + return + memcmp(plain + HMAC_POS_DATA, internal + HMAC_POS_DATA, 32) == 0 && + memcmp(plain + HMAC_POS_TAG, internal + HMAC_POS_TAG, 32) == 0; +} + +void nfc3d_amiibo_pack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * plain, uint8_t * tag) { + uint8_t cipher[NFC3D_AMIIBO_SIZE]; + nfc3d_keygen_derivedkeys tagKeys; + nfc3d_keygen_derivedkeys dataKeys; + + // Generate keys + nfc3d_amiibo_keygen(&amiiboKeys->tag, plain, &tagKeys); + nfc3d_amiibo_keygen(&amiiboKeys->data, plain, &dataKeys); + + // Generate tag HMAC + mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey), + plain + 0x1D4, 0x34, cipher + HMAC_POS_TAG ); + + // Init mbedtls HMAC context + mbedtls_md_context_t ctx; + mbedtls_md_init( &ctx ); + mbedtls_md_setup( &ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1 ); + + // Generate data HMAC + mbedtls_md_hmac_starts( &ctx, dataKeys.hmacKey, sizeof(dataKeys.hmacKey) ); + mbedtls_md_hmac_update( &ctx, plain + 0x029, 0x18B ); // Data + mbedtls_md_hmac_update( &ctx, cipher + HMAC_POS_TAG, 0x20 ); // Tag HMAC + mbedtls_md_hmac_update( &ctx, plain + 0x1D4, 0x34 ); // Here be dragons + + mbedtls_md_hmac_finish( &ctx, cipher + HMAC_POS_DATA ); + + // HMAC cleanup + mbedtls_md_free( &ctx ); + + // Encrypt + nfc3d_amiibo_cipher(&dataKeys, plain, cipher); + + // Convert back to hardware + nfc3d_amiibo_internal_to_tag(cipher, tag); +} + +bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path) { + FILE * f = fopen(path, "rb"); + if (!f) { + return false; + } + + if (!fread(amiiboKeys, sizeof(*amiiboKeys), 1, f)) { + fclose(f); + return false; + } + fclose(f); + + if ( + (amiiboKeys->data.magicBytesSize > 16) || + (amiiboKeys->tag.magicBytesSize > 16) + ) { + return false; + } + + return true; +} + +void nfc3d_amiibo_copy_app_data(const uint8_t * src, uint8_t * dst) { + + + //uint16_t *ami_nb_wr = (uint16_t*)(dst + 0x29); + //uint16_t *cfg_nb_wr = (uint16_t*)(dst + 0xB4); + + /* increment write counters */ + //*ami_nb_wr = htobe16(be16toh(*ami_nb_wr) + 1); + //*cfg_nb_wr = htobe16(be16toh(*cfg_nb_wr) + 1); + + uint16_t ami_nb_wr = ((uint16_t)bytes_to_num(dst + 0x29, 2)) + 1; + uint16_t cfg_nb_wr = ((uint16_t)bytes_to_num(dst + 0xB4, 2)) + 1; + + num_to_bytes(ami_nb_wr, 2, dst + 0x29); + num_to_bytes(cfg_nb_wr, 2, dst + 0xB4); + + /* copy flags */ + dst[0x2C] = src[0x2C]; + /* copy programID */ + memcpy(dst + 0xAC, src + 0xAC, 8); + /* copy AppID */ + memcpy(dst + 0xB6, src + 0xB6, 4); + /* copy AppData */ + memcpy(dst + 0xDC, src + 0xDC, 216); +} + diff --git a/client/amiitool/amiibo.h b/client/amiitool/amiibo.h new file mode 100644 index 000000000..3c7dccc70 --- /dev/null +++ b/client/amiitool/amiibo.h @@ -0,0 +1,32 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * (c) 2016 javiMaD + * + * SPDX-License-Identifier: MIT + */ + +#ifndef HAVE_NFC3D_AMIIBO_H +#define HAVE_NFC3D_AMIIBO_H + +#include +#include +#include +#include +#include "keygen.h" +#include "util.h" + +#define NFC3D_AMIIBO_SIZE 520 + +#pragma pack(1) +typedef struct { + nfc3d_keygen_masterkeys data; + nfc3d_keygen_masterkeys tag; +} nfc3d_amiibo_keys; +#pragma pack() + +bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * tag, uint8_t * plain); +void nfc3d_amiibo_pack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * plain, uint8_t * tag); +bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path); +void nfc3d_amiibo_copy_app_data(const uint8_t * src, uint8_t * dst); + +#endif diff --git a/client/amiitool/amiitool.c b/client/amiitool/amiitool.c new file mode 100644 index 000000000..40e7b05eb --- /dev/null +++ b/client/amiitool/amiitool.c @@ -0,0 +1,175 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * (c) 2016 javiMaD + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include "../loclass/fileutil.h" + +#define NTAG215_SIZE 540 + +static char * self; + +void amiitool_usage() { + fprintf(stderr, + "amiitool build %i (commit %s-%08x)\n" + "by Marcos Del Sol Vives \n" + "\n" + "Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n" + " -e encrypt and sign amiibo\n" + " -d decrypt and test amiibo\n" + " -c decrypt, copy AppData and encrypt amiibo\n" + " -k key set file. For retail amiibo, use \"retail unfixed\" key set\n" + " -i input file. If not specified, stdin will be used.\n" + " -s input save file, save from this file will replace input file ones.\n" + " -o output file. If not specified, stdout will be used.\n" + " -l decrypt files with invalid signatures.\n", + , self + ); +} + +static bool LoadAmiikey(nfc3d_amiibo_keys keys, char* keyfile) { + + if (!nfc3d_amiibo_load_keys(&keys, keyfile)) { + PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile); + return false; + } + return true; +} + +int main(int argc, char ** argv) { + self = argv[0]; + + char * infile = NULL; + char * savefile = NULL; + char * outfile = NULL; + char * keyfile = NULL; + char op = '\0'; + bool lenient = false; + + char c; + while ((c = getopt(argc, argv, "edci:s:o:k:l")) != -1) { + switch (c) { + case 'e': + case 'd': + case 'c': + op = c; + break; + case 'i': + infile = optarg; + break; + case 's': + savefile = optarg; + break; + case 'o': + outfile = optarg; + break; + case 'l': + lenient = true; + break; + default: + amiitool_usage(); + return 2; + } + } + + if (op == '\0' || keyfile == NULL) { + amiitool_usage(); + return 1; + } + + nfc3d_amiibo_keys amiiboKeys; + + + uint8_t original[NTAG215_SIZE]; + uint8_t modified[NFC3D_AMIIBO_SIZE]; + + FILE * f = stdin; + if (infile) { + f = fopen(infile, "rb"); + if (!f) { + fprintf(stderr, "Could not open input file\n"); + return 3; + } + } + size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f); + if (readPages < NFC3D_AMIIBO_SIZE / 4) { + fprintf(stderr, "Could not read from input\n"); + fclose(f); + return 3; + } + fclose(f); + + + if (op == 'e') { + nfc3d_amiibo_pack(&amiiboKeys, original, modified); + } else if (op == 'd') { + if (!nfc3d_amiibo_unpack(&amiiboKeys, original, modified)) { + fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n"); + if (!lenient) { + return 6; + } + } + } else { /* copy */ + uint8_t plain_base[NFC3D_AMIIBO_SIZE]; + uint8_t plain_save[NFC3D_AMIIBO_SIZE]; + + if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_base)) { + fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n"); + if (!lenient) { + return 6; + } + } + if (savefile) { + f = fopen(savefile, "rb"); + if (!f) { + fprintf(stderr, "Could not open save file\n"); + return 3; + } + } + size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f); + if (readPages < NFC3D_AMIIBO_SIZE / 4) { + fprintf(stderr, "Could not read from save\n"); + fclose(f); + return 3; + } + fclose(f); + + if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_save)) { + fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n"); + if (!lenient) { + return 6; + } + } + + nfc3d_amiibo_copy_app_data(plain_save, plain_base); + nfc3d_amiibo_pack(&amiiboKeys, plain_base, modified); + } + + f = stdout; + if (outfile) { + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "Could not open output file\n"); + return 4; + } + } + if (fwrite(modified, NFC3D_AMIIBO_SIZE, 1, f) != 1) { + fprintf(stderr, "Could not write to output\n"); + fclose(f); + return 4; + } + if (readPages > NFC3D_AMIIBO_SIZE / 4) { + if (fwrite(original + NFC3D_AMIIBO_SIZE, readPages * 4 - NFC3D_AMIIBO_SIZE, 1, f) != 1) { + fprintf(stderr, "Could not write to output:\n"); + fclose(f); + return 4; + } + } + fclose(f); + return 0; +} diff --git a/client/amiitool/drbg.c b/client/amiitool/drbg.c new file mode 100644 index 000000000..d56366077 --- /dev/null +++ b/client/amiitool/drbg.c @@ -0,0 +1,78 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * (c) 2016 javiMaD + * + * SPDX-License-Identifier: MIT + */ + +#include "drbg.h" +#include +#include +#include + +void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize) { + assert(ctx != NULL); + assert(hmacKey != NULL); + assert(seed != NULL); + assert(seedSize <= NFC3D_DRBG_MAX_SEED_SIZE); + + // Initialize primitives + ctx->used = false; + ctx->iteration = 0; + ctx->bufferSize = sizeof(ctx->iteration) + seedSize; + + // The 16-bit counter is prepended to the seed when hashing, so we'll leave 2 bytes at the start + memcpy(ctx->buffer + sizeof(uint16_t), seed, seedSize); + + // Initialize underlying HMAC context + mbedtls_md_init(&ctx->hmacCtx); + mbedtls_md_setup(&ctx->hmacCtx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); + mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize); +} + +void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output) { + assert(ctx != NULL); + assert(output != NULL); + + if (ctx->used) { + // If used at least once, reinitialize the HMAC + mbedtls_md_hmac_reset(&ctx->hmacCtx); + } else { + ctx->used = true; + } + + // Store counter in big endian, and increment it + ctx->buffer[0] = ctx->iteration >> 8; + ctx->buffer[1] = ctx->iteration >> 0; + ctx->iteration++; + + // Do HMAC magic + mbedtls_md_hmac_update(&ctx->hmacCtx, ctx->buffer, ctx->bufferSize); + mbedtls_md_hmac_finish(&ctx->hmacCtx, output); +} + +void nfc3d_drbg_cleanup(nfc3d_drbg_ctx * ctx) { + assert(ctx != NULL); + mbedtls_md_free(&ctx->hmacCtx); +} + +void nfc3d_drbg_generate_bytes(const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize, uint8_t * output, size_t outputSize) { + uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE]; + + nfc3d_drbg_ctx rngCtx; + nfc3d_drbg_init(&rngCtx, hmacKey, hmacKeySize, seed, seedSize); + + while (outputSize > 0) { + if (outputSize < NFC3D_DRBG_OUTPUT_SIZE) { + nfc3d_drbg_step(&rngCtx, temp); + memcpy(output, temp, outputSize); + break; + } + + nfc3d_drbg_step(&rngCtx, output); + output += NFC3D_DRBG_OUTPUT_SIZE; + outputSize -= NFC3D_DRBG_OUTPUT_SIZE; + } + + nfc3d_drbg_cleanup(&rngCtx); +} diff --git a/client/amiitool/drbg.h b/client/amiitool/drbg.h new file mode 100644 index 000000000..0e93abfc0 --- /dev/null +++ b/client/amiitool/drbg.h @@ -0,0 +1,33 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * (c) 2016 javiMaD + * + * SPDX-License-Identifier: MIT + */ + +#ifndef HAVE_NFC3D_DRBG_H +#define HAVE_NFC3D_DRBG_H + +#include +#include +#include "mbedtls/md.h" + +#define NFC3D_DRBG_MAX_SEED_SIZE 480 /* Hardcoded max size in 3DS NFC module */ +#define NFC3D_DRBG_OUTPUT_SIZE 32 /* Every iteration generates 32 bytes */ + +typedef struct { + mbedtls_md_context_t hmacCtx; + bool used; + uint16_t iteration; + + uint8_t buffer[sizeof(uint16_t) + NFC3D_DRBG_MAX_SEED_SIZE]; + size_t bufferSize; +} nfc3d_drbg_ctx; + +void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize); +void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output); +void nfc3d_drbg_cleanup(nfc3d_drbg_ctx * ctx); +void nfc3d_drbg_generate_bytes(const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize, uint8_t * output, size_t outputSize); + +#endif + diff --git a/client/amiitool/key_retail.bin b/client/amiitool/key_retail.bin new file mode 100644 index 0000000000000000000000000000000000000000..9ecc9e35a39e5c28c46891bb1438bca2beac5462 GIT binary patch literal 160 zcmb0Y^EQtzS{kmgQ#NJW;zO*Zd1;vysVNGXd1?8@3=Dj?z317xs`p#g{h#f>b20-1 zi>LUVvMtjbuKlpIoW{TI%6m)wRhvXKRw@1tdFsmQo>pI~t5Lj&LHys37}nAW-nlvX l$=N{Tic^z|QcD;Z1pb~_P&Q@9JRkSVwJ*-alpG{v9ssi +#include +#include + +void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, uint8_t * output, size_t * outputSize) { + assert(baseKeys != NULL); + assert(baseSeed != NULL); + assert(output != NULL); + assert(outputSize != NULL); + + uint8_t * start = output; + + // 1: Copy whole type string + output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString)); + + // 2: Append (16 - magicBytesSize) from the input seed + size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize; + memcpy(output, baseSeed, leadingSeedBytes); + output += leadingSeedBytes; + + // 3: Append all bytes from magicBytes + memcpy(output, baseKeys->magicBytes, baseKeys->magicBytesSize); + output += baseKeys->magicBytesSize; + + // 4: Append bytes 0x10-0x1F from input seed + memcpy(output, baseSeed + 0x10, 16); + output += 16; + + // 5: Xor last bytes 0x20-0x3F of input seed with AES XOR pad and append them + unsigned int i; + for (i = 0; i < 32; i++) { + output[i] = baseSeed[i + 32] ^ baseKeys->xorPad[i]; + } + output += 32; + + *outputSize = output - start; +} + +void nfc3d_keygen(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, nfc3d_keygen_derivedkeys * derivedKeys) { + uint8_t preparedSeed[NFC3D_DRBG_MAX_SEED_SIZE]; + size_t preparedSeedSize; + + nfc3d_keygen_prepare_seed(baseKeys, baseSeed, preparedSeed, &preparedSeedSize); + nfc3d_drbg_generate_bytes(baseKeys->hmacKey, sizeof(baseKeys->hmacKey), preparedSeed, preparedSeedSize, (uint8_t *) derivedKeys, sizeof(*derivedKeys)); +} diff --git a/client/amiitool/keygen.h b/client/amiitool/keygen.h new file mode 100644 index 000000000..35595e3ef --- /dev/null +++ b/client/amiitool/keygen.h @@ -0,0 +1,34 @@ +/* + * (c) 2015-2017 Marcos Del Sol Vives + * + * SPDX-License-Identifier: MIT + */ + +#ifndef HAVE_NFC3D_KEYGEN_H +#define HAVE_NFC3D_KEYGEN_H + +#include +#include + +#define NFC3D_KEYGEN_SEED_SIZE 64 + +#pragma pack(1) +typedef struct { + uint8_t hmacKey[16]; + char typeString[14]; + uint8_t rfu; + uint8_t magicBytesSize; + uint8_t magicBytes[16]; + uint8_t xorPad[32]; +} nfc3d_keygen_masterkeys; + +typedef struct { + const uint8_t aesKey[16]; + const uint8_t aesIV[16]; + const uint8_t hmacKey[16]; +} nfc3d_keygen_derivedkeys; +#pragma pack() + +void nfc3d_keygen(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, nfc3d_keygen_derivedkeys * derivedKeys); + +#endif diff --git a/client/obj/amiitool/.dummy b/client/obj/amiitool/.dummy new file mode 100644 index 000000000..e69de29bb From 88d42a1af5d244387a51508520627740a3a4f6e6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 13:46:52 +0200 Subject: [PATCH 017/320] make --- client/Makefile | 1 + client/emv/emv_roca.c | 117 ++++++++++++++++++++++++++++++++++++++++++ client/emv/emv_roca.h | 41 +++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 client/emv/emv_roca.c create mode 100644 client/emv/emv_roca.h diff --git a/client/Makefile b/client/Makefile index 766163c09..4f7168fa0 100644 --- a/client/Makefile +++ b/client/Makefile @@ -155,6 +155,7 @@ CMDSRCS = crapto1/crapto1.c \ emv/test/dda_test.c\ emv/test/cda_test.c\ emv/cmdemv.c \ + emv/emv_roca.c \ mifare4.c \ cmdanalyse.c \ cmdhf.c \ diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c new file mode 100644 index 000000000..0dfaa1339 --- /dev/null +++ b/client/emv/emv_roca.c @@ -0,0 +1,117 @@ +/* roca.c - ROCA (CVE-2017-15361) fingerprint checker. + * Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) + * Copyright (C) 2017 COMODO CA Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "emv_roca.h" + +static uint8_t g_primes[ROCA_PRINTS_LENGTH] = { + 11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 +}; + +mbedtls_mpi* g_prints[ROCA_PRINTS_LENGTH]; + +void rocacheck_init(void) { + + for (uint8_t i = 0; i < ROCA_PRINTS_LENGTH; i++) + mbedtls_mpi_init(g_prints[i]); + + mbedtls_mpi_read_string(g_prints[0], 10, "1026"); + mbedtls_mpi_read_string(g_prints[1], 10, "5658"); + mbedtls_mpi_read_string(g_prints[2], 10, "107286"); + mbedtls_mpi_read_string(g_prints[3], 10, "199410"); + mbedtls_mpi_read_string(g_prints[4], 10, "67109890"); + mbedtls_mpi_read_string(g_prints[5], 10, "5310023542746834"); + mbedtls_mpi_read_string(g_prints[6], 10, "1455791217086302986"); + mbedtls_mpi_read_string(g_prints[7], 10, "20052041432995567486"); + mbedtls_mpi_read_string(g_prints[8], 10, "6041388139249378920330"); + mbedtls_mpi_read_string(g_prints[9], 10, "207530445072488465666"); + mbedtls_mpi_read_string(g_prints[10], 10, "79228162521181866724264247298"); + mbedtls_mpi_read_string(g_prints[11], 10, "1760368345969468176824550810518"); + mbedtls_mpi_read_string(g_prints[12], 10, "50079290986288516948354744811034"); + mbedtls_mpi_read_string(g_prints[13], 10, "473022961816146413042658758988474"); + mbedtls_mpi_read_string(g_prints[14], 10, "144390480366845522447407333004847678774"); + mbedtls_mpi_read_string(g_prints[15], 10, "1800793591454480341970779146165214289059119882"); + mbedtls_mpi_read_string(g_prints[16], 10, "126304807362733370595828809000324029340048915994"); +} + +void rocacheck_cleanup(void) { + for (uint8_t i = 0; i < ROCA_PRINTS_LENGTH; i++) + mbedtls_mpi_free(g_prints[i]); +} + +int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ) { + + for (int i = 0; i < mbedtls_mpi_bitlen(a); i++) { + + if (mbedtls_mpi_get_bit(a, i) && mbedtls_mpi_get_bit(b, i)) + return 0; + } + return 1; +} + + +bool emv_rocacheck(char *modulus) { + + mbedtls_mpi *t_modulus = NULL; + mbedtls_mpi_init(t_modulus); + + bool ret = true; + + rocacheck_init(); + + // + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(t_modulus, 10, modulus) ); + + + for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { + + mbedtls_mpi* t_temp = NULL; + mbedtls_mpi* t_prime = NULL; + mbedtls_mpi* g_one = NULL; + + mbedtls_mpi_init(g_one); + mbedtls_mpi_init(t_temp); + mbedtls_mpi_init(t_prime); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(g_one, 10, "1") ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(t_prime, t_prime, g_primes[i]) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(t_temp, t_modulus, t_prime) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(g_one, t_temp) ); + + if (bitand_is_zero(t_temp, g_prints[i])) { + PrintAndLogEx(FAILED, "No fingerprint found\n"); + ret = false; + goto cleanup; + } + + mbedtls_mpi_free(g_one); + mbedtls_mpi_free(t_temp); + mbedtls_mpi_free(t_prime); + } + + PrintAndLogEx(SUCCESS, "Fingerprint found!\n"); + +cleanup: + if (t_modulus) + mbedtls_mpi_free(t_modulus); + + rocacheck_cleanup(); + return ret; +} diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h new file mode 100644 index 000000000..e2ba0ac51 --- /dev/null +++ b/client/emv/emv_roca.h @@ -0,0 +1,41 @@ + +// ROCA (CVE-2017-15361) fingerprint checker. +// Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) +// Copyright (C) 2017 COMODO CA Limited +// modified 2018 iceman (dropped openssl bignum, now use mbedtls lib) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//----------------------------------------------------------------------------- +// EMV roca commands +//----------------------------------------------------------------------------- + +#ifndef EMV_ROCA_H__ +#define EMV_ROCA_H__ + +#include +#include +#include "mbedtls/bignum.h" +#include "util.h" + +#define ROCA_PRINTS_LENGTH 17 + +void rocacheck_init(void); +void rocacheck_cleanup(void); +int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ); + +extern bool emv_rocacheck( char *modulus ); + +#endif + From b1145ba57771237d5a7b8223f2f5746863b5f418 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 14:50:23 +0200 Subject: [PATCH 018/320] mpi_get_uint --- client/emv/emv_roca.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 0dfaa1339..2843cb2c1 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -64,6 +64,15 @@ int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ) { } +mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { + + if (X->n == 1) { + return X->p[0]; + } + + return 0; +} + bool emv_rocacheck(char *modulus) { mbedtls_mpi *t_modulus = NULL; @@ -93,7 +102,7 @@ bool emv_rocacheck(char *modulus) { MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(t_temp, t_modulus, t_prime) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(g_one, t_temp) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(g_one, mpi_get_uint(t_temp)) ); if (bitand_is_zero(t_temp, g_prints[i])) { PrintAndLogEx(FAILED, "No fingerprint found\n"); From 9804526dca774c21f617b3b13d431826e3c7a685 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 14:52:24 +0200 Subject: [PATCH 019/320] small fix for unsigned int --- client/emv/emv_roca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 2843cb2c1..48845c99f 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -66,7 +66,7 @@ int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ) { mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { - if (X->n == 1) { + if (X->n == 1 && X->s > 0) { return X->p[0]; } From ab41b4a991fe4e75c1ebd6c3056ac1667f8d0e2a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 16:40:53 +0200 Subject: [PATCH 020/320] emv_rocacheck --- client/emv/cmdemv.h | 1 + client/emv/emv_roca.c | 5 ++--- client/emv/emv_roca.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/emv/cmdemv.h b/client/emv/cmdemv.h index 0b0419b07..c91f75606 100644 --- a/client/emv/cmdemv.h +++ b/client/emv/cmdemv.h @@ -25,6 +25,7 @@ #include "cmdmain.h" #include "emvcore.h" #include "apduinfo.h" +#include "emv_roca.h" int CmdEMV(const char *Cmd); diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 48845c99f..fe68b83ce 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -73,7 +73,7 @@ mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { return 0; } -bool emv_rocacheck(char *modulus) { +bool emv_rocacheck(const unsigned char *buf, size_t buflen) { mbedtls_mpi *t_modulus = NULL; mbedtls_mpi_init(t_modulus); @@ -82,8 +82,7 @@ bool emv_rocacheck(char *modulus) { rocacheck_init(); - // - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(t_modulus, 10, modulus) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(t_modulus, buf, buflen) ); for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h index e2ba0ac51..a42d8349e 100644 --- a/client/emv/emv_roca.h +++ b/client/emv/emv_roca.h @@ -35,7 +35,7 @@ void rocacheck_init(void); void rocacheck_cleanup(void); int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ); -extern bool emv_rocacheck( char *modulus ); +extern bool emv_rocacheck( const unsigned char *buf, size_t buflen ); #endif From 8e5133582d98e3f37cd2e94d5585678f10d456e1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 16:43:15 +0200 Subject: [PATCH 021/320] `emv roca` select app --- client/emv/cmdemv.c | 81 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 1029d5a7e..d3ec26c53 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1464,6 +1464,12 @@ int CmdEMVTest(const char *cmd) { } int CmdEMVRoca(const char *cmd) { + uint8_t AID[APDU_AID_LEN] = {0}; + size_t AIDlen = 0; + uint8_t buf[APDU_RES_LEN] = {0}; + size_t len = 0; + uint16_t sw = 0; + int res; CLIParserInit("emv roca", "Tries to extract public keys and run the ROCA test against them.\n", @@ -1481,16 +1487,71 @@ int CmdEMVRoca(const char *cmd) { if (arg_get_lit(1)) channel = ECC_CONTACT; + // select card + uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; + + // init applets list tree + const char *al = "Applets list"; + struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); + + // EMV PPSE + PrintAndLogEx(NORMAL, "--> PPSE."); + res = EMVSelectPSE(channel, true, true, psenum, buf, sizeof(buf), &len, &sw); + + if (!res && sw == 0x9000){ + struct tlvdb *fci = tlvdb_parse_multi(buf, len); + tlvdb_free(fci); + } + + SetAPDULogging(false); + res = EMVSearchPSE(channel, false, true, false, tlvSelect); + + // check PPSE and select application id + if (!res) { + TLVPrintAIDlistFromSelectTLV(tlvSelect); + } else { + // EMV SEARCH with AID list + PrintAndLogEx(NORMAL, "--> AID search."); + if (EMVSearch(channel, false, true, false, tlvSelect)) { + PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); + tlvdb_free(tlvSelect); + DropField(); + return 3; + } + + // check search and select application id + TLVPrintAIDlistFromSelectTLV(tlvSelect); + } + + // EMV SELECT application + SetAPDULogging(false); + EMVSelectApplication(tlvSelect, AID, &AIDlen); + + tlvdb_free(tlvSelect); + + if (!AIDlen) { + PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); + DropField(); + return 4; + } + // Init TLV tree const char *alr = "Root terminal TLV tree"; struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr); - // select card - uint8_t buf[APDU_RES_LEN] = {0}; - size_t len = 0; - uint16_t sw = 0; - uint8_t psenum = (channel == ECC_CONTACT) ? 1: 2; - int res = EMVSelectPSE(channel, true, true, psenum, buf, sizeof(buf), &len, &sw); + // EMV SELECT applet + PrintAndLogEx(NORMAL, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID, AIDlen)); + res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot); + + if (res) { + PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); + tlvdb_free(tlvRoot); + DropField(); + return 5; + } + + + // getting certificates if (tlvdb_get(tlvRoot, 0x90, NULL)) { @@ -1530,8 +1591,16 @@ int CmdEMVRoca(const char *cmd) { sprint_hex(icc_pk->serial, 3) ); + // icc_pk->exp, icc_pk->elen // icc_pk->modulus, icc_pk->mlen + if (icc_pk->elen > 0 && icc_pk->mlen > 0) { + if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen)) { + PrintAndLogEx(INFO, "ICC pk is vulnerable by roca."); + } else { + PrintAndLogEx(INFO, "ICC pk is OK("); + } + } PKISetStrictExecution(true); From b0c1828c1defffeca88b150abfed924fc5125929 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 16:58:11 +0200 Subject: [PATCH 022/320] load params --- client/emv/cmdemv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index d3ec26c53..c058c9913 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1550,6 +1550,8 @@ int CmdEMVRoca(const char *cmd) { return 5; } + PrintAndLog("\n* Init transaction parameters."); + InitTransactionParameters(tlvRoot, true, TT_QVSDCMCHIP, false); From 67b7edeb44756c332cd90f0caf185d2a942b7190 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 17:07:58 +0200 Subject: [PATCH 023/320] extract keys works --- client/emv/cmdemv.c | 75 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index c058c9913..7922bc616 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1553,8 +1553,74 @@ int CmdEMVRoca(const char *cmd) { PrintAndLog("\n* Init transaction parameters."); InitTransactionParameters(tlvRoot, true, TT_QVSDCMCHIP, false); - + PrintAndLogEx(NORMAL, "-->Calc PDOL."); + struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83); + if (!pdol_data_tlv){ + PrintAndLogEx(ERR, "Can't create PDOL TLV."); + tlvdb_free(tlvRoot); + DropField(); + return 6; + } + size_t pdol_data_tlv_data_len; + unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len); + if (!pdol_data_tlv_data) { + PrintAndLogEx(ERR, "Can't create PDOL data."); + tlvdb_free(tlvRoot); + DropField(); + return 6; + } + PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); + + PrintAndLogEx(INFO, "-->GPO."); + res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); + + free(pdol_data_tlv_data); + free(pdol_data_tlv); + + if (res) { + PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); + tlvdb_free(tlvRoot); + DropField(); + return 7; + } + ProcessGPOResponseFormat1(tlvRoot, buf, len, false); + + PrintAndLogEx(INFO, "-->Read records from AFL."); + const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL); + + while(AFL && AFL->len) { + if (AFL->len % 4) { + PrintAndLogEx(ERR, "Wrong AFL length: %d", AFL->len); + break; + } + + for (int i = 0; i < AFL->len / 4; i++) { + uint8_t SFI = AFL->value[i * 4 + 0] >> 3; + uint8_t SFIstart = AFL->value[i * 4 + 1]; + uint8_t SFIend = AFL->value[i * 4 + 2]; + uint8_t SFIoffline = AFL->value[i * 4 + 3]; + + PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); + if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) { + PrintAndLogEx(ERR, "SFI ERROR! Skipped..."); + continue; + } + + for(int n = SFIstart; n <= SFIend; n++) { + PrintAndLogEx(INFO, "---->SFI[%02x] %d", SFI, n); + + res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot); + if (res) { + PrintAndLogEx(ERR, "SFI[%02x]. APDU error %4x", SFI, sw); + continue; + } + } + } + + break; + } + // getting certificates if (tlvdb_get(tlvRoot, 0x90, NULL)) { PrintAndLogEx(INFO, "-->Recovering certificates."); @@ -1593,9 +1659,10 @@ int CmdEMVRoca(const char *cmd) { sprint_hex(icc_pk->serial, 3) ); - -// icc_pk->exp, icc_pk->elen -// icc_pk->modulus, icc_pk->mlen + PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen)); + + // icc_pk->exp, icc_pk->elen + // icc_pk->modulus, icc_pk->mlen if (icc_pk->elen > 0 && icc_pk->mlen > 0) { if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen)) { PrintAndLogEx(INFO, "ICC pk is vulnerable by roca."); From 625b696291d734c14d420bcd55e88ffe1c40e34c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 17:25:11 +0200 Subject: [PATCH 024/320] roca works --- client/emv/emv_roca.c | 85 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index fe68b83ce..2aaa10875 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -22,35 +22,35 @@ static uint8_t g_primes[ROCA_PRINTS_LENGTH] = { 11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 }; -mbedtls_mpi* g_prints[ROCA_PRINTS_LENGTH]; +mbedtls_mpi g_prints[ROCA_PRINTS_LENGTH]; void rocacheck_init(void) { - for (uint8_t i = 0; i < ROCA_PRINTS_LENGTH; i++) - mbedtls_mpi_init(g_prints[i]); + for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) + mbedtls_mpi_init(&g_prints[i]); - mbedtls_mpi_read_string(g_prints[0], 10, "1026"); - mbedtls_mpi_read_string(g_prints[1], 10, "5658"); - mbedtls_mpi_read_string(g_prints[2], 10, "107286"); - mbedtls_mpi_read_string(g_prints[3], 10, "199410"); - mbedtls_mpi_read_string(g_prints[4], 10, "67109890"); - mbedtls_mpi_read_string(g_prints[5], 10, "5310023542746834"); - mbedtls_mpi_read_string(g_prints[6], 10, "1455791217086302986"); - mbedtls_mpi_read_string(g_prints[7], 10, "20052041432995567486"); - mbedtls_mpi_read_string(g_prints[8], 10, "6041388139249378920330"); - mbedtls_mpi_read_string(g_prints[9], 10, "207530445072488465666"); - mbedtls_mpi_read_string(g_prints[10], 10, "79228162521181866724264247298"); - mbedtls_mpi_read_string(g_prints[11], 10, "1760368345969468176824550810518"); - mbedtls_mpi_read_string(g_prints[12], 10, "50079290986288516948354744811034"); - mbedtls_mpi_read_string(g_prints[13], 10, "473022961816146413042658758988474"); - mbedtls_mpi_read_string(g_prints[14], 10, "144390480366845522447407333004847678774"); - mbedtls_mpi_read_string(g_prints[15], 10, "1800793591454480341970779146165214289059119882"); - mbedtls_mpi_read_string(g_prints[16], 10, "126304807362733370595828809000324029340048915994"); + mbedtls_mpi_read_string(&g_prints[0], 10, "1026"); + mbedtls_mpi_read_string(&g_prints[1], 10, "5658"); + mbedtls_mpi_read_string(&g_prints[2], 10, "107286"); + mbedtls_mpi_read_string(&g_prints[3], 10, "199410"); + mbedtls_mpi_read_string(&g_prints[4], 10, "67109890"); + mbedtls_mpi_read_string(&g_prints[5], 10, "5310023542746834"); + mbedtls_mpi_read_string(&g_prints[6], 10, "1455791217086302986"); + mbedtls_mpi_read_string(&g_prints[7], 10, "20052041432995567486"); + mbedtls_mpi_read_string(&g_prints[8], 10, "6041388139249378920330"); + mbedtls_mpi_read_string(&g_prints[9], 10, "207530445072488465666"); + mbedtls_mpi_read_string(&g_prints[10], 10, "79228162521181866724264247298"); + mbedtls_mpi_read_string(&g_prints[11], 10, "1760368345969468176824550810518"); + mbedtls_mpi_read_string(&g_prints[12], 10, "50079290986288516948354744811034"); + mbedtls_mpi_read_string(&g_prints[13], 10, "473022961816146413042658758988474"); + mbedtls_mpi_read_string(&g_prints[14], 10, "144390480366845522447407333004847678774"); + mbedtls_mpi_read_string(&g_prints[15], 10, "1800793591454480341970779146165214289059119882"); + mbedtls_mpi_read_string(&g_prints[16], 10, "126304807362733370595828809000324029340048915994"); } void rocacheck_cleanup(void) { - for (uint8_t i = 0; i < ROCA_PRINTS_LENGTH; i++) - mbedtls_mpi_free(g_prints[i]); + for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) + mbedtls_mpi_free(&g_prints[i]); } int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ) { @@ -75,50 +75,49 @@ mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { bool emv_rocacheck(const unsigned char *buf, size_t buflen) { - mbedtls_mpi *t_modulus = NULL; - mbedtls_mpi_init(t_modulus); + mbedtls_mpi t_modulus; + mbedtls_mpi_init(&t_modulus); bool ret = true; rocacheck_init(); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(t_modulus, buf, buflen) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus, buf, buflen) ); + mbedtls_mpi_init(&g_one); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { +printf("--p:%d\n", i); - mbedtls_mpi* t_temp = NULL; - mbedtls_mpi* t_prime = NULL; - mbedtls_mpi* g_one = NULL; + mbedtls_mpi t_temp; + mbedtls_mpi t_prime; + mbedtls_mpi g_one; - mbedtls_mpi_init(g_one); - mbedtls_mpi_init(t_temp); - mbedtls_mpi_init(t_prime); + mbedtls_mpi_init(&t_temp); + mbedtls_mpi_init(&t_prime); + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&t_prime, &t_prime, g_primes[i]) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(g_one, 10, "1") ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(t_prime, t_prime, g_primes[i]) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&t_temp, &t_modulus, &t_prime) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(t_temp, t_modulus, t_prime) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp)) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(g_one, mpi_get_uint(t_temp)) ); - - if (bitand_is_zero(t_temp, g_prints[i])) { + if (bitand_is_zero(&t_temp, &g_prints[i])) { PrintAndLogEx(FAILED, "No fingerprint found\n"); ret = false; goto cleanup; } - mbedtls_mpi_free(g_one); - mbedtls_mpi_free(t_temp); - mbedtls_mpi_free(t_prime); + mbedtls_mpi_free(&g_one); + mbedtls_mpi_free(&t_temp); + mbedtls_mpi_free(&t_prime); } PrintAndLogEx(SUCCESS, "Fingerprint found!\n"); cleanup: - if (t_modulus) - mbedtls_mpi_free(t_modulus); + mbedtls_mpi_free(&t_modulus); rocacheck_cleanup(); return ret; From 6afda099db761b9793a126f3616e33ebad7db315 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 17:46:57 +0200 Subject: [PATCH 025/320] added test/ not works --- client/emv/cmdemv.c | 6 ++++++ client/emv/emv_roca.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 7922bc616..a42002c60 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1661,6 +1661,12 @@ int CmdEMVRoca(const char *cmd) { PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen)); + + uint8_t key[] = "944e13208a280c37efc31c3114485e590192adbb8e11c87cad60cdef0037ce99278330d3f471a2538fa667802ed2a3c44a8b7dea826e888d0aa341fd664f7fa7"; + if (emv_rocacheck(key, 64)) + PrintAndLogEx(INFO, "DEMO ICC pk is vulnerable by roca."); + + // icc_pk->exp, icc_pk->elen // icc_pk->modulus, icc_pk->mlen if (icc_pk->elen > 0 && icc_pk->mlen > 0) { diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 2aaa10875..42bcce6db 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -84,6 +84,7 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus, buf, buflen) ); + mbedtls_mpi g_one; mbedtls_mpi_init(&g_one); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); @@ -92,7 +93,6 @@ printf("--p:%d\n", i); mbedtls_mpi t_temp; mbedtls_mpi t_prime; - mbedtls_mpi g_one; mbedtls_mpi_init(&t_temp); mbedtls_mpi_init(&t_prime); From 18225c7c7f0b466b7d77f500975c3bbb2867926b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 17:48:52 +0200 Subject: [PATCH 026/320] some fix --- client/emv/cmdemv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a42002c60..c1ae8b1f3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1662,7 +1662,10 @@ int CmdEMVRoca(const char *cmd) { PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen)); - uint8_t key[] = "944e13208a280c37efc31c3114485e590192adbb8e11c87cad60cdef0037ce99278330d3f471a2538fa667802ed2a3c44a8b7dea826e888d0aa341fd664f7fa7"; + uint8_t key[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\ + "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\ + "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ + "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; if (emv_rocacheck(key, 64)) PrintAndLogEx(INFO, "DEMO ICC pk is vulnerable by roca."); From 404f23ddbd6ae3df7f8065999250d29f9af442be Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 17:50:51 +0200 Subject: [PATCH 027/320] small fix --- client/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index c1ae8b1f3..16e5c4765 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1674,7 +1674,7 @@ int CmdEMVRoca(const char *cmd) { // icc_pk->modulus, icc_pk->mlen if (icc_pk->elen > 0 && icc_pk->mlen > 0) { if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen)) { - PrintAndLogEx(INFO, "ICC pk is vulnerable by roca."); + PrintAndLogEx(INFO, "ICC pk is a subject to ROCA vulnerability, insecure.."); } else { PrintAndLogEx(INFO, "ICC pk is OK("); } From 5eafc491ec91ccdf7b98ff33f2daa3cd6352b330 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 18:00:37 +0200 Subject: [PATCH 028/320] small add --- client/emv/cmdemv.c | 1 + client/emv/emv_roca.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 16e5c4765..adb47b136 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1666,6 +1666,7 @@ int CmdEMVRoca(const char *cmd) { "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\ "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; + PrintAndLogEx(INFO, "DEMO ICC pk modulus: %s", sprint_hex_inrow(key, 64)); if (emv_rocacheck(key, 64)) PrintAndLogEx(INFO, "DEMO ICC pk is vulnerable by roca."); diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 42bcce6db..88a7b21ad 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -69,7 +69,7 @@ mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { if (X->n == 1 && X->s > 0) { return X->p[0]; } - + printf("ZERRRRO!!!\n"); return 0; } @@ -89,7 +89,7 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { -printf("--p:%d\n", i); +printf("--roca:%d\n", i); mbedtls_mpi t_temp; mbedtls_mpi t_prime; From f1cd108b1a432132c922fe62b6c9966f26fdec43 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 18:09:20 +0200 Subject: [PATCH 029/320] move g_one to cycle --- client/emv/emv_roca.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 88a7b21ad..53fd91c15 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -84,18 +84,19 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus, buf, buflen) ); - mbedtls_mpi g_one; - mbedtls_mpi_init(&g_one); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { printf("--roca:%d\n", i); mbedtls_mpi t_temp; mbedtls_mpi t_prime; + mbedtls_mpi g_one; mbedtls_mpi_init(&t_temp); mbedtls_mpi_init(&t_prime); + mbedtls_mpi_init(&g_one); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&t_prime, &t_prime, g_primes[i]) ); From 05814fbe75bd9e77dbf589c3fdf0c8c287e6a0dc Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 19:06:51 +0200 Subject: [PATCH 030/320] added mpi print --- client/emv/emv_roca.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 53fd91c15..ad39d1043 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -73,6 +73,15 @@ mbedtls_mpi_uint mpi_get_uint(const mbedtls_mpi *X) { return 0; } +void print_mpi(const char *msg, int radix, const mbedtls_mpi *X) { + + char Xchar[400] = {0}; + size_t len = 0; + + mbedtls_mpi_write_string(X, radix, Xchar, sizeof(Xchar), &len); + printf("%s[%d] %s\n", msg, len, Xchar); +} + bool emv_rocacheck(const unsigned char *buf, size_t buflen) { mbedtls_mpi t_modulus; @@ -83,6 +92,7 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { rocacheck_init(); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus, buf, buflen) ); + print_mpi("--t_modulus:", 16, &t_modulus); for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { From 44343d806fa74594ac3f4f4c930599a7be787511 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 19:25:19 +0200 Subject: [PATCH 031/320] add some debug --- client/emv/emv_roca.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index ad39d1043..9297ce452 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -109,11 +109,15 @@ printf("--roca:%d\n", i); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&t_prime, &t_prime, g_primes[i]) ); + print_mpi("--t_prime:", 10, &t_prime); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&t_temp, &t_modulus, &t_prime) ); + print_mpi("--t_temp:", 10, &t_temp); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp)) ); + print_mpi("--g_one:", 10, &g_one); + print_mpi("--g_prints:", 10, &g_prints[i]); if (bitand_is_zero(&t_temp, &g_prints[i])) { PrintAndLogEx(FAILED, "No fingerprint found\n"); ret = false; From e315328625d9cc632dc8223d0f46e398730cb9bc Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 20:06:18 +0200 Subject: [PATCH 032/320] works --- client/emv/emv_roca.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 9297ce452..977584f73 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -92,11 +92,8 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { rocacheck_init(); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus, buf, buflen) ); - print_mpi("--t_modulus:", 16, &t_modulus); - for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) { -printf("--roca:%d\n", i); mbedtls_mpi t_temp; mbedtls_mpi t_prime; @@ -109,17 +106,13 @@ printf("--roca:%d\n", i); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one, 10, "1") ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&t_prime, &t_prime, g_primes[i]) ); - print_mpi("--t_prime:", 10, &t_prime); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&t_temp, &t_modulus, &t_prime) ); - print_mpi("--t_temp:", 10, &t_temp); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp)) ); - print_mpi("--g_one:", 10, &g_one); - print_mpi("--g_prints:", 10, &g_prints[i]); - if (bitand_is_zero(&t_temp, &g_prints[i])) { - PrintAndLogEx(FAILED, "No fingerprint found\n"); + if (bitand_is_zero(&g_one, &g_prints[i])) { + PrintAndLogEx(FAILED, "No fingerprint found.\n"); ret = false; goto cleanup; } From 7401d51ebf256b723e10e3db875feafaefe01c5c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 20:33:24 +0200 Subject: [PATCH 033/320] roca works --- client/emv/cmdemv.c | 15 ++--------- client/emv/emv_roca.c | 58 +++++++++++++++++++++++++++++++++++++++---- client/emv/emv_roca.h | 7 ++---- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index adb47b136..4cbbe2e0b 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1661,26 +1661,15 @@ int CmdEMVRoca(const char *cmd) { PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen)); - - uint8_t key[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\ - "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\ - "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ - "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; - PrintAndLogEx(INFO, "DEMO ICC pk modulus: %s", sprint_hex_inrow(key, 64)); - if (emv_rocacheck(key, 64)) - PrintAndLogEx(INFO, "DEMO ICC pk is vulnerable by roca."); - - // icc_pk->exp, icc_pk->elen // icc_pk->modulus, icc_pk->mlen if (icc_pk->elen > 0 && icc_pk->mlen > 0) { - if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen)) { + if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen, true)) { PrintAndLogEx(INFO, "ICC pk is a subject to ROCA vulnerability, insecure.."); } else { PrintAndLogEx(INFO, "ICC pk is OK("); } - } - + } PKISetStrictExecution(true); } diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 977584f73..5081ed446 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -82,12 +82,12 @@ void print_mpi(const char *msg, int radix, const mbedtls_mpi *X) { printf("%s[%d] %s\n", msg, len, Xchar); } -bool emv_rocacheck(const unsigned char *buf, size_t buflen) { +bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) { mbedtls_mpi t_modulus; mbedtls_mpi_init(&t_modulus); - bool ret = true; + bool ret = false; rocacheck_init(); @@ -112,8 +112,8 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp)) ); if (bitand_is_zero(&g_one, &g_prints[i])) { - PrintAndLogEx(FAILED, "No fingerprint found.\n"); - ret = false; + if (verbose) + PrintAndLogEx(FAILED, "No fingerprint found.\n"); goto cleanup; } @@ -122,7 +122,9 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) { mbedtls_mpi_free(&t_prime); } - PrintAndLogEx(SUCCESS, "Fingerprint found!\n"); + ret = true; + if (verbose) + PrintAndLogEx(SUCCESS, "Fingerprint found!\n"); cleanup: mbedtls_mpi_free(&t_modulus); @@ -130,3 +132,49 @@ cleanup: rocacheck_cleanup(); return ret; } + +int roca_self_test( int verbose ) { + int ret = 0; + + if( verbose != 0 ) + printf( "\nROCA check vulnerability tests\n" ); + + // positive + uint8_t keyp[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\ + "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\ + "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ + "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; + + if( verbose != 0 ) + printf( " ROCA positive test: " ); + + if (emv_rocacheck(keyp, 64, false)) { + if( verbose != 0 ) + printf( "passed\n" ); + } else { + ret = 1; + if( verbose != 0 ) + printf( "failed\n" ); + } + + // negative + uint8_t keyn[] = "\x84\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\ + "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\ + "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ + "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; + + if( verbose != 0 ) + printf( " ROCA negative test: " ); + + if (emv_rocacheck(keyn, 64, false)) { + ret = 1; + if( verbose != 0 ) + printf( "failed\n" ); + } else { + if( verbose != 0 ) + printf( "passed\n" ); + } + + + return ret; +} diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h index a42d8349e..a9559ef79 100644 --- a/client/emv/emv_roca.h +++ b/client/emv/emv_roca.h @@ -31,11 +31,8 @@ #define ROCA_PRINTS_LENGTH 17 -void rocacheck_init(void); -void rocacheck_cleanup(void); -int bitand_is_zero( mbedtls_mpi* a, mbedtls_mpi* b ); - -extern bool emv_rocacheck( const unsigned char *buf, size_t buflen ); +extern bool emv_rocacheck( const unsigned char *buf, size_t buflen, bool verbose ); +extern int roca_self_test( int verbose ); #endif From 376ead028a07aa4ff4b4818259d762fb7f6438c9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 20:33:38 +0200 Subject: [PATCH 034/320] added tests --- client/emv/test/cryptotest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index 1d5891fe0..b0212a70b 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -31,6 +31,7 @@ #include "dda_test.h" #include "cda_test.h" #include "crypto/libpcrypto.h" +#include "emv/emv_roca.h" int ExecuteCryptoTests(bool verbose) { int res; @@ -90,6 +91,9 @@ int ExecuteCryptoTests(bool verbose) { res = exec_crypto_test(verbose); if (res) TestFail = true; + res = roca_self_test(verbose); + if (res) TestFail = true; + PrintAndLog("\n--------------------------"); if (TestFail) PrintAndLog("Test(s) [ERROR]."); From 392687499591d30437af625d203d8fa90e0dff20 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 28 Dec 2018 20:48:45 +0200 Subject: [PATCH 035/320] fix pse channels --- client/emv/cmdemv.c | 18 +++++++----------- client/emv/emvcore.c | 4 ++-- client/emv/emvcore.h | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 4cbbe2e0b..a443f6aad 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -722,6 +722,7 @@ int CmdEMVExec(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(11)) channel = ECC_CONTACT; + uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; CLIParserFree(); SetAPDULogging(showAPDU); @@ -736,7 +737,7 @@ int CmdEMVExec(const char *cmd) { // PPSE PrintAndLogEx(NORMAL, "\n* PPSE."); SetAPDULogging(showAPDU); - res = EMVSearchPSE(channel, activateField, true, decodeTLV, tlvSelect); + res = EMVSearchPSE(channel, activateField, true, psenum, decodeTLV, tlvSelect); // check PPSE and select application id if (!res) { @@ -1170,6 +1171,7 @@ int CmdEMVScan(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(11)) channel = ECC_CONTACT; + uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; uint8_t relfname[250] ={0}; char *crelfname = (char *)relfname; int relfnamelen = 0; @@ -1248,7 +1250,7 @@ int CmdEMVScan(const char *cmd) { tlvdb_free(fci); } - res = EMVSearchPSE(channel, false, true, decodeTLV, tlvSelect); + res = EMVSearchPSE(channel, false, true, psenum, decodeTLV, tlvSelect); // check PPSE and select application id if (!res) { @@ -1490,21 +1492,15 @@ int CmdEMVRoca(const char *cmd) { // select card uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; + SetAPDULogging(false); + // init applets list tree const char *al = "Applets list"; struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); // EMV PPSE PrintAndLogEx(NORMAL, "--> PPSE."); - res = EMVSelectPSE(channel, true, true, psenum, buf, sizeof(buf), &len, &sw); - - if (!res && sw == 0x9000){ - struct tlvdb *fci = tlvdb_parse_multi(buf, len); - tlvdb_free(fci); - } - - SetAPDULogging(false); - res = EMVSearchPSE(channel, false, true, false, tlvSelect); + res = EMVSearchPSE(channel, false, true, psenum, false, tlvSelect); // check PPSE and select application id if (!res) { diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index b67e7ac76..b582792ac 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -332,14 +332,14 @@ int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO return res; } -int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, bool decodeTLV, struct tlvdb *tlv) { +int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; uint16_t sw = 0; int res; // select PPSE - res = EMVSelectPSE(channel, ActivateField, true, 2, data, sizeof(data), &datalen, &sw); + res = EMVSelectPSE(channel, ActivateField, true, PSENum, data, sizeof(data), &datalen, &sw); if (!res){ struct tlvdb *t = NULL; diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index 829107126..7d53e83bb 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -79,7 +79,7 @@ extern void SetAPDULogging(bool logging); extern int EMVExchange(EMVCommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv); // search application -extern int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, bool decodeTLV, struct tlvdb *tlv); +extern int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv); extern int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, bool decodeTLV, struct tlvdb *tlv); extern int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); extern int EMVSelect(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv); From 690a8e604aee614ab6e6ee1b159af9d587f41d38 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 29 Dec 2018 00:31:10 +0200 Subject: [PATCH 036/320] updated licanse according to changes https://gist.github.com/robstradling/f525d423c79690b72e650e2ad38a161d#file-roca-c-L138 --- client/emv/emv_roca.c | 9 +++++++-- client/emv/emv_roca.h | 38 +++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index 5081ed446..a6738ae2f 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -1,10 +1,12 @@ /* roca.c - ROCA (CVE-2017-15361) fingerprint checker. * Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) - * Copyright (C) 2017 COMODO CA Limited + * Copyright (C) 2017-2018 Sectigo Limited + * modified 2018 iceman (dropped openssl bignum, now use mbedtls lib) + * modified 2018 merlok * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or + * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -15,6 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +//----------------------------------------------------------------------------- +// EMV roca commands +//----------------------------------------------------------------------------- #include "emv_roca.h" diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h index a9559ef79..26d37d146 100644 --- a/client/emv/emv_roca.h +++ b/client/emv/emv_roca.h @@ -1,22 +1,22 @@ - -// ROCA (CVE-2017-15361) fingerprint checker. -// Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) -// Copyright (C) 2017 COMODO CA Limited -// modified 2018 iceman (dropped openssl bignum, now use mbedtls lib) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// +/* roca.c - ROCA (CVE-2017-15361) fingerprint checker. + * Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) + * Copyright (C) 2017-2018 Sectigo Limited + * modified 2018 iceman (dropped openssl bignum, now use mbedtls lib) + * modified 2018 merlok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ //----------------------------------------------------------------------------- // EMV roca commands //----------------------------------------------------------------------------- From 9e07a5c65a9443b9a5db2c403f19f5b864f3c057 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 31 Dec 2018 15:46:32 +0100 Subject: [PATCH 037/320] CHG: updated to RevEng v1.6.0 --- client/cmdcrc.c | 17 +- client/reveng/model.c | 2 +- client/reveng/preset.c | 933 +++++++++++++++++++++-------------------- client/reveng/reveng.h | 31 +- client/scripting.c | 2 +- 5 files changed, 523 insertions(+), 462 deletions(-) diff --git a/client/cmdcrc.c b/client/cmdcrc.c index 25653dbab..a34c7d351 100644 --- a/client/cmdcrc.c +++ b/client/cmdcrc.c @@ -39,8 +39,7 @@ int split(char *str, char *arr[MAX_ARGS]){ return wordCnt; } -int CmdCrc(const char *Cmd) -{ +int CmdCrc(const char *Cmd) { char name[] = {"reveng "}; char Cmd2[100 + 7]; memcpy(Cmd2, name, 7); @@ -198,6 +197,11 @@ int GetModels(char *Models[], int *count, uint8_t *width){ pfree(qptr); } } + if(uflags & C_NOBFS && ~rflags & R_HAVEP) { + PrintAndLogEx(WARNING, "no models found"); + return 0; + } + if (!(model.flags & P_REFIN) != !(model.flags & P_REFOUT)){ PrintAndLogEx(WARNING, "cannot search for crossed-endian models"); return 0; @@ -259,8 +263,9 @@ int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *res SETBMP(); //set model - if (!(c = mbynam(&model, inModel))) { - PrintAndLogEx(WARNING, "error: preset model '%s' not found. Use reveng -D to list presets.", inModel); + c = mbynam(&model, inModel); + if (!c) { + PrintAndLogEx(WARNING, "error: preset model '%s' not found. Use reveng -D to list presets. [%d]", inModel, c); return 0; } if (c < 0){ @@ -396,7 +401,7 @@ char *SwapEndianStr(const char *inStr, const size_t len, const uint8_t blockSize // takes hex string in and searches for a matching result (hex string must include checksum) int CmdrevengSearch(const char *Cmd){ -#define NMODELS 103 +#define NMODELS 105 char inHexStr[100] = {0x00}; int dataLen = param_getstr(Cmd, 0, inHexStr, sizeof(inHexStr)); @@ -432,7 +437,7 @@ int CmdrevengSearch(const char *Cmd){ char *outHex = calloc(dataLen-crcChars+1, sizeof(char)); memcpy(outHex, inHexStr, dataLen-crcChars); - // PrintAndLogEx(DEBUG, "DEBUG: dataLen: %d, crcChars: %d, Model: %s, CRC: %s, width: %d, outHex: %s",dataLen, crcChars, Models[i], inCRC, width[i], outHex); + PrintAndLogEx(DEBUG, "DEBUG: dataLen: %d, crcChars: %d, Model: %s, CRC: %s, width: %d, outHex: %s",dataLen, crcChars, Models[i], inCRC, width[i], outHex); ans = RunModel(Models[i], outHex, false, 0, result); if (ans) { // test for match diff --git a/client/reveng/model.c b/client/reveng/model.c index 60870d80a..f99b1ee02 100644 --- a/client/reveng/model.c +++ b/client/reveng/model.c @@ -121,7 +121,7 @@ char * mtostr(const model_t *model) { if ((string = malloc(size))) { sprintf(strbuf, "\"%s\"", model->name); sprintf(string, - "width=%lu" + "width=%lu " "poly=0x%s " "init=0x%s " "refin=%s " diff --git a/client/reveng/preset.c b/client/reveng/preset.c index 9e7b721ff..6dbedaed9 100644 --- a/client/reveng/preset.c +++ b/client/reveng/preset.c @@ -1,5 +1,5 @@ /* preset.c - * Greg Cook, 26/Jul/2018 + * Greg Cook, 21/Nov/2018 */ /* CRC RevEng: arbitrary-precision CRC calculator and algorithm finder @@ -22,7 +22,9 @@ * along with CRC RevEng. If not, see . */ -/* 2018-07-26: added CRC-24/OS-9 +/* 2018-11-21: added CRC-8/NRSC-5, CRC-16/NRSC-5 + * 2018-11-21: renamed algorithms, new aliases, added classes + * 2018-07-26: added CRC-24/OS-9 * 2018-07-26: struct malias.name declared const char *const * 2017-06-19: added CRC-8/BLUETOOTH, CRC-17/CAN-FD, CRC-21/CAN-FD * 2017-02-18: added 8 new GSM algorithms @@ -269,200 +271,203 @@ static const bmp_t b32[] = { BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ - BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 11 -- 31,04c11db7 */ - BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 12 -- 15, 059e */ - BMP_C(0x0c000000) << (BMP_BIT - 32), /* 13 -- 6, 03 */ - BMP_C(0x0c200000) << (BMP_BIT - 32), /* 14 -- 11, 061 */ - BMP_C(0x0c780000) << (BMP_BIT - 32), /* 15 -- 14, 031e */ - BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 16 -- 16, 0fb3 */ - BMP_C(0x10210000) << (BMP_BIT - 32), /* 17 -- 16, 1021 */ - BMP_C(0x12000000) << (BMP_BIT - 32), /* 18 -- 7, 09 */ - BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 19 -- 30,04c34abf */ - BMP_C(0x144e6300) << (BMP_BIT - 32), /* 20 -- 24, 144e63 */ - BMP_C(0x15000000) << (BMP_BIT - 32), /* 21 -- 8, 15 */ - BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 22 -- 32,1697d06a */ - BMP_C(0x17800000) << (BMP_BIT - 32), /* 23 -- 12, 178 */ - BMP_C(0x18000000) << (BMP_BIT - 32), /* 24 -- 6, 06 */ - BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 25 -- 31,0ce9e46c */ - BMP_C(0x1c000000) << (BMP_BIT - 32), /* 26 -- 6, 07 */ - BMP_C(0x1d000000) << (BMP_BIT - 32), /* 27 -- 8, 1d */ - BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 28 -- 16, 1d0f */ - BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 29 -- 16, 1dcf */ - BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 30 -- 32,1edc6f41 */ - BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 31 -- 24, 1f23b8 */ - BMP_C(0x20000000) << (BMP_BIT - 32), /* 32 -- 4, 2 */ - BMP_C(0x200fa500) << (BMP_BIT - 32), /* 33 -- 24, 200fa5 */ - BMP_C(0x20140000) << (BMP_BIT - 32), /* 34 -- 14, 0805 */ - BMP_C(0x20b40000) << (BMP_BIT - 32), /* 35 -- 14, 082d */ - BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 36 -- 16, 20fe */ - BMP_C(0x21890000) << (BMP_BIT - 32), /* 37 -- 16, 2189 */ - BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 38 -- 24, 21cf02 */ - BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 39 -- 24, 23ef52 */ - BMP_C(0x25000000) << (BMP_BIT - 32), /* 40 -- 8, 25 */ - BMP_C(0x26000000) << (BMP_BIT - 32), /* 41 -- 8, 26 */ - BMP_C(0x26b10000) << (BMP_BIT - 32), /* 42 -- 16, 26b1 */ - BMP_C(0x27818000) << (BMP_BIT - 32), /* 43 -- 17, 04f03 */ - BMP_C(0x27d00000) << (BMP_BIT - 32), /* 44 -- 13, 04fa */ - BMP_C(0x28000000) << (BMP_BIT - 32), /* 45 -- 5, 05 */ - BMP_C(0x29b10000) << (BMP_BIT - 32), /* 46 -- 16, 29b1 */ - BMP_C(0x2f000000) << (BMP_BIT - 32), /* 47 -- 8, 2f */ - BMP_C(0x30000000) << (BMP_BIT - 32), /* 48 -- 4, 3/ 5, 6 */ - BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 49 -- 32,3010bf7f */ - BMP_C(0x31000000) << (BMP_BIT - 32), /* 50 -- 8, 31 */ - BMP_C(0x31800000) << (BMP_BIT - 32), /* 51 -- 10, 0c6 */ - BMP_C(0x31c30000) << (BMP_BIT - 32), /* 52 -- 16, 31c3 */ - BMP_C(0x328b6300) << (BMP_BIT - 32), /* 53 -- 24, 328b63 */ - BMP_C(0x34000000) << (BMP_BIT - 32), /* 54 -- 6, 0d */ - BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 55 -- 32,340bc6d9 */ - BMP_C(0x37000000) << (BMP_BIT - 32), /* 56 -- 8, 37 */ - BMP_C(0x38000000) << (BMP_BIT - 32), /* 57 -- 5, 07 */ - BMP_C(0x39000000) << (BMP_BIT - 32), /* 58 -- 8, 39 */ - BMP_C(0x3d650000) << (BMP_BIT - 32), /* 59 -- 16, 3d65 */ - BMP_C(0x3e000000) << (BMP_BIT - 32), /* 60 -- 8, 3e */ - BMP_C(0x40000000) << (BMP_BIT - 32), /* 61 -- 3, 2 */ - BMP_C(0x42000000) << (BMP_BIT - 32), /* 62 -- 8, 42 */ - BMP_C(0x44c20000) << (BMP_BIT - 32), /* 63 -- 16, 44c2 */ - BMP_C(0x45270551) << (BMP_BIT - 32), /* 64 -- 32,45270551 */ - BMP_C(0x48000000) << (BMP_BIT - 32), /* 65 -- 5, 09 */ - BMP_C(0x49000000) << (BMP_BIT - 32), /* 66 -- 8, 49 */ - BMP_C(0x4a800000) << (BMP_BIT - 32), /* 67 -- 10, 12a */ - BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 68 -- 15, 2566 */ - BMP_C(0x4b000000) << (BMP_BIT - 32), /* 69 -- 8, 4b */ - BMP_C(0x4b370000) << (BMP_BIT - 32), /* 70 -- 16, 4b37 */ - BMP_C(0x4c000000) << (BMP_BIT - 32), /* 71 -- 6, 13 */ - BMP_C(0x4c060000) << (BMP_BIT - 32), /* 72 -- 16, 4c06 */ - BMP_C(0x53000000) << (BMP_BIT - 32), /* 73 -- 8, 53 */ - BMP_C(0x55000000) << (BMP_BIT - 32), /* 74 -- 8, 55 */ - BMP_C(0x55555500) << (BMP_BIT - 32), /* 75 -- 24, 555555 */ - BMP_C(0x59350000) << (BMP_BIT - 32), /* 76 -- 16, 5935 */ - BMP_C(0x5d380000) << (BMP_BIT - 32), /* 77 -- 16, 5d38 */ - BMP_C(0x5d400000) << (BMP_BIT - 32), /* 78 -- 10, 175 */ - BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 79 -- 24, 5d6dcb */ - BMP_C(0x60000000) << (BMP_BIT - 32), /* 80 -- 3, 3 */ - BMP_C(0x60e00000) << (BMP_BIT - 32), /* 81 -- 11, 307 */ - BMP_C(0x63d00000) << (BMP_BIT - 32), /* 82 -- 16, 63d0 */ - BMP_C(0x64000000) << (BMP_BIT - 32), /* 83 -- 6, 19 */ - BMP_C(0x66400000) << (BMP_BIT - 32), /* 84 -- 10, 199 */ - BMP_C(0x66c50000) << (BMP_BIT - 32), /* 85 -- 16, 66c5 */ - BMP_C(0x6f630000) << (BMP_BIT - 32), /* 86 -- 16, 6f63 */ - BMP_C(0x6f910000) << (BMP_BIT - 32), /* 87 -- 16, 6f91 */ - BMP_C(0x70000000) << (BMP_BIT - 32), /* 88 -- 4, 7 */ - BMP_C(0x70a00000) << (BMP_BIT - 32), /* 89 -- 11, 385 */ - BMP_C(0x755b0000) << (BMP_BIT - 32), /* 90 -- 16, 755b */ - BMP_C(0x765e7680) << (BMP_BIT - 32), /* 91 -- 32,765e7680 */ - BMP_C(0x76c20800) << (BMP_BIT - 32), /* 92 -- 32, 0ed841 */ - BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 93 -- 24, 7979bd */ - BMP_C(0x7e000000) << (BMP_BIT - 32), /* 94 -- 8, 7e */ - BMP_C(0x80000000) << (BMP_BIT - 32), /* 95 -- 3, 4 */ - BMP_C(0x80006300) << (BMP_BIT - 32), /* 96 -- 24, 800063 */ - BMP_C(0x80050000) << (BMP_BIT - 32), /* 97 -- 16, 8005 */ - BMP_C(0x800d0000) << (BMP_BIT - 32), /* 98 -- 16, 800d */ - BMP_C(0x800fe300) << (BMP_BIT - 32), /* 99 -- 24, 800fe3 */ - BMP_C(0x80b40000) << (BMP_BIT - 32), /* 100 -- 14, 202d */ - BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 101 -- 30,2030b9c7 */ - BMP_C(0x80f00000) << (BMP_BIT - 32), /* 102 -- 12, 80f */ - BMP_C(0x814141ab) << (BMP_BIT - 32), /* 103 -- 32,814141ab */ - BMP_C(0x8144c800) << (BMP_BIT - 32), /* 104 -- 21, 102899 */ - BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 105 -- 24, 864cfb */ - BMP_C(0x87315576) << (BMP_BIT - 32), /* 106 -- 32,87315576 */ - BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 107 -- 16, 89ec */ - BMP_C(0x8a000000) << (BMP_BIT - 32), /* 108 -- 7, 45 */ - BMP_C(0x8b320000) << (BMP_BIT - 32), /* 109 -- 15, 4599 */ - BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 110 -- 16, 8bb7 */ - BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 111 -- 10, 233 */ - BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 112 -- 32,904cddbf */ - BMP_C(0x906e0000) << (BMP_BIT - 32), /* 113 -- 16, 906e */ - BMP_C(0x94000000) << (BMP_BIT - 32), /* 114 -- 8, 94 */ - BMP_C(0x97000000) << (BMP_BIT - 32), /* 115 -- 8, 97 */ - BMP_C(0x98000000) << (BMP_BIT - 32), /* 116 -- 6, 26 */ - BMP_C(0x9b000000) << (BMP_BIT - 32), /* 117 -- 8, 9b */ - BMP_C(0x9c000000) << (BMP_BIT - 32), /* 118 -- 6, 27 */ - BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 119 -- 31,4eaf26f1 */ - BMP_C(0x9e000000) << (BMP_BIT - 32), /* 120 -- 7, 4f */ - BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 121 -- 16, 9ecf */ - BMP_C(0xa0970000) << (BMP_BIT - 32), /* 122 -- 16, a097 */ - BMP_C(0xa1000000) << (BMP_BIT - 32), /* 123 -- 8, a1 */ - BMP_C(0xa3660000) << (BMP_BIT - 32), /* 124 -- 16, a366 */ - BMP_C(0xa6000000) << (BMP_BIT - 32), /* 125 -- 7, 53 */ - BMP_C(0xa7000000) << (BMP_BIT - 32), /* 126 -- 8, a7 */ - BMP_C(0xa8000000) << (BMP_BIT - 32), /* 127 -- 5, 15 */ - BMP_C(0xa8190000) << (BMP_BIT - 32), /* 128 -- 16, a819 */ - BMP_C(0xa833982b) << (BMP_BIT - 32), /* 129 -- 32,a833982b */ - BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 130 -- 24, abcdef */ - BMP_C(0xac000000) << (BMP_BIT - 32), /* 131 -- 8, ac */ - BMP_C(0xaee70000) << (BMP_BIT - 32), /* 132 -- 16, aee7 */ - BMP_C(0xb0000000) << (BMP_BIT - 32), /* 133 -- 4, b */ - BMP_C(0xb0010000) << (BMP_BIT - 32), /* 134 -- 16, b001 */ - BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 135 -- 16, b2aa */ - BMP_C(0xb3400000) << (BMP_BIT - 32), /* 136 -- 12, b34 */ - BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 137 -- 17, 1685b */ - BMP_C(0xb4600000) << (BMP_BIT - 32), /* 138 -- 11, 5a3 */ - BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 139 -- 16, b4c8 */ - BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 140 -- 24, b4f3e6 */ - BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 141 -- 24, b704ce */ - BMP_C(0xb798b438) << (BMP_BIT - 32), /* 142 -- 32,b798b438 */ - BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 143 -- 16, bb3d */ - BMP_C(0xbc000000) << (BMP_BIT - 32), /* 144 -- 6,2f/ 8,bc */ - BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 145 -- 32,bd0be338 */ - BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 146 -- 16, bdf4 */ - BMP_C(0xbf050000) << (BMP_BIT - 32), /* 147 -- 16, bf05 */ - BMP_C(0xc0000000) << (BMP_BIT - 32), /* 148 -- 3, 6 */ - BMP_C(0xc2000000) << (BMP_BIT - 32), /* 149 -- 7, 61 */ - BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 150 -- 24, c25a56 */ - BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 151 -- 16, c2b7 */ - BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 152 -- 14, 30ae */ - BMP_C(0xc4000000) << (BMP_BIT - 32), /* 153 -- 8, c4 */ - BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 154 -- 16, c6c6 */ - BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 155 -- 32,c704dd7b */ - BMP_C(0xc8000000) << (BMP_BIT - 32), /* 156 -- 5, 19 */ - BMP_C(0xc8670000) << (BMP_BIT - 32), /* 157 -- 16, c867 */ - BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 158 -- 32,cbf43926 */ - BMP_C(0xcde70300) << (BMP_BIT - 32), /* 159 -- 24, cde703 */ - BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 160 -- 16, ce3c */ - BMP_C(0xd0000000) << (BMP_BIT - 32), /* 161 -- 8, d0 */ - BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 162 -- 15, 6815 */ - BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 163 -- 16, d0db */ - BMP_C(0xd3100000) << (BMP_BIT - 32), /* 164 -- 12, d31 */ - BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 165 -- 30,34efa55a */ - BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 166 -- 12, d4d */ - BMP_C(0xd5000000) << (BMP_BIT - 32), /* 167 -- 8, d5 */ - BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 168 -- 16, d64e */ - BMP_C(0xda000000) << (BMP_BIT - 32), /* 169 -- 8, da */ - BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 170 -- 12, daf */ - BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 171 -- 32,debb20e3 */ - BMP_C(0xdf000000) << (BMP_BIT - 32), /* 172 -- 8, df */ - BMP_C(0xe0000000) << (BMP_BIT - 32), /* 173 -- 3, 7 */ - BMP_C(0xe3069283) << (BMP_BIT - 32), /* 174 -- 32,e3069283 */ - BMP_C(0xe3940000) << (BMP_BIT - 32), /* 175 -- 16, e394 */ - BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 176 -- 16, e5cc */ - BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 177 -- 13, 1cf5 */ - BMP_C(0xe8000000) << (BMP_BIT - 32), /* 178 -- 6, 3a */ - BMP_C(0xea000000) << (BMP_BIT - 32), /* 179 -- 7, 75 */ - BMP_C(0xea820000) << (BMP_BIT - 32), /* 180 -- 16, ea82 */ - BMP_C(0xec000000) << (BMP_BIT - 32), /* 181 -- 6, 3b */ - BMP_C(0xf0000000) << (BMP_BIT - 32), /* 182 -- 4, f */ - BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 183 -- 16, f0b8 */ - BMP_C(0xf1300000) << (BMP_BIT - 32), /* 184 -- 12, f13 */ - BMP_C(0xf4000000) << (BMP_BIT - 32), /* 185 -- 8, f4 */ - BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 186 -- 32,f4acfb13 */ - BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 187 -- 12, f5b */ - BMP_C(0xf6400000) << (BMP_BIT - 32), /* 188 -- 10, 3d9 */ - BMP_C(0xf8000000) << (BMP_BIT - 32), /* 189 -- 5, 1f */ - BMP_C(0xfc000000) << (BMP_BIT - 32), /* 190 -- 6, 3f */ - BMP_C(0xfc891918) << (BMP_BIT - 32), /* 191 -- 32,fc891918 */ - BMP_C(0xfd000000) << (BMP_BIT - 32), /* 192 -- 8, fd */ - BMP_C(0xfe000000) << (BMP_BIT - 32), /* 193 -- 7, 7f */ - BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 194 -- 24, fedcba */ - BMP_C(0xfee80000) << (BMP_BIT - 32), /* 195 -- 16, fee8 */ - BMP_C(0xff000000) << (BMP_BIT - 32), /* 196 -- 8, ff */ - BMP_C(0xffc00000) << (BMP_BIT - 32), /* 197 -- 10, 3ff */ - BMP_C(0xfff00000) << (BMP_BIT - 32), /* 198 -- 12, fff */ - BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 199 -- 14, 3fff */ - BMP_C(0xffff0000) << (BMP_BIT - 32), /* 200 -- 16, ffff */ - BMP_C(0xffffff00) << (BMP_BIT - 32), /* 201 -- 24, ffffff */ - BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 202 -- 30,3fffffff */ - BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 203 -- 31,7fffffff */ - BMP_C(0xffffffff) << (BMP_BIT - 32), /* 204 -- 32,ffffffff */ + BMP_C(0x080b0000) << (BMP_BIT - 32), /* 11 -- 16, 080b */ + BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 12 -- 31,04c11db7 */ + BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 13 -- 15, 059e */ + BMP_C(0x0c000000) << (BMP_BIT - 32), /* 14 -- 6, 03 */ + BMP_C(0x0c200000) << (BMP_BIT - 32), /* 15 -- 11, 061 */ + BMP_C(0x0c780000) << (BMP_BIT - 32), /* 16 -- 14, 031e */ + BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 17 -- 16, 0fb3 */ + BMP_C(0x10210000) << (BMP_BIT - 32), /* 18 -- 16, 1021 */ + BMP_C(0x12000000) << (BMP_BIT - 32), /* 19 -- 7, 09 */ + BMP_C(0x130d2afc) << (BMP_BIT - 32), /* 20 -- 30,04c34abf */ + BMP_C(0x144e6300) << (BMP_BIT - 32), /* 21 -- 24, 144e63 */ + BMP_C(0x15000000) << (BMP_BIT - 32), /* 22 -- 8, 15 */ + BMP_C(0x1697d06a) << (BMP_BIT - 32), /* 23 -- 32,1697d06a */ + BMP_C(0x17800000) << (BMP_BIT - 32), /* 24 -- 12, 178 */ + BMP_C(0x18000000) << (BMP_BIT - 32), /* 25 -- 6, 06 */ + BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 26 -- 31,0ce9e46c */ + BMP_C(0x1c000000) << (BMP_BIT - 32), /* 27 -- 6, 07 */ + BMP_C(0x1d000000) << (BMP_BIT - 32), /* 28 -- 8, 1d */ + BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 29 -- 16, 1d0f */ + BMP_C(0x1dcf0000) << (BMP_BIT - 32), /* 30 -- 16, 1dcf */ + BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 31 -- 32,1edc6f41 */ + BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 32 -- 24, 1f23b8 */ + BMP_C(0x20000000) << (BMP_BIT - 32), /* 33 -- 4, 2 */ + BMP_C(0x200fa500) << (BMP_BIT - 32), /* 34 -- 24, 200fa5 */ + BMP_C(0x20140000) << (BMP_BIT - 32), /* 35 -- 14, 0805 */ + BMP_C(0x20b40000) << (BMP_BIT - 32), /* 36 -- 14, 082d */ + BMP_C(0x20fe0000) << (BMP_BIT - 32), /* 37 -- 16, 20fe */ + BMP_C(0x21890000) << (BMP_BIT - 32), /* 38 -- 16, 2189 */ + BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 39 -- 24, 21cf02 */ + BMP_C(0x23ef5200) << (BMP_BIT - 32), /* 40 -- 24, 23ef52 */ + BMP_C(0x25000000) << (BMP_BIT - 32), /* 41 -- 8, 25 */ + BMP_C(0x26000000) << (BMP_BIT - 32), /* 42 -- 8, 26 */ + BMP_C(0x26b10000) << (BMP_BIT - 32), /* 43 -- 16, 26b1 */ + BMP_C(0x27818000) << (BMP_BIT - 32), /* 44 -- 17, 04f03 */ + BMP_C(0x27d00000) << (BMP_BIT - 32), /* 45 -- 13, 04fa */ + BMP_C(0x28000000) << (BMP_BIT - 32), /* 46 -- 5, 05 */ + BMP_C(0x29b10000) << (BMP_BIT - 32), /* 47 -- 16, 29b1 */ + BMP_C(0x2f000000) << (BMP_BIT - 32), /* 48 -- 8, 2f */ + BMP_C(0x30000000) << (BMP_BIT - 32), /* 49 -- 4, 3/ 5, 6 */ + BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 50 -- 32,3010bf7f */ + BMP_C(0x31000000) << (BMP_BIT - 32), /* 51 -- 8, 31 */ + BMP_C(0x31800000) << (BMP_BIT - 32), /* 52 -- 10, 0c6 */ + BMP_C(0x31c30000) << (BMP_BIT - 32), /* 53 -- 16, 31c3 */ + BMP_C(0x328b6300) << (BMP_BIT - 32), /* 54 -- 24, 328b63 */ + BMP_C(0x34000000) << (BMP_BIT - 32), /* 55 -- 6, 0d */ + BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 56 -- 32,340bc6d9 */ + BMP_C(0x37000000) << (BMP_BIT - 32), /* 57 -- 8, 37 */ + BMP_C(0x38000000) << (BMP_BIT - 32), /* 58 -- 5, 07 */ + BMP_C(0x39000000) << (BMP_BIT - 32), /* 59 -- 8, 39 */ + BMP_C(0x3d650000) << (BMP_BIT - 32), /* 60 -- 16, 3d65 */ + BMP_C(0x3e000000) << (BMP_BIT - 32), /* 61 -- 8, 3e */ + BMP_C(0x40000000) << (BMP_BIT - 32), /* 62 -- 3, 2 */ + BMP_C(0x42000000) << (BMP_BIT - 32), /* 63 -- 8, 42 */ + BMP_C(0x44c20000) << (BMP_BIT - 32), /* 64 -- 16, 44c2 */ + BMP_C(0x45270551) << (BMP_BIT - 32), /* 65 -- 32,45270551 */ + BMP_C(0x48000000) << (BMP_BIT - 32), /* 66 -- 5, 09 */ + BMP_C(0x49000000) << (BMP_BIT - 32), /* 67 -- 8, 49 */ + BMP_C(0x4a800000) << (BMP_BIT - 32), /* 68 -- 10, 12a */ + BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 69 -- 15, 2566 */ + BMP_C(0x4b000000) << (BMP_BIT - 32), /* 70 -- 8, 4b */ + BMP_C(0x4b370000) << (BMP_BIT - 32), /* 71 -- 16, 4b37 */ + BMP_C(0x4c000000) << (BMP_BIT - 32), /* 72 -- 6, 13 */ + BMP_C(0x4c060000) << (BMP_BIT - 32), /* 73 -- 16, 4c06 */ + BMP_C(0x53000000) << (BMP_BIT - 32), /* 74 -- 8, 53 */ + BMP_C(0x55000000) << (BMP_BIT - 32), /* 75 -- 8, 55 */ + BMP_C(0x55555500) << (BMP_BIT - 32), /* 76 -- 24, 555555 */ + BMP_C(0x59350000) << (BMP_BIT - 32), /* 77 -- 16, 5935 */ + BMP_C(0x5d380000) << (BMP_BIT - 32), /* 78 -- 16, 5d38 */ + BMP_C(0x5d400000) << (BMP_BIT - 32), /* 79 -- 10, 175 */ + BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 80 -- 24, 5d6dcb */ + BMP_C(0x60000000) << (BMP_BIT - 32), /* 81 -- 3, 3 */ + BMP_C(0x60e00000) << (BMP_BIT - 32), /* 82 -- 11, 307 */ + BMP_C(0x63d00000) << (BMP_BIT - 32), /* 83 -- 16, 63d0 */ + BMP_C(0x64000000) << (BMP_BIT - 32), /* 84 -- 6, 19 */ + BMP_C(0x66400000) << (BMP_BIT - 32), /* 85 -- 10, 199 */ + BMP_C(0x66c50000) << (BMP_BIT - 32), /* 86 -- 16, 66c5 */ + BMP_C(0x6f630000) << (BMP_BIT - 32), /* 87 -- 16, 6f63 */ + BMP_C(0x6f910000) << (BMP_BIT - 32), /* 88 -- 16, 6f91 */ + BMP_C(0x70000000) << (BMP_BIT - 32), /* 89 -- 4, 7 */ + BMP_C(0x70a00000) << (BMP_BIT - 32), /* 90 -- 11, 385 */ + BMP_C(0x755b0000) << (BMP_BIT - 32), /* 91 -- 16, 755b */ + BMP_C(0x765e7680) << (BMP_BIT - 32), /* 92 -- 32,765e7680 */ + BMP_C(0x76c20800) << (BMP_BIT - 32), /* 93 -- 32, 0ed841 */ + BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 94 -- 24, 7979bd */ + BMP_C(0x7e000000) << (BMP_BIT - 32), /* 95 -- 8, 7e */ + BMP_C(0x80000000) << (BMP_BIT - 32), /* 96 -- 3, 4 */ + BMP_C(0x80006300) << (BMP_BIT - 32), /* 97 -- 24, 800063 */ + BMP_C(0x80050000) << (BMP_BIT - 32), /* 98 -- 16, 8005 */ + BMP_C(0x800d0000) << (BMP_BIT - 32), /* 99 -- 16, 800d */ + BMP_C(0x800fe300) << (BMP_BIT - 32), /* 100 -- 24, 800fe3 */ + BMP_C(0x80b40000) << (BMP_BIT - 32), /* 101 -- 14, 202d */ + BMP_C(0x80c2e71c) << (BMP_BIT - 32), /* 102 -- 30,2030b9c7 */ + BMP_C(0x80f00000) << (BMP_BIT - 32), /* 103 -- 12, 80f */ + BMP_C(0x814141ab) << (BMP_BIT - 32), /* 104 -- 32,814141ab */ + BMP_C(0x8144c800) << (BMP_BIT - 32), /* 105 -- 21, 102899 */ + BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 106 -- 24, 864cfb */ + BMP_C(0x87315576) << (BMP_BIT - 32), /* 107 -- 32,87315576 */ + BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 108 -- 16, 89ec */ + BMP_C(0x8a000000) << (BMP_BIT - 32), /* 109 -- 7, 45 */ + BMP_C(0x8b320000) << (BMP_BIT - 32), /* 110 -- 15, 4599 */ + BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 111 -- 16, 8bb7 */ + BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 112 -- 10, 233 */ + BMP_C(0x904cddbf) << (BMP_BIT - 32), /* 113 -- 32,904cddbf */ + BMP_C(0x906e0000) << (BMP_BIT - 32), /* 114 -- 16, 906e */ + BMP_C(0x94000000) << (BMP_BIT - 32), /* 115 -- 8, 94 */ + BMP_C(0x97000000) << (BMP_BIT - 32), /* 116 -- 8, 97 */ + BMP_C(0x98000000) << (BMP_BIT - 32), /* 117 -- 6, 26 */ + BMP_C(0x9b000000) << (BMP_BIT - 32), /* 118 -- 8, 9b */ + BMP_C(0x9c000000) << (BMP_BIT - 32), /* 119 -- 6, 27 */ + BMP_C(0x9d5e4de2) << (BMP_BIT - 32), /* 120 -- 31,4eaf26f1 */ + BMP_C(0x9e000000) << (BMP_BIT - 32), /* 121 -- 7, 4f */ + BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 122 -- 16, 9ecf */ + BMP_C(0xa0660000) << (BMP_BIT - 32), /* 123 -- 16, a066 */ + BMP_C(0xa0970000) << (BMP_BIT - 32), /* 124 -- 16, a097 */ + BMP_C(0xa1000000) << (BMP_BIT - 32), /* 125 -- 8, a1 */ + BMP_C(0xa3660000) << (BMP_BIT - 32), /* 126 -- 16, a366 */ + BMP_C(0xa6000000) << (BMP_BIT - 32), /* 127 -- 7, 53 */ + BMP_C(0xa7000000) << (BMP_BIT - 32), /* 128 -- 8, a7 */ + BMP_C(0xa8000000) << (BMP_BIT - 32), /* 129 -- 5, 15 */ + BMP_C(0xa8190000) << (BMP_BIT - 32), /* 130 -- 16, a819 */ + BMP_C(0xa833982b) << (BMP_BIT - 32), /* 131 -- 32,a833982b */ + BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 132 -- 24, abcdef */ + BMP_C(0xac000000) << (BMP_BIT - 32), /* 133 -- 8, ac */ + BMP_C(0xaee70000) << (BMP_BIT - 32), /* 134 -- 16, aee7 */ + BMP_C(0xb0000000) << (BMP_BIT - 32), /* 135 -- 4, b */ + BMP_C(0xb0010000) << (BMP_BIT - 32), /* 136 -- 16, b001 */ + BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 137 -- 16, b2aa */ + BMP_C(0xb3400000) << (BMP_BIT - 32), /* 138 -- 12, b34 */ + BMP_C(0xb42d8000) << (BMP_BIT - 32), /* 139 -- 17, 1685b */ + BMP_C(0xb4600000) << (BMP_BIT - 32), /* 140 -- 11, 5a3 */ + BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 141 -- 16, b4c8 */ + BMP_C(0xb4f3e600) << (BMP_BIT - 32), /* 142 -- 24, b4f3e6 */ + BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 143 -- 24, b704ce */ + BMP_C(0xb798b438) << (BMP_BIT - 32), /* 144 -- 32,b798b438 */ + BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 145 -- 16, bb3d */ + BMP_C(0xbc000000) << (BMP_BIT - 32), /* 146 -- 6,2f/ 8,bc */ + BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 147 -- 32,bd0be338 */ + BMP_C(0xbdf40000) << (BMP_BIT - 32), /* 148 -- 16, bdf4 */ + BMP_C(0xbf050000) << (BMP_BIT - 32), /* 149 -- 16, bf05 */ + BMP_C(0xc0000000) << (BMP_BIT - 32), /* 150 -- 3, 6 */ + BMP_C(0xc2000000) << (BMP_BIT - 32), /* 151 -- 7, 61 */ + BMP_C(0xc25a5600) << (BMP_BIT - 32), /* 152 -- 24, c25a56 */ + BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 153 -- 16, c2b7 */ + BMP_C(0xc2b80000) << (BMP_BIT - 32), /* 154 -- 14, 30ae */ + BMP_C(0xc4000000) << (BMP_BIT - 32), /* 155 -- 8, c4 */ + BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 156 -- 16, c6c6 */ + BMP_C(0xc704dd7b) << (BMP_BIT - 32), /* 157 -- 32,c704dd7b */ + BMP_C(0xc8000000) << (BMP_BIT - 32), /* 158 -- 5, 19 */ + BMP_C(0xc8670000) << (BMP_BIT - 32), /* 159 -- 16, c867 */ + BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 160 -- 32,cbf43926 */ + BMP_C(0xcde70300) << (BMP_BIT - 32), /* 161 -- 24, cde703 */ + BMP_C(0xce3c0000) << (BMP_BIT - 32), /* 162 -- 16, ce3c */ + BMP_C(0xd0000000) << (BMP_BIT - 32), /* 163 -- 8, d0 */ + BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 164 -- 15, 6815 */ + BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 165 -- 16, d0db */ + BMP_C(0xd3100000) << (BMP_BIT - 32), /* 166 -- 12, d31 */ + BMP_C(0xd3be9568) << (BMP_BIT - 32), /* 167 -- 30,34efa55a */ + BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 168 -- 12, d4d */ + BMP_C(0xd5000000) << (BMP_BIT - 32), /* 169 -- 8, d5 */ + BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 170 -- 16, d64e */ + BMP_C(0xda000000) << (BMP_BIT - 32), /* 171 -- 8, da */ + BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 172 -- 12, daf */ + BMP_C(0xdebb20e3) << (BMP_BIT - 32), /* 173 -- 32,debb20e3 */ + BMP_C(0xdf000000) << (BMP_BIT - 32), /* 174 -- 8, df */ + BMP_C(0xe0000000) << (BMP_BIT - 32), /* 175 -- 3, 7 */ + BMP_C(0xe3069283) << (BMP_BIT - 32), /* 176 -- 32,e3069283 */ + BMP_C(0xe3940000) << (BMP_BIT - 32), /* 177 -- 16, e394 */ + BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 178 -- 16, e5cc */ + BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 179 -- 13, 1cf5 */ + BMP_C(0xe8000000) << (BMP_BIT - 32), /* 180 -- 6, 3a */ + BMP_C(0xea000000) << (BMP_BIT - 32), /* 181 -- 7, 75 */ + BMP_C(0xea820000) << (BMP_BIT - 32), /* 182 -- 16, ea82 */ + BMP_C(0xec000000) << (BMP_BIT - 32), /* 183 -- 6, 3b */ + BMP_C(0xf0000000) << (BMP_BIT - 32), /* 184 -- 4, f */ + BMP_C(0xf0b80000) << (BMP_BIT - 32), /* 185 -- 16, f0b8 */ + BMP_C(0xf1300000) << (BMP_BIT - 32), /* 186 -- 12, f13 */ + BMP_C(0xf4000000) << (BMP_BIT - 32), /* 187 -- 8, f4 */ + BMP_C(0xf4acfb13) << (BMP_BIT - 32), /* 188 -- 32,f4acfb13 */ + BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 189 -- 12, f5b */ + BMP_C(0xf6400000) << (BMP_BIT - 32), /* 190 -- 10, 3d9 */ + BMP_C(0xf7000000) << (BMP_BIT - 32), /* 191 -- 8, f7 */ + BMP_C(0xf8000000) << (BMP_BIT - 32), /* 192 -- 5, 1f */ + BMP_C(0xfc000000) << (BMP_BIT - 32), /* 193 -- 6, 3f */ + BMP_C(0xfc891918) << (BMP_BIT - 32), /* 194 -- 32,fc891918 */ + BMP_C(0xfd000000) << (BMP_BIT - 32), /* 195 -- 8, fd */ + BMP_C(0xfe000000) << (BMP_BIT - 32), /* 196 -- 7, 7f */ + BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 197 -- 24, fedcba */ + BMP_C(0xfee80000) << (BMP_BIT - 32), /* 198 -- 16, fee8 */ + BMP_C(0xff000000) << (BMP_BIT - 32), /* 199 -- 8, ff */ + BMP_C(0xffc00000) << (BMP_BIT - 32), /* 200 -- 10, 3ff */ + BMP_C(0xfff00000) << (BMP_BIT - 32), /* 201 -- 12, fff */ + BMP_C(0xfffc0000) << (BMP_BIT - 32), /* 202 -- 14, 3fff */ + BMP_C(0xffff0000) << (BMP_BIT - 32), /* 203 -- 16, ffff */ + BMP_C(0xffffff00) << (BMP_BIT - 32), /* 204 -- 24, ffffff */ + BMP_C(0xfffffffc) << (BMP_BIT - 32), /* 205 -- 30,3fffffff */ + BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 206 -- 31,7fffffff */ + BMP_C(0xffffffff) << (BMP_BIT - 32), /* 207 -- 32,ffffffff */ }; static const struct malias aliases[]; @@ -471,265 +476,303 @@ static const struct malias aliases[]; * Sorted by left-justified polynomial for bsearch(). */ static const struct mpreset models[] = { - {64UL, b64, b64a, P_LE, b64a, b64b, b64c, aliases+100}, /* 0 */ - {32UL, b32+ 0, 0, P_BE, 0, b32+145, 0, aliases+138}, /* 1 */ - {40UL, b40, 0, P_BE, b40a, b40b, b40c, aliases+ 88}, /* 2 */ - {24UL, b32+ 3, b32+ 75, P_LE, 0, b32+150, 0, aliases+ 60}, /* 3 */ - {32UL, b32+ 8, 0, P_BE, b32+204, b32+ 91, b32+155, aliases+ 82}, /* 4 */ - {32UL, b32+ 8, b32+204, P_BE, 0, b32+ 7, 0, aliases+ 81}, /* 5 */ - {32UL, b32+ 8, b32+204, P_BE, b32+204, b32+191, b32+155, aliases+ 76}, /* 6 */ - {32UL, b32+ 8, b32+204, P_LE, 0, b32+ 55, 0, aliases+130}, /* 7 */ - {32UL, b32+ 8, b32+204, P_LE, b32+204, b32+158, b32+171, aliases+ 72}, /* 8 */ - {16UL, b32+ 9, 0, P_BE, 0, b32+ 5, 0, aliases+ 31}, /* 9 */ - {16UL, b32+ 9, 0, P_BE, b32+ 1, b32+ 4, b32+ 9, aliases+ 30}, /* 10 */ - { 8UL, b32+ 10, 0, P_BE, 0, b32+185, 0, aliases+106}, /* 11 */ - { 8UL, b32+ 10, 0, P_BE, b32+ 74, b32+123, b32+131, aliases+117}, /* 12 */ - { 8UL, b32+ 10, b32+196, P_LE, 0, b32+161, 0, aliases+121}, /* 13 */ - {31UL, b32+ 11, b32+203, P_BE, b32+203, b32+ 25, b32+119, aliases+ 71}, /* 14 */ - { 6UL, b32+ 13, 0, P_LE, 0, b32+ 24, 0, aliases+ 96}, /* 15 */ - {82UL, b82, 0, P_LE, 0, b82a, 0, aliases+124}, /* 16 */ - {16UL, b32+ 17, 0, P_BE, 0, b32+ 52, 0, aliases+139}, /* 17 */ - {16UL, b32+ 17, 0, P_BE, b32+200, b32+160, b32+ 28, aliases+ 36}, /* 18 */ - {16UL, b32+ 17, 0, P_LE, 0, b32+ 37, 0, aliases+131}, /* 19 */ - {16UL, b32+ 17, b32+ 28, P_BE, 0, b32+176, 0, aliases+ 21}, /* 20 */ - {16UL, b32+ 17, b32+107, P_LE, 0, b32+ 42, 0, aliases+ 53}, /* 21 */ - {16UL, b32+ 17, b32+135, P_LE, 0, b32+ 82, 0, aliases+ 49}, /* 22 */ - {16UL, b32+ 17, b32+154, P_LE, 0, b32+147, 0, aliases+125}, /* 23 */ - {16UL, b32+ 17, b32+200, P_BE, 0, b32+ 46, 0, aliases+ 24}, /* 24 */ - {16UL, b32+ 17, b32+200, P_BE, b32+200, b32+168, b32+ 28, aliases+ 35}, /* 25 */ - {16UL, b32+ 17, b32+200, P_LE, 0, b32+ 87, 0, aliases+ 45}, /* 26 */ - {16UL, b32+ 17, b32+200, P_LE, b32+200, b32+113, b32+183, aliases+135}, /* 27 */ - { 7UL, b32+ 18, 0, P_BE, 0, b32+179, 0, aliases+103}, /* 28 */ - { 6UL, b32+ 26, b32+190, P_BE, 0, b32+181, 0, aliases+ 93}, /* 29 */ - { 8UL, b32+ 27, 0, P_BE, 0, b32+ 56, 0, aliases+114}, /* 30 */ - { 8UL, b32+ 27, b32+192, P_BE, 0, b32+ 94, 0, aliases+116}, /* 31 */ - { 8UL, b32+ 27, b32+196, P_BE, b32+196, b32+ 69, b32+153, aliases+122}, /* 32 */ - { 8UL, b32+ 27, b32+196, P_LE, 0, b32+115, 0, aliases+113}, /* 33 */ - {16UL, b32+ 29, b32+200, P_BE, b32+200, b32+128, b32+175, aliases+ 48}, /* 34 */ - {32UL, b32+ 30, b32+204, P_LE, b32+204, b32+174, b32+142, aliases+ 83}, /* 35 */ - {14UL, b32+ 34, 0, P_LE, 0, b32+ 35, 0, aliases+ 14}, /* 36 */ - { 5UL, b32+ 45, b32+189, P_LE, b32+189, b32+156, b32+ 48, aliases+ 91}, /* 37 */ - { 8UL, b32+ 47, 0, P_BE, 0, b32+ 60, 0, aliases+120}, /* 38 */ - { 8UL, b32+ 47, b32+196, P_BE, b32+196, b32+172, b32+ 62, aliases+108}, /* 39 */ - { 4UL, b32+ 48, 0, P_LE, 0, b32+ 88, 0, aliases+ 87}, /* 40 */ - { 4UL, b32+ 48, b32+182, P_BE, b32+182, b32+133, b32+ 32, aliases+ 86}, /* 41 */ - { 8UL, b32+ 50, 0, P_LE, 0, b32+123, 0, aliases+119}, /* 42 */ - {24UL, b32+ 53, b32+201, P_BE, b32+201, b32+140, b32+ 20, aliases+ 63}, /* 43 */ - { 8UL, b32+ 58, 0, P_LE, 0, b32+ 21, 0, aliases+111}, /* 44 */ - {16UL, b32+ 59, 0, P_BE, b32+200, b32+151, b32+124, aliases+ 33}, /* 45 */ - {16UL, b32+ 59, 0, P_LE, b32+200, b32+180, b32+ 85, aliases+ 32}, /* 46 */ - {64UL, b64d, 0, P_BE, 0, b64e, 0, aliases+ 97}, /* 47 */ - {64UL, b64d, b64a, P_BE, b64a, b64f, b64g, aliases+101}, /* 48 */ - {64UL, b64d, b64a, P_LE, b64a, b64h, b64i, aliases+102}, /* 49 */ - { 5UL, b32+ 65, b32+ 65, P_BE, 0, 0, 0, aliases+ 89}, /* 50 */ - { 8UL, b32+ 66, 0, P_BE, b32+196, b32+114, b32+ 73, aliases+115}, /* 51 */ - {16UL, b32+ 76, 0, P_BE, 0, b32+ 77, 0, aliases+ 46}, /* 52 */ - {10UL, b32+ 78, 0, P_BE, b32+197, b32+ 67, b32+ 51, aliases+ 5}, /* 53 */ - {24UL, b32+ 79, b32+130, P_BE, 0, b32+ 31, 0, aliases+ 62}, /* 54 */ - {24UL, b32+ 79, b32+194, P_BE, 0, b32+ 93, 0, aliases+ 61}, /* 55 */ - { 3UL, b32+ 80, 0, P_BE, b32+173, b32+ 95, b32+ 61, aliases+ 68}, /* 56 */ - { 3UL, b32+ 80, b32+173, P_LE, 0, b32+148, 0, aliases+ 69}, /* 57 */ - {11UL, b32+ 81, 0, P_BE, 0, b32+ 14, 0, aliases+ 7}, /* 58 */ - { 6UL, b32+ 83, 0, P_LE, 0, b32+116, 0, aliases+ 94}, /* 59 */ - {16UL, b32+ 86, 0, P_BE, 0, b32+146, 0, aliases+ 42}, /* 60 */ - {11UL, b32+ 89, b32+ 6, P_BE, 0, b32+138, 0, aliases+ 6}, /* 61 */ - {16UL, b32+ 90, 0, P_BE, 0, b32+ 36, 0, aliases+ 47}, /* 62 */ - {24UL, b32+ 96, 0, P_BE, 0, b32+ 39, 0, aliases+ 65}, /* 63 */ - {24UL, b32+ 96, b32+201, P_BE, b32+201, b32+ 33, b32+ 99, aliases+ 67}, /* 64 */ - {16UL, b32+ 97, 0, P_BE, 0, b32+195, 0, aliases+ 22}, /* 65 */ - {16UL, b32+ 97, 0, P_LE, 0, b32+143, 0, aliases+ 0}, /* 66 */ - {16UL, b32+ 97, 0, P_LE, b32+200, b32+ 63, b32+134, aliases+ 44}, /* 67 */ - {16UL, b32+ 97, b32+ 98, P_BE, 0, b32+121, 0, aliases+ 29}, /* 68 */ - {16UL, b32+ 97, b32+200, P_BE, 0, b32+132, 0, aliases+ 27}, /* 69 */ - {16UL, b32+ 97, b32+200, P_LE, 0, b32+ 70, 0, aliases+132}, /* 70 */ - {16UL, b32+ 97, b32+200, P_LE, b32+200, b32+139, b32+134, aliases+ 55}, /* 71 */ - {14UL, b32+100, 0, P_BE, b32+199, b32+152, b32+ 15, aliases+ 15}, /* 72 */ - {30UL, b32+101, b32+202, P_BE, b32+202, b32+ 19, b32+165, aliases+ 70}, /* 73 */ - {12UL, b32+102, 0, P_BE, 0, b32+187, 0, aliases+ 10}, /* 74 */ - {12UL, b32+102, 0, P_BELE, 0, b32+170, 0, aliases+ 12}, /* 75 */ - {32UL, b32+103, 0, P_BE, 0, b32+ 49, 0, aliases+ 85}, /* 76 */ - {21UL, b32+104, 0, P_BE, 0, b32+ 92, 0, aliases+ 58}, /* 77 */ - {24UL, b32+105, 0, P_BE, 0, b32+159, 0, aliases+ 64}, /* 78 */ - {24UL, b32+105, b32+141, P_BE, 0, b32+ 38, 0, aliases+ 59}, /* 79 */ - { 7UL, b32+108, 0, P_BE, 0, b32+149, 0, aliases+105}, /* 80 */ - {15UL, b32+109, 0, P_BE, 0, b32+ 12, 0, aliases+ 16}, /* 81 */ - {16UL, b32+110, 0, P_BE, 0, b32+163, 0, aliases+ 51}, /* 82 */ - {10UL, b32+111, 0, P_BE, 0, b32+ 84, 0, aliases+ 3}, /* 83 */ - { 8UL, b32+117, 0, P_BE, 0, b32+179, 0, aliases+118}, /* 84 */ - { 8UL, b32+117, 0, P_LE, 0, b32+ 40, 0, aliases+123}, /* 85 */ - { 8UL, b32+117, b32+196, P_BE, 0, b32+169, 0, aliases+110}, /* 86 */ - { 6UL, b32+118, b32+190, P_BE, 0, b32+ 54, 0, aliases+ 92}, /* 87 */ - { 7UL, b32+120, b32+193, P_LE, 0, b32+125, 0, aliases+104}, /* 88 */ - {16UL, b32+122, 0, P_BE, 0, b32+ 16, 0, aliases+ 52}, /* 89 */ - { 8UL, b32+126, 0, P_LE, 0, b32+ 41, 0, aliases+109}, /* 90 */ - { 5UL, b32+127, 0, P_LE, 0, b32+ 57, 0, aliases+ 90}, /* 91 */ - {32UL, b32+129, b32+204, P_LE, b32+204, b32+106, b32+ 64, aliases+ 84}, /* 92 */ - {17UL, b32+137, 0, P_BE, 0, b32+ 43, 0, aliases+ 57}, /* 93 */ - { 6UL, b32+144, 0, P_BE, b32+190, b32+ 71, b32+178, aliases+ 95}, /* 94 */ - {16UL, b32+157, b32+200, P_BE, 0, b32+ 72, 0, aliases+ 26}, /* 95 */ - {15UL, b32+162, 0, P_BE, b32+ 2, b32+ 68, b32+162, aliases+ 17}, /* 96 */ - {12UL, b32+164, 0, P_BE, b32+198, b32+136, b32+ 23, aliases+ 11}, /* 97 */ - { 8UL, b32+167, 0, P_BE, 0, b32+144, 0, aliases+112}, /* 98 */ - {13UL, b32+177, 0, P_BE, 0, b32+ 44, 0, aliases+ 13}, /* 99 */ - {12UL, b32+184, b32+198, P_BE, 0, b32+166, 0, aliases+ 9}, /* 100 */ - {32UL, b32+186, b32+204, P_LE, b32+204, b32+ 22, b32+112, aliases+ 75}, /* 101 */ - {10UL, b32+188, b32+197, P_BE, 0, b32+111, 0, aliases+ 4}, /* 102 */ - { 0UL, 0, 0, P_BE, 0, 0, 0, NULL }, /* terminating entry */ + {64UL, b64, b64a, P_LE | P_CONFIR, b64a, b64b, b64c, aliases+130}, /* 0 */ + {32UL, b32+ 0, 0, P_BE | P_CONFIR, 0, b32+147, 0, aliases+107}, /* 1 */ + {40UL, b40, 0, P_BE | P_ACADEM, b40a, b40b, b40c, aliases+115}, /* 2 */ + {24UL, b32+ 3, b32+ 76, P_LE | P_ATTEST, 0, b32+152, 0, aliases+ 77}, /* 3 */ + {32UL, b32+ 8, 0, P_BE | P_ATTEST, b32+207, b32+ 92, b32+157, aliases+ 98}, /* 4 */ + {32UL, b32+ 8, b32+207, P_BE | P_ATTEST, 0, b32+ 7, 0, aliases+104}, /* 5 */ + {32UL, b32+ 8, b32+207, P_BE | P_ATTEST, b32+207, b32+194, b32+157, aliases+ 96}, /* 6 */ + {32UL, b32+ 8, b32+207, P_LE | P_CONFIR, 0, b32+ 56, 0, aliases+103}, /* 7 */ + {32UL, b32+ 8, b32+207, P_LE | P_ATTEST, b32+207, b32+160, b32+173, aliases+102}, /* 8 */ + {16UL, b32+ 9, 0, P_BE | P_ATTEST, 0, b32+ 5, 0, aliases+ 36}, /* 9 */ + {16UL, b32+ 9, 0, P_BE | P_ATTEST, b32+ 1, b32+ 4, b32+ 9, aliases+ 35}, /* 10 */ + { 8UL, b32+ 10, 0, P_BE | P_ATTEST, 0, b32+187, 0, aliases+157}, /* 11 */ + { 8UL, b32+ 10, 0, P_BE | P_ACADEM, b32+ 75, b32+125, b32+133, aliases+147}, /* 12 */ + { 8UL, b32+ 10, b32+199, P_LE | P_ACADEM, 0, b32+163, 0, aliases+155}, /* 13 */ + {16UL, b32+ 11, b32+203, P_LE | P_ATTEST, 0, b32+123, 0, aliases+ 58}, /* 14 */ + {31UL, b32+ 12, b32+206, P_BE | P_CONFIR, b32+206, b32+ 26, b32+120, aliases+ 88}, /* 15 */ + { 6UL, b32+ 14, 0, P_LE | P_ACADEM, 0, b32+ 25, 0, aliases+124}, /* 16 */ + {82UL, b82, 0, P_LE | P_ATTEST, 0, b82a, 0, aliases+160}, /* 17 */ + {16UL, b32+ 18, 0, P_BE | P_ATTEST, 0, b32+ 53, 0, aliases+ 73}, /* 18 */ + {16UL, b32+ 18, 0, P_BE | P_ACADEM, b32+203, b32+162, b32+ 29, aliases+ 42}, /* 19 */ + {16UL, b32+ 18, 0, P_LE | P_ATTEST, 0, b32+ 38, 0, aliases+ 50}, /* 20 */ + {16UL, b32+ 18, b32+ 29, P_BE | P_ATTEST, 0, b32+178, 0, aliases+ 63}, /* 21 */ + {16UL, b32+ 18, b32+108, P_LE | P_ATTEST, 0, b32+ 43, 0, aliases+ 66}, /* 22 */ + {16UL, b32+ 18, b32+137, P_LE | P_THIRDP, 0, b32+ 83, 0, aliases+ 62}, /* 23 */ + {16UL, b32+ 18, b32+156, P_LE | P_ATTEST, 0, b32+149, 0, aliases+ 48}, /* 24 */ + {16UL, b32+ 18, b32+203, P_BE | P_ATTEST, 0, b32+ 47, 0, aliases+ 44}, /* 25 */ + {16UL, b32+ 18, b32+203, P_BE | P_ATTEST, b32+203, b32+170, b32+ 29, aliases+ 41}, /* 26 */ + {16UL, b32+ 18, b32+203, P_LE | P_ATTEST, 0, b32+ 88, 0, aliases+ 56}, /* 27 */ + {16UL, b32+ 18, b32+203, P_LE | P_ATTEST, b32+203, b32+114, b32+185, aliases+ 45}, /* 28 */ + { 7UL, b32+ 19, 0, P_BE | P_ACADEM, 0, b32+181, 0, aliases+134}, /* 29 */ + { 6UL, b32+ 27, b32+193, P_BE | P_ACADEM, 0, b32+183, 0, aliases+122}, /* 30 */ + { 8UL, b32+ 28, 0, P_BE | P_ACADEM, 0, b32+ 57, 0, aliases+145}, /* 31 */ + { 8UL, b32+ 28, b32+195, P_BE | P_ATTEST, 0, b32+ 95, 0, aliases+148}, /* 32 */ + { 8UL, b32+ 28, b32+199, P_BE | P_ATTEST, b32+199, b32+ 70, b32+155, aliases+156}, /* 33 */ + { 8UL, b32+ 28, b32+199, P_LE | P_ATTEST, 0, b32+116, 0, aliases+158}, /* 34 */ + {16UL, b32+ 30, b32+203, P_BE | P_ATTEST, b32+203, b32+130, b32+177, aliases+ 61}, /* 35 */ + {32UL, b32+ 31, b32+207, P_LE | P_ATTEST, b32+207, b32+176, b32+144, aliases+101}, /* 36 */ + {14UL, b32+ 35, 0, P_LE | P_ATTEST, 0, b32+ 36, 0, aliases+ 17}, /* 37 */ + { 5UL, b32+ 46, b32+192, P_LE | P_THIRDP, b32+192, b32+158, b32+ 49, aliases+120}, /* 38 */ + { 8UL, b32+ 48, 0, P_BE | P_ATTEST, 0, b32+ 61, 0, aliases+154}, /* 39 */ + { 8UL, b32+ 48, b32+199, P_BE | P_ATTEST, b32+199, b32+174, b32+ 63, aliases+139}, /* 40 */ + { 4UL, b32+ 49, 0, P_LE | P_ACADEM, 0, b32+ 89, 0, aliases+112}, /* 41 */ + { 4UL, b32+ 49, b32+184, P_BE | P_ACADEM, b32+184, b32+135, b32+ 33, aliases+113}, /* 42 */ + { 8UL, b32+ 51, 0, P_LE | P_ATTEST, 0, b32+125, 0, aliases+152}, /* 43 */ + { 8UL, b32+ 51, b32+199, P_BE | P_ATTEST, 0, b32+191, 0, aliases+153}, /* 44 */ + {24UL, b32+ 54, b32+204, P_BE | P_ACADEM, b32+204, b32+142, b32+ 21, aliases+ 80}, /* 45 */ + { 8UL, b32+ 59, 0, P_LE | P_ATTEST, 0, b32+ 22, 0, aliases+142}, /* 46 */ + {16UL, b32+ 60, 0, P_BE | P_CONFIR, b32+203, b32+153, b32+126, aliases+ 38}, /* 47 */ + {16UL, b32+ 60, 0, P_LE | P_CONFIR, b32+203, b32+182, b32+ 86, aliases+ 37}, /* 48 */ + {64UL, b64d, 0, P_BE | P_ACADEM, 0, b64e, 0, aliases+128}, /* 49 */ + {64UL, b64d, b64a, P_BE | P_CONFIR, b64a, b64f, b64g, aliases+131}, /* 50 */ + {64UL, b64d, b64a, P_LE | P_ATTEST, b64a, b64h, b64i, aliases+132}, /* 51 */ + { 5UL, b32+ 66, b32+ 66, P_BE | P_ATTEST, 0, 0, 0, aliases+117}, /* 52 */ + { 8UL, b32+ 67, 0, P_BE | P_ACADEM, b32+199, b32+115, b32+ 74, aliases+146}, /* 53 */ + {16UL, b32+ 77, 0, P_BE | P_ATTEST, 0, b32+ 78, 0, aliases+ 59}, /* 54 */ + {10UL, b32+ 79, 0, P_BE | P_ACADEM, b32+200, b32+ 68, b32+ 52, aliases+ 6}, /* 55 */ + {24UL, b32+ 80, b32+132, P_BE | P_ATTEST, 0, b32+ 32, 0, aliases+ 79}, /* 56 */ + {24UL, b32+ 80, b32+197, P_BE | P_ATTEST, 0, b32+ 94, 0, aliases+ 78}, /* 57 */ + { 3UL, b32+ 81, 0, P_BE | P_ACADEM, b32+175, b32+ 96, b32+ 62, aliases+ 85}, /* 58 */ + { 3UL, b32+ 81, b32+175, P_LE | P_ACADEM, 0, b32+150, 0, aliases+ 86}, /* 59 */ + {11UL, b32+ 82, 0, P_BE | P_ACADEM, 0, b32+ 15, 0, aliases+ 10}, /* 60 */ + { 6UL, b32+ 84, 0, P_LE | P_ATTEST, 0, b32+117, 0, aliases+123}, /* 61 */ + {16UL, b32+ 87, 0, P_BE | P_THIRDP, 0, b32+148, 0, aliases+ 52}, /* 62 */ + {11UL, b32+ 90, b32+ 6, P_BE | P_ATTEST, 0, b32+140, 0, aliases+ 9}, /* 63 */ + {16UL, b32+ 91, 0, P_BE | P_ATTEST, 0, b32+ 37, 0, aliases+ 60}, /* 64 */ + {24UL, b32+ 97, 0, P_BE | P_ACADEM, 0, b32+ 40, 0, aliases+ 82}, /* 65 */ + {24UL, b32+ 97, b32+204, P_BE | P_ATTEST, b32+204, b32+ 34, b32+100, aliases+ 84}, /* 66 */ + {16UL, b32+ 98, 0, P_BE | P_ATTEST, 0, b32+198, 0, aliases+ 67}, /* 67 */ + {16UL, b32+ 98, 0, P_LE | P_CONFIR, 0, b32+145, 0, aliases+ 24}, /* 68 */ + {16UL, b32+ 98, 0, P_LE | P_ATTEST, b32+203, b32+ 64, b32+136, aliases+ 55}, /* 69 */ + {16UL, b32+ 98, b32+ 99, P_BE | P_ATTEST, 0, b32+122, 0, aliases+ 34}, /* 70 */ + {16UL, b32+ 98, b32+203, P_BE | P_THIRDP, 0, b32+134, 0, aliases+ 32}, /* 71 */ + {16UL, b32+ 98, b32+203, P_LE | P_ATTEST, 0, b32+ 71, 0, aliases+ 57}, /* 72 */ + {16UL, b32+ 98, b32+203, P_LE | P_THIRDP, b32+203, b32+141, b32+136, aliases+ 68}, /* 73 */ + {14UL, b32+101, 0, P_BE | P_ACADEM, b32+202, b32+154, b32+ 16, aliases+ 18}, /* 74 */ + {30UL, b32+102, b32+205, P_BE | P_ACADEM, b32+205, b32+ 20, b32+167, aliases+ 87}, /* 75 */ + {12UL, b32+103, 0, P_BE | P_ACADEM, 0, b32+189, 0, aliases+ 13}, /* 76 */ + {12UL, b32+103, 0, P_BELE | P_ACADEM, 0, b32+172, 0, aliases+ 15}, /* 77 */ + {32UL, b32+104, 0, P_BE | P_ATTEST, 0, b32+ 50, 0, aliases+ 92}, /* 78 */ + {21UL, b32+105, 0, P_BE | P_ACADEM, 0, b32+ 93, 0, aliases+ 75}, /* 79 */ + {24UL, b32+106, 0, P_BE | P_ACADEM, 0, b32+161, 0, aliases+ 81}, /* 80 */ + {24UL, b32+106, b32+143, P_BE | P_ATTEST, 0, b32+ 39, 0, aliases+ 83}, /* 81 */ + { 7UL, b32+109, 0, P_BE | P_ACADEM, 0, b32+151, 0, aliases+136}, /* 82 */ + {15UL, b32+110, 0, P_BE | P_ACADEM, 0, b32+ 13, 0, aliases+ 20}, /* 83 */ + {16UL, b32+111, 0, P_BE | P_ATTEST, 0, b32+165, 0, aliases+ 64}, /* 84 */ + {10UL, b32+112, 0, P_BE | P_ATTEST, 0, b32+ 85, 0, aliases+ 4}, /* 85 */ + { 8UL, b32+118, 0, P_BE | P_ACADEM, 0, b32+181, 0, aliases+150}, /* 86 */ + { 8UL, b32+118, 0, P_LE | P_THIRDP, 0, b32+ 41, 0, aliases+159}, /* 87 */ + { 8UL, b32+118, b32+199, P_BE | P_ACADEM, 0, b32+171, 0, aliases+141}, /* 88 */ + { 6UL, b32+119, b32+193, P_BE | P_ATTEST, 0, b32+ 55, 0, aliases+121}, /* 89 */ + { 7UL, b32+121, b32+196, P_LE | P_ACADEM, 0, b32+127, 0, aliases+135}, /* 90 */ + {16UL, b32+124, 0, P_BE | P_CONFIR, 0, b32+ 17, 0, aliases+ 65}, /* 91 */ + { 8UL, b32+128, 0, P_LE | P_ATTEST, 0, b32+ 42, 0, aliases+140}, /* 92 */ + { 5UL, b32+129, 0, P_LE | P_ACADEM, 0, b32+ 58, 0, aliases+118}, /* 93 */ + {32UL, b32+131, b32+207, P_LE | P_CONFIR, b32+207, b32+107, b32+ 65, aliases+ 95}, /* 94 */ + {17UL, b32+139, 0, P_BE | P_ACADEM, 0, b32+ 44, 0, aliases+ 74}, /* 95 */ + { 6UL, b32+146, 0, P_BE | P_ACADEM, b32+193, b32+ 72, b32+180, aliases+125}, /* 96 */ + {16UL, b32+159, b32+203, P_BE | P_ACADEM, 0, b32+ 73, 0, aliases+ 31}, /* 97 */ + {15UL, b32+164, 0, P_BE | P_ATTEST, b32+ 2, b32+ 69, b32+164, aliases+ 21}, /* 98 */ + {12UL, b32+166, 0, P_BE | P_ACADEM, b32+201, b32+138, b32+ 24, aliases+ 14}, /* 99 */ + { 8UL, b32+169, 0, P_BE | P_ACADEM, 0, b32+146, 0, aliases+143}, /* 100 */ + {13UL, b32+179, 0, P_BE | P_ATTEST, 0, b32+ 45, 0, aliases+ 16}, /* 101 */ + {12UL, b32+186, b32+201, P_BE | P_ACADEM, 0, b32+168, 0, aliases+ 12}, /* 102 */ + {32UL, b32+188, b32+207, P_LE | P_ATTEST, b32+207, b32+ 23, b32+113, aliases+ 93}, /* 103 */ + {10UL, b32+190, b32+200, P_BE | P_ACADEM, 0, b32+112, 0, aliases+ 5}, /* 104 */ + { 0UL, 0, 0, P_BE | P_UNDFCL, 0, 0, 0, NULL }, /* terminating entry */ }; -# define NPRESETS 103 +# define NPRESETS 105 /* List of names with pointers to models, pre-sorted for use with bsearch() */ static const struct malias aliases[] = { - {"ARC", models+ 66}, /* 0 */ - {"B-CRC-32", models+ 6}, /* 1 */ - {"CKSUM", models+ 4}, /* 2 */ - {"CRC-10", models+ 83}, /* 3 */ - {"CRC-10/CDMA2000", models+102}, /* 4 */ - {"CRC-10/GSM", models+ 53}, /* 5 */ - {"CRC-11", models+ 61}, /* 6 */ - {"CRC-11/UMTS", models+ 58}, /* 7 */ - {"CRC-12/3GPP", models+ 75}, /* 8 */ - {"CRC-12/CDMA2000", models+100}, /* 9 */ - {"CRC-12/DECT", models+ 74}, /* 10 */ - {"CRC-12/GSM", models+ 97}, /* 11 */ - {"CRC-12/UMTS", models+ 75}, /* 12 */ - {"CRC-13/BBC", models+ 99}, /* 13 */ - {"CRC-14/DARC", models+ 36}, /* 14 */ - {"CRC-14/GSM", models+ 72}, /* 15 */ - {"CRC-15", models+ 81}, /* 16 */ - {"CRC-15/MPT1327", models+ 96}, /* 17 */ - {"CRC-16", models+ 66}, /* 18 */ - {"CRC-16/ACORN", models+ 17}, /* 19 */ - {"CRC-16/ARC", models+ 66}, /* 20 */ - {"CRC-16/AUG-CCITT", models+ 20}, /* 21 */ - {"CRC-16/BUYPASS", models+ 65}, /* 22 */ - {"CRC-16/CCITT", models+ 19}, /* 23 */ - {"CRC-16/CCITT-FALSE", models+ 24}, /* 24 */ - {"CRC-16/CCITT-TRUE", models+ 19}, /* 25 */ - {"CRC-16/CDMA2000", models+ 95}, /* 26 */ - {"CRC-16/CMS", models+ 69}, /* 27 */ - {"CRC-16/DARC", models+ 25}, /* 28 */ - {"CRC-16/DDS-110", models+ 68}, /* 29 */ - {"CRC-16/DECT-R", models+ 10}, /* 30 */ - {"CRC-16/DECT-X", models+ 9}, /* 31 */ - {"CRC-16/DNP", models+ 46}, /* 32 */ - {"CRC-16/EN-13757", models+ 45}, /* 33 */ - {"CRC-16/EPC", models+ 25}, /* 34 */ - {"CRC-16/GENIBUS", models+ 25}, /* 35 */ - {"CRC-16/GSM", models+ 18}, /* 36 */ - {"CRC-16/I-CODE", models+ 25}, /* 37 */ - {"CRC-16/IBM-SDLC", models+ 27}, /* 38 */ - {"CRC-16/IEC-61158-2", models+ 34}, /* 39 */ - {"CRC-16/ISO-HDLC", models+ 27}, /* 40 */ - {"CRC-16/LHA", models+ 66}, /* 41 */ - {"CRC-16/LJ1200", models+ 60}, /* 42 */ - {"CRC-16/LTE", models+ 17}, /* 43 */ - {"CRC-16/MAXIM", models+ 67}, /* 44 */ - {"CRC-16/MCRF4XX", models+ 26}, /* 45 */ - {"CRC-16/OPENSAFETY-A", models+ 52}, /* 46 */ - {"CRC-16/OPENSAFETY-B", models+ 62}, /* 47 */ - {"CRC-16/PROFIBUS", models+ 34}, /* 48 */ - {"CRC-16/RIELLO", models+ 22}, /* 49 */ - {"CRC-16/SPI-FUJITSU", models+ 20}, /* 50 */ - {"CRC-16/T10-DIF", models+ 82}, /* 51 */ - {"CRC-16/TELEDISK", models+ 89}, /* 52 */ - {"CRC-16/TMS37157", models+ 21}, /* 53 */ - {"CRC-16/UMTS", models+ 65}, /* 54 */ - {"CRC-16/USB", models+ 71}, /* 55 */ - {"CRC-16/VERIFONE", models+ 65}, /* 56 */ - {"CRC-17/CAN-FD", models+ 93}, /* 57 */ - {"CRC-21/CAN-FD", models+ 77}, /* 58 */ - {"CRC-24", models+ 79}, /* 59 */ - {"CRC-24/BLE", models+ 3}, /* 60 */ - {"CRC-24/FLEXRAY-A", models+ 55}, /* 61 */ - {"CRC-24/FLEXRAY-B", models+ 54}, /* 62 */ - {"CRC-24/INTERLAKEN", models+ 43}, /* 63 */ - {"CRC-24/LTE-A", models+ 78}, /* 64 */ - {"CRC-24/LTE-B", models+ 63}, /* 65 */ - {"CRC-24/OPENPGP", models+ 79}, /* 66 */ - {"CRC-24/OS-9", models+ 64}, /* 67 */ - {"CRC-3/GSM", models+ 56}, /* 68 */ - {"CRC-3/ROHC", models+ 57}, /* 69 */ - {"CRC-30/CDMA", models+ 73}, /* 70 */ - {"CRC-31/PHILIPS", models+ 14}, /* 71 */ - {"CRC-32", models+ 8}, /* 72 */ - {"CRC-32/AAL5", models+ 6}, /* 73 */ - {"CRC-32/ADCCP", models+ 8}, /* 74 */ - {"CRC-32/AUTOSAR", models+101}, /* 75 */ - {"CRC-32/BZIP2", models+ 6}, /* 76 */ - {"CRC-32/CASTAGNOLI", models+ 35}, /* 77 */ - {"CRC-32/DECT-B", models+ 6}, /* 78 */ - {"CRC-32/INTERLAKEN", models+ 35}, /* 79 */ - {"CRC-32/ISCSI", models+ 35}, /* 80 */ - {"CRC-32/MPEG-2", models+ 5}, /* 81 */ - {"CRC-32/POSIX", models+ 4}, /* 82 */ - {"CRC-32C", models+ 35}, /* 83 */ - {"CRC-32D", models+ 92}, /* 84 */ - {"CRC-32Q", models+ 76}, /* 85 */ - {"CRC-4/INTERLAKEN", models+ 41}, /* 86 */ - {"CRC-4/ITU", models+ 40}, /* 87 */ - {"CRC-40/GSM", models+ 2}, /* 88 */ - {"CRC-5/EPC", models+ 50}, /* 89 */ - {"CRC-5/ITU", models+ 91}, /* 90 */ - {"CRC-5/USB", models+ 37}, /* 91 */ - {"CRC-6/CDMA2000-A", models+ 87}, /* 92 */ - {"CRC-6/CDMA2000-B", models+ 29}, /* 93 */ - {"CRC-6/DARC", models+ 59}, /* 94 */ - {"CRC-6/GSM", models+ 94}, /* 95 */ - {"CRC-6/ITU", models+ 15}, /* 96 */ - {"CRC-64", models+ 47}, /* 97 */ - {"CRC-64/ECMA-182", models+ 47}, /* 98 */ - {"CRC-64/GO-ECMA", models+ 49}, /* 99 */ - {"CRC-64/GO-ISO", models+ 0}, /* 100 */ - {"CRC-64/WE", models+ 48}, /* 101 */ - {"CRC-64/XZ", models+ 49}, /* 102 */ - {"CRC-7", models+ 28}, /* 103 */ - {"CRC-7/ROHC", models+ 88}, /* 104 */ - {"CRC-7/UMTS", models+ 80}, /* 105 */ - {"CRC-8", models+ 11}, /* 106 */ - {"CRC-8/AES", models+ 33}, /* 107 */ - {"CRC-8/AUTOSAR", models+ 39}, /* 108 */ - {"CRC-8/BLUETOOTH", models+ 90}, /* 109 */ - {"CRC-8/CDMA2000", models+ 86}, /* 110 */ - {"CRC-8/DARC", models+ 44}, /* 111 */ - {"CRC-8/DVB-S2", models+ 98}, /* 112 */ - {"CRC-8/EBU", models+ 33}, /* 113 */ - {"CRC-8/GSM-A", models+ 30}, /* 114 */ - {"CRC-8/GSM-B", models+ 51}, /* 115 */ - {"CRC-8/I-CODE", models+ 31}, /* 116 */ - {"CRC-8/ITU", models+ 12}, /* 117 */ - {"CRC-8/LTE", models+ 84}, /* 118 */ - {"CRC-8/MAXIM", models+ 42}, /* 119 */ - {"CRC-8/OPENSAFETY", models+ 38}, /* 120 */ - {"CRC-8/ROHC", models+ 13}, /* 121 */ - {"CRC-8/SAE-J1850", models+ 32}, /* 122 */ - {"CRC-8/WCDMA", models+ 85}, /* 123 */ - {"CRC-82/DARC", models+ 16}, /* 124 */ - {"CRC-A", models+ 23}, /* 125 */ - {"CRC-B", models+ 27}, /* 126 */ - {"CRC-CCITT", models+ 19}, /* 127 */ - {"CRC-IBM", models+ 66}, /* 128 */ - {"DOW-CRC", models+ 42}, /* 129 */ - {"JAMCRC", models+ 7}, /* 130 */ - {"KERMIT", models+ 19}, /* 131 */ - {"MODBUS", models+ 70}, /* 132 */ - {"PKZIP", models+ 8}, /* 133 */ - {"R-CRC-16", models+ 10}, /* 134 */ - {"X-25", models+ 27}, /* 135 */ - {"X-CRC-12", models+ 74}, /* 136 */ - {"X-CRC-16", models+ 9}, /* 137 */ - {"XFER", models+ 1}, /* 138 */ - {"XMODEM", models+ 17}, /* 139 */ - {"ZMODEM", models+ 17}, /* 140 */ - {NULL, NULL }, /* terminating entry */ + {"ARC", models+ 68}, /* 0 */ + {"B-CRC-32", models+ 6}, /* 1 */ + {"CKSUM", models+ 4}, /* 2 */ + {"CRC-10", models+ 85}, /* 3 */ + {"CRC-10/ATM", models+ 85}, /* 4 */ + {"CRC-10/CDMA2000", models+104}, /* 5 */ + {"CRC-10/GSM", models+ 55}, /* 6 */ + {"CRC-10/I-610", models+ 85}, /* 7 */ + {"CRC-11", models+ 63}, /* 8 */ + {"CRC-11/FLEXRAY", models+ 63}, /* 9 */ + {"CRC-11/UMTS", models+ 60}, /* 10 */ + {"CRC-12/3GPP", models+ 77}, /* 11 */ + {"CRC-12/CDMA2000", models+102}, /* 12 */ + {"CRC-12/DECT", models+ 76}, /* 13 */ + {"CRC-12/GSM", models+ 99}, /* 14 */ + {"CRC-12/UMTS", models+ 77}, /* 15 */ + {"CRC-13/BBC", models+101}, /* 16 */ + {"CRC-14/DARC", models+ 37}, /* 17 */ + {"CRC-14/GSM", models+ 74}, /* 18 */ + {"CRC-15", models+ 83}, /* 19 */ + {"CRC-15/CAN", models+ 83}, /* 20 */ + {"CRC-15/MPT1327", models+ 98}, /* 21 */ + {"CRC-16", models+ 68}, /* 22 */ + {"CRC-16/ACORN", models+ 18}, /* 23 */ + {"CRC-16/ARC", models+ 68}, /* 24 */ + {"CRC-16/AUG-CCITT", models+ 21}, /* 25 */ + {"CRC-16/AUTOSAR", models+ 25}, /* 26 */ + {"CRC-16/BUYPASS", models+ 67}, /* 27 */ + {"CRC-16/CCITT", models+ 20}, /* 28 */ + {"CRC-16/CCITT-FALSE", models+ 25}, /* 29 */ + {"CRC-16/CCITT-TRUE", models+ 20}, /* 30 */ + {"CRC-16/CDMA2000", models+ 97}, /* 31 */ + {"CRC-16/CMS", models+ 71}, /* 32 */ + {"CRC-16/DARC", models+ 26}, /* 33 */ + {"CRC-16/DDS-110", models+ 70}, /* 34 */ + {"CRC-16/DECT-R", models+ 10}, /* 35 */ + {"CRC-16/DECT-X", models+ 9}, /* 36 */ + {"CRC-16/DNP", models+ 48}, /* 37 */ + {"CRC-16/EN-13757", models+ 47}, /* 38 */ + {"CRC-16/EPC", models+ 26}, /* 39 */ + {"CRC-16/EPC-C1G2", models+ 26}, /* 40 */ + {"CRC-16/GENIBUS", models+ 26}, /* 41 */ + {"CRC-16/GSM", models+ 19}, /* 42 */ + {"CRC-16/I-CODE", models+ 26}, /* 43 */ + {"CRC-16/IBM-3740", models+ 25}, /* 44 */ + {"CRC-16/IBM-SDLC", models+ 28}, /* 45 */ + {"CRC-16/IEC-61158-2", models+ 35}, /* 46 */ + {"CRC-16/ISO-HDLC", models+ 28}, /* 47 */ + {"CRC-16/ISO-IEC-14443-3-A", models+ 24}, /* 48 */ + {"CRC-16/ISO-IEC-14443-3-B", models+ 28}, /* 49 */ + {"CRC-16/KERMIT", models+ 20}, /* 50 */ + {"CRC-16/LHA", models+ 68}, /* 51 */ + {"CRC-16/LJ1200", models+ 62}, /* 52 */ + {"CRC-16/LTE", models+ 18}, /* 53 */ + {"CRC-16/MAXIM", models+ 69}, /* 54 */ + {"CRC-16/MAXIM-DOW", models+ 69}, /* 55 */ + {"CRC-16/MCRF4XX", models+ 27}, /* 56 */ + {"CRC-16/MODBUS", models+ 72}, /* 57 */ + {"CRC-16/NRSC-5", models+ 14}, /* 58 */ + {"CRC-16/OPENSAFETY-A", models+ 54}, /* 59 */ + {"CRC-16/OPENSAFETY-B", models+ 64}, /* 60 */ + {"CRC-16/PROFIBUS", models+ 35}, /* 61 */ + {"CRC-16/RIELLO", models+ 23}, /* 62 */ + {"CRC-16/SPI-FUJITSU", models+ 21}, /* 63 */ + {"CRC-16/T10-DIF", models+ 84}, /* 64 */ + {"CRC-16/TELEDISK", models+ 91}, /* 65 */ + {"CRC-16/TMS37157", models+ 22}, /* 66 */ + {"CRC-16/UMTS", models+ 67}, /* 67 */ + {"CRC-16/USB", models+ 73}, /* 68 */ + {"CRC-16/V-41-LSB", models+ 20}, /* 69 */ + {"CRC-16/V-41-MSB", models+ 18}, /* 70 */ + {"CRC-16/VERIFONE", models+ 67}, /* 71 */ + {"CRC-16/X-25", models+ 28}, /* 72 */ + {"CRC-16/XMODEM", models+ 18}, /* 73 */ + {"CRC-17/CAN-FD", models+ 95}, /* 74 */ + {"CRC-21/CAN-FD", models+ 79}, /* 75 */ + {"CRC-24", models+ 81}, /* 76 */ + {"CRC-24/BLE", models+ 3}, /* 77 */ + {"CRC-24/FLEXRAY-A", models+ 57}, /* 78 */ + {"CRC-24/FLEXRAY-B", models+ 56}, /* 79 */ + {"CRC-24/INTERLAKEN", models+ 45}, /* 80 */ + {"CRC-24/LTE-A", models+ 80}, /* 81 */ + {"CRC-24/LTE-B", models+ 65}, /* 82 */ + {"CRC-24/OPENPGP", models+ 81}, /* 83 */ + {"CRC-24/OS-9", models+ 66}, /* 84 */ + {"CRC-3/GSM", models+ 58}, /* 85 */ + {"CRC-3/ROHC", models+ 59}, /* 86 */ + {"CRC-30/CDMA", models+ 75}, /* 87 */ + {"CRC-31/PHILIPS", models+ 15}, /* 88 */ + {"CRC-32", models+ 8}, /* 89 */ + {"CRC-32/AAL5", models+ 6}, /* 90 */ + {"CRC-32/ADCCP", models+ 8}, /* 91 */ + {"CRC-32/AIXM", models+ 78}, /* 92 */ + {"CRC-32/AUTOSAR", models+103}, /* 93 */ + {"CRC-32/BASE91-C", models+ 36}, /* 94 */ + {"CRC-32/BASE91-D", models+ 94}, /* 95 */ + {"CRC-32/BZIP2", models+ 6}, /* 96 */ + {"CRC-32/CASTAGNOLI", models+ 36}, /* 97 */ + {"CRC-32/CKSUM", models+ 4}, /* 98 */ + {"CRC-32/DECT-B", models+ 6}, /* 99 */ + {"CRC-32/INTERLAKEN", models+ 36}, /* 100 */ + {"CRC-32/ISCSI", models+ 36}, /* 101 */ + {"CRC-32/ISO-HDLC", models+ 8}, /* 102 */ + {"CRC-32/JAMCRC", models+ 7}, /* 103 */ + {"CRC-32/MPEG-2", models+ 5}, /* 104 */ + {"CRC-32/POSIX", models+ 4}, /* 105 */ + {"CRC-32/V-42", models+ 8}, /* 106 */ + {"CRC-32/XFER", models+ 1}, /* 107 */ + {"CRC-32/XZ", models+ 8}, /* 108 */ + {"CRC-32C", models+ 36}, /* 109 */ + {"CRC-32D", models+ 94}, /* 110 */ + {"CRC-32Q", models+ 78}, /* 111 */ + {"CRC-4/G-704", models+ 41}, /* 112 */ + {"CRC-4/INTERLAKEN", models+ 42}, /* 113 */ + {"CRC-4/ITU", models+ 41}, /* 114 */ + {"CRC-40/GSM", models+ 2}, /* 115 */ + {"CRC-5/EPC", models+ 52}, /* 116 */ + {"CRC-5/EPC-C1G2", models+ 52}, /* 117 */ + {"CRC-5/G-704", models+ 93}, /* 118 */ + {"CRC-5/ITU", models+ 93}, /* 119 */ + {"CRC-5/USB", models+ 38}, /* 120 */ + {"CRC-6/CDMA2000-A", models+ 89}, /* 121 */ + {"CRC-6/CDMA2000-B", models+ 30}, /* 122 */ + {"CRC-6/DARC", models+ 61}, /* 123 */ + {"CRC-6/G-704", models+ 16}, /* 124 */ + {"CRC-6/GSM", models+ 96}, /* 125 */ + {"CRC-6/ITU", models+ 16}, /* 126 */ + {"CRC-64", models+ 49}, /* 127 */ + {"CRC-64/ECMA-182", models+ 49}, /* 128 */ + {"CRC-64/GO-ECMA", models+ 51}, /* 129 */ + {"CRC-64/GO-ISO", models+ 0}, /* 130 */ + {"CRC-64/WE", models+ 50}, /* 131 */ + {"CRC-64/XZ", models+ 51}, /* 132 */ + {"CRC-7", models+ 29}, /* 133 */ + {"CRC-7/MMC", models+ 29}, /* 134 */ + {"CRC-7/ROHC", models+ 90}, /* 135 */ + {"CRC-7/UMTS", models+ 82}, /* 136 */ + {"CRC-8", models+ 11}, /* 137 */ + {"CRC-8/AES", models+ 34}, /* 138 */ + {"CRC-8/AUTOSAR", models+ 40}, /* 139 */ + {"CRC-8/BLUETOOTH", models+ 92}, /* 140 */ + {"CRC-8/CDMA2000", models+ 88}, /* 141 */ + {"CRC-8/DARC", models+ 46}, /* 142 */ + {"CRC-8/DVB-S2", models+100}, /* 143 */ + {"CRC-8/EBU", models+ 34}, /* 144 */ + {"CRC-8/GSM-A", models+ 31}, /* 145 */ + {"CRC-8/GSM-B", models+ 53}, /* 146 */ + {"CRC-8/I-432-1", models+ 12}, /* 147 */ + {"CRC-8/I-CODE", models+ 32}, /* 148 */ + {"CRC-8/ITU", models+ 12}, /* 149 */ + {"CRC-8/LTE", models+ 86}, /* 150 */ + {"CRC-8/MAXIM", models+ 43}, /* 151 */ + {"CRC-8/MAXIM-DOW", models+ 43}, /* 152 */ + {"CRC-8/NRSC-5", models+ 44}, /* 153 */ + {"CRC-8/OPENSAFETY", models+ 39}, /* 154 */ + {"CRC-8/ROHC", models+ 13}, /* 155 */ + {"CRC-8/SAE-J1850", models+ 33}, /* 156 */ + {"CRC-8/SMBUS", models+ 11}, /* 157 */ + {"CRC-8/TECH-3250", models+ 34}, /* 158 */ + {"CRC-8/WCDMA", models+ 87}, /* 159 */ + {"CRC-82/DARC", models+ 17}, /* 160 */ + {"CRC-A", models+ 24}, /* 161 */ + {"CRC-B", models+ 28}, /* 162 */ + {"CRC-CCITT", models+ 20}, /* 163 */ + {"CRC-IBM", models+ 68}, /* 164 */ + {"DOW-CRC", models+ 43}, /* 165 */ + {"JAMCRC", models+ 7}, /* 166 */ + {"KERMIT", models+ 20}, /* 167 */ + {"MODBUS", models+ 72}, /* 168 */ + {"PKZIP", models+ 8}, /* 169 */ + {"R-CRC-16", models+ 10}, /* 170 */ + {"X-25", models+ 28}, /* 171 */ + {"X-CRC-12", models+ 76}, /* 172 */ + {"X-CRC-16", models+ 9}, /* 173 */ + {"XFER", models+ 1}, /* 174 */ + {"XMODEM", models+ 18}, /* 175 */ + {"ZMODEM", models+ 18}, /* 176 */ + {NULL, NULL }, /* terminating entry */ }; -# define NALIASES 141 +# define NALIASES 177 # endif /* BMP_BIT */ #else /* PRESETS */ static const struct mpreset models[] = { - { 0UL, 0, 0, P_BE, 0, 0, 0, NULL }, /* terminating entry */ + { 0UL, 0, 0, P_BE | P_UNDFCL, 0, 0, 0, NULL }, /* terminating entry */ }; # define NPRESETS 0 diff --git a/client/reveng/reveng.h b/client/reveng/reveng.h index 08a7a6d1a..70f594072 100644 --- a/client/reveng/reveng.h +++ b/client/reveng/reveng.h @@ -1,5 +1,5 @@ /* reveng.h - * Greg Cook, 26/Jul/2018 + * Greg Cook, 21/Nov/2018 */ /* CRC RevEng: arbitrary-precision CRC calculator and algorithm finder @@ -93,7 +93,7 @@ /* Global definitions */ /* CRC RevEng version string */ -#define VERSION "1.5.3" +#define VERSION "1.6.0" /* bmpbit.c */ typedef BMP_T bmp_t; @@ -111,6 +111,19 @@ extern void setbmp(void); #define P_LTLBYT 64 #define P_DIRECT 128 +/* class flags */ +#define P_CLBIT0 256 +#define P_CLBIT1 512 +#define P_SOLID 1024 +#define P_CLMASK (P_SOLID | P_CLBIT1 | P_CLBIT0) + +#define P_UNDFCL 0 +#define P_UNCONF (P_CLBIT0) +#define P_THIRDP (P_CLBIT1) +#define P_ACADEM (P_CLBIT1 | P_CLBIT0) +#define P_CONFIR (P_SOLID | P_CLBIT0) +#define P_ATTEST (P_SOLID | P_CLBIT1) + /* default flags */ #define P_BE (P_RTJUST | P_MULXN) #define P_LE (P_REFIN | P_REFOUT | P_MULXN) @@ -187,7 +200,7 @@ extern void mrev(model_t *model); extern void mnovel(model_t *model); /* preset.c */ -#define M_OVERWR 256 +#define M_OVERWR 1 extern int mbynam(model_t *dest, const char *key); extern void mbynum(model_t *dest, int num); @@ -196,12 +209,12 @@ extern char *mnames(void); extern void mmatch(model_t *model, int flags); /* reveng.c */ -#define R_HAVEP 512 -#define R_HAVEI 1024 -#define R_HAVERI 2048 -#define R_HAVERO 4096 -#define R_HAVEX 8192 -#define R_HAVEQ 16384 +#define R_HAVEP 1 +#define R_HAVEI 2 +#define R_HAVERI 4 +#define R_HAVERO 8 +#define R_HAVEX 16 +#define R_HAVEQ 32 #define R_SPMASK 0x7FFFFFFUL diff --git a/client/scripting.c b/client/scripting.c index 762a9c470..3d3518ced 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -515,7 +515,7 @@ static int l_sha1(lua_State *L) { static int l_reveng_models(lua_State *L){ // This array needs to be adjusted if RevEng adds more crc-models. -#define NMODELS 103 +#define NMODELS 105 int count = 0; uint8_t in_width = luaL_checkunsigned(L, 1); From 0ddda8998e6e50dc617026250c44fa91738f3779 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 1 Jan 2019 10:15:27 +0100 Subject: [PATCH 038/320] chg: added info --- client/emv/emv_tags.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 81cee89f3..74a37aba6 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -292,6 +292,9 @@ static const struct emv_tag emv_tags[] = { { 0x9f6b, "Track 2 Data" }, { 0x9f6c, "Card Transaction Qualifiers (CTQ)", EMV_TAG_BITMASK, &EMV_CTQ }, { 0x9f6e, "Form Factor Indicator" }, + + { 0x9f7c, "Customer Exclusive Data (CED)"}, + { 0xa5 , "File Control Information (FCI) Proprietary Template" }, { 0xbf0c, "File Control Information (FCI) Issuer Discretionary Data" }, { 0xdf20, "Issuer Proprietary Bitmap (IPB)" }, From 75d0b0b06f11cb66581fb0c92f79bcca04cff952 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 1 Jan 2019 10:53:41 +0100 Subject: [PATCH 039/320] CHG: 'emv roca' - added selftest and textual layouts' DEL: removed unused old emv files --- client/cmdhfemv.c | 351 ----------------------------------- client/cmdhfemv.h | 45 ----- client/emv/cmdemv.c | 9 +- client/emv/emv_roca.c | 30 +-- client/emv/emv_roca.h | 2 +- client/emv/test/cryptotest.c | 7 +- 6 files changed, 22 insertions(+), 422 deletions(-) delete mode 100644 client/cmdhfemv.c delete mode 100644 client/cmdhfemv.h diff --git a/client/cmdhfemv.c b/client/cmdhfemv.c deleted file mode 100644 index ab9396a14..000000000 --- a/client/cmdhfemv.c +++ /dev/null @@ -1,351 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 Peter Fillmore -// 2017 iceman -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency EMV commands -//----------------------------------------------------------------------------- -#include "cmdhfemv.h" - -static int CmdHelp(const char *Cmd); - -int usage_hf_emv_test(void){ - PrintAndLogEx(NORMAL, "EMV test "); - PrintAndLogEx(NORMAL, "Usage: hf emv test [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv test"); - return 0; -} -int usage_hf_emv_readrecord(void){ - PrintAndLogEx(NORMAL, "Read a EMV record "); - PrintAndLogEx(NORMAL, "Usage: hf emv readrecord [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " : number of records"); - PrintAndLogEx(NORMAL, " : number of SFI records"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv readrecord 1 1"); - return 0; -} -int usage_hf_emv_clone(void){ - PrintAndLogEx(NORMAL, "Usage: hf emv clone [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " : number of records"); - PrintAndLogEx(NORMAL, " : number of SFI records"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv clone 10 10"); - return 0; -} -int usage_hf_emv_transaction(void){ - PrintAndLogEx(NORMAL, "Performs EMV reader transaction"); - PrintAndLogEx(NORMAL, "Usage: hf emv trans [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv trans"); - return 0; -} -int usage_hf_emv_getrnd(void){ - PrintAndLogEx(NORMAL, "retrieve the UN number from a terminal"); - PrintAndLogEx(NORMAL, "Usage: hf emv getrnd [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv getrnd"); - return 0; -} -int usage_hf_emv_eload(void){ - PrintAndLogEx(NORMAL, "set EMV tags in the device to use in a transaction"); - PrintAndLogEx(NORMAL, "Usage: hf emv eload [h] o "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " o : filename w/o '.bin'"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv eload o myfile"); - return 0; -} -int usage_hf_emv_dump(void){ - PrintAndLogEx(NORMAL, "Gets EMV contactless tag values."); - PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`"); - PrintAndLogEx(NORMAL, "Usage: hf emv dump [h] o "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " o : filename w/o '.bin' to dump bytes"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv dump"); - PrintAndLogEx(NORMAL, " hf emv dump o myfile"); - return 0; -} -int usage_hf_emv_sim(void){ - PrintAndLogEx(NORMAL, "Simulates a EMV contactless card"); - PrintAndLogEx(NORMAL, "Usage: hf emv sim [h]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf emv sim"); - return 0; -} - -int CmdHfEmvTest(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') return usage_hf_emv_test(); - - UsbCommand c = {CMD_EMV_TEST, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "Command execute time-out"); - return 1; - } - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk: %02x", isOK); - return 0; -} - -int CmdHfEmvReadRecord(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ((strlen(Cmd)<3) || cmdp == 'h' || cmdp == 'H') return usage_hf_emv_readrecord(); - - uint8_t record = param_get8(Cmd, 0); - uint8_t sfi = param_getchar(Cmd, 1); - if(record > 32){ - PrintAndLogEx(WARNING, "Record must be less than 32"); - return 1; - } - PrintAndLogEx(NORMAL, "--record no:%02x SFI:%02x ", record, sfi); - - UsbCommand c = {CMD_EMV_READ_RECORD, {record, sfi, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "Command execute timeout"); - return 1; - } - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - return 0; -} - -int CmdHfEmvClone(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ((strlen(Cmd)<3) || cmdp == 'h' || cmdp == 'H') return usage_hf_emv_clone(); - - uint8_t record = param_get8(Cmd, 0); - uint8_t sfi = param_get8(Cmd, 1); - if(record > 32){ - PrintAndLogEx(WARNING, "Record must be less than 32"); - return 1; - } - UsbCommand c = {CMD_EMV_CLONE, {sfi, record, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "Command execute timeout"); - return 1; - } - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - return 0; -} - -int CmdHfEmvTrans(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') return usage_hf_emv_transaction(); - - UsbCommand c = {CMD_EMV_TRANSACTION, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 5000)) { - PrintAndLogEx(WARNING, "Command execute time-out"); - return 1; - } - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk: %02x", isOK); - print_hex_break(resp.d.asBytes, 512, 32); - return 0; -} -//retrieve the UN number from a terminal -int CmdHfEmvGetrng(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') return usage_hf_emv_getrnd(); - UsbCommand c = {CMD_EMV_GET_RANDOM_NUM, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - return 0; -} -//Load a dumped EMV tag on to emulator memory -int CmdHfEmvELoad(const char *Cmd) { - FILE * f; - char filename[FILE_PATH_SIZE]; - char *fnameptr = filename; - int len; - bool errors = false; - uint8_t cmdp = 0; - - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_hf_emv_eload(); - case 'o': - case 'O': - len = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); - if (!len) - errors = true; - if (len > FILE_PATH_SIZE-5) - len = FILE_PATH_SIZE-5; - sprintf(fnameptr + len,".bin"); - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - //Validations - if (errors || cmdp == 0) return usage_hf_emv_eload(); - - // open file - f = fopen(filename,"r"); - if (!f) { - PrintAndLogEx(WARNING, "File %s not found or locked", filename); - return 1; - } - - char line[512]; - char *token; - uint16_t tag; - - UsbCommand c = {CMD_EMV_LOAD_VALUE, {0,0,0}}; - - // transfer to device - while (fgets(line, sizeof (line), f)) { - PrintAndLogEx(NORMAL, "LINE = %s\n", line); - - token = strtok(line, ":"); - tag = (uint16_t)strtol(token, NULL, 0); - token = strtok(NULL,""); - - c.arg[0] = tag; - memcpy(c.d.asBytes, token, strlen(token)); - - clearCommandBuffer(); - SendCommand(&c); - - PrintAndLogEx(NORMAL, "Loaded TAG = %04x\n", tag); - PrintAndLogEx(NORMAL, "Loaded VALUE = %s\n", token); - } - - fclose(f); - PrintAndLogEx(NORMAL, "loaded %s", filename); - //PrintAndLogEx(NORMAL, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename); - return 0; -} - -int CmdHfEmvDump(const char *Cmd){ - - bool errors = false; - uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_hf_emv_dump(); - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - //Validations - if (errors) return usage_hf_emv_dump(); - - UsbCommand c = {CMD_EMV_DUMP_CARD, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - PrintAndLogEx(WARNING, "Command execute time-out"); - return 1; - } - return 0; -} - -int CmdHfEmvSim(const char *Cmd) { - - bool errors = false; - uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_hf_emv_sim(); - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - //Validations - if (errors) return usage_hf_emv_sim(); - - UsbCommand c = {CMD_EMV_SIM, {0,0,0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "Command execute time-out"); - return 1; - } - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - return 0; -} - -int CmdHfEmvList(const char *Cmd) { - return CmdTraceList("7816"); -} - -static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"readrecord", CmdHfEmvReadRecord, 0, "EMV Read Record"}, - {"transaction", CmdHfEmvTrans, 0, "Perform EMV Transaction"}, - {"getrng", CmdHfEmvGetrng, 0, "get random number from terminal"}, - {"eload", CmdHfEmvELoad, 0, "load EMV tag into device"}, - {"dump", CmdHfEmvDump, 0, "dump EMV tag values"}, - {"sim", CmdHfEmvSim, 0, "simulate EMV tag"}, - {"clone", CmdHfEmvClone, 0, "clone an EMV tag"}, - {"list", CmdHfEmvList, 0, "[Deprecated] List ISO7816 history"}, - {"test", CmdHfEmvTest, 0, "Test Function"}, - {NULL, NULL, 0, NULL} -}; - -int CmdHFEmv(const char *Cmd) { - clearCommandBuffer(); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; -} \ No newline at end of file diff --git a/client/cmdhfemv.h b/client/cmdhfemv.h deleted file mode 100644 index 0b68a455c..000000000 --- a/client/cmdhfemv.h +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 Peter Fillmore -// 2017 iceman -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency EMV commands -//----------------------------------------------------------------------------- - -#ifndef CMDHFEMV_H__ -#define CMDHFEMV_H__ - -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" -#include "cmdmain.h" -#include "util.h" -#include "cmdhf.h" // "hf list" - -int CmdHFEmv(const char *Cmd); - -int CmdHfEmvTest(const char *Cmd); -int CmdHfEmvReadRecord(const char *Cmd); -int CmdHfEmvClone(const char *Cmd); -int CmdHfEmvTrans(const char *Cmd); -int CmdHfEmvGetrng(const char *Cmd); -int CmdHfEmvELoad(const char *Cmd); -int CmdHfEmvDump(const char *Cmd); -int CmdHfEmvSim(const char *Cmd); -int CmdHfEmvList(const char *Cmd); - -int usage_hf_emv_test(void); -int usage_hf_emv_readrecord(void); -int usage_hf_emv_clone(void); -int usage_hf_emv_transaction(void); -int usage_hf_emv_getrnd(void); -int usage_hf_emv_eload(void); -int usage_hf_emv_dump(void); -int usage_hf_emv_sim(void); - -#endif diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a443f6aad..396918d7e 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1456,7 +1456,6 @@ int CmdEMVScan(const char *cmd) { return 0; } - int CmdEMVList(const char *Cmd) { return CmdTraceList("7816"); } @@ -1476,10 +1475,13 @@ int CmdEMVRoca(const char *cmd) { CLIParserInit("emv roca", "Tries to extract public keys and run the ROCA test against them.\n", "Usage:\n" - "\temv roca -w -> select CONTACT card and run test\n\temv roca -> select CONTACTLESS card and run test\n"); + "\temv roca -w -> select --CONTACT-- card and run test\n" + "\temv roca -> select --CONTACTLESS-- card and run test\n" + ); void* argtable[] = { arg_param_begin, + arg_lit0("tT", "selftest", "self test"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; @@ -1487,6 +1489,9 @@ int CmdEMVRoca(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(1)) + return roca_self_test(); + + if (arg_get_lit(2)) channel = ECC_CONTACT; // select card diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c index a6738ae2f..6f90f11b5 100644 --- a/client/emv/emv_roca.c +++ b/client/emv/emv_roca.c @@ -138,11 +138,10 @@ cleanup: return ret; } -int roca_self_test( int verbose ) { +int roca_self_test(void) { int ret = 0; - if( verbose != 0 ) - printf( "\nROCA check vulnerability tests\n" ); + PrintAndLogEx(INFO, "ROCA check vulnerability tests" ); // positive uint8_t keyp[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\ @@ -150,16 +149,13 @@ int roca_self_test( int verbose ) { "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; - if( verbose != 0 ) - printf( " ROCA positive test: " ); if (emv_rocacheck(keyp, 64, false)) { - if( verbose != 0 ) - printf( "passed\n" ); - } else { - ret = 1; - if( verbose != 0 ) - printf( "failed\n" ); + PrintAndLogEx(SUCCESS, "Weak modulus [ %s]", _GREEN_(PASS) ); + } + else { + ret++; + PrintAndLogEx(FAILED, "Weak modulus [ %s]", _RED_(FAIL) ); } // negative @@ -168,18 +164,12 @@ int roca_self_test( int verbose ) { "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; - if( verbose != 0 ) - printf( " ROCA negative test: " ); - if (emv_rocacheck(keyn, 64, false)) { - ret = 1; - if( verbose != 0 ) - printf( "failed\n" ); + ret++; + PrintAndLogEx(FAILED, "Strong modulus [ %s]", _RED_(FAIL) ); } else { - if( verbose != 0 ) - printf( "passed\n" ); + PrintAndLogEx(SUCCESS, "Strong modulus [ %s]", _GREEN_(PASS) ); } - return ret; } diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h index 26d37d146..9e12e4256 100644 --- a/client/emv/emv_roca.h +++ b/client/emv/emv_roca.h @@ -32,7 +32,7 @@ #define ROCA_PRINTS_LENGTH 17 extern bool emv_rocacheck( const unsigned char *buf, size_t buflen, bool verbose ); -extern int roca_self_test( int verbose ); +extern int roca_self_test( void ); #endif diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index b0212a70b..4e8df1a25 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -91,14 +91,15 @@ int ExecuteCryptoTests(bool verbose) { res = exec_crypto_test(verbose); if (res) TestFail = true; - res = roca_self_test(verbose); + res = roca_self_test(); if (res) TestFail = true; PrintAndLog("\n--------------------------"); + if (TestFail) - PrintAndLog("Test(s) [ERROR]."); + PrintAndLogEx(FAILED, "\tTest(s) [ %s ]", _RED_(FAIL) ); else - PrintAndLog("Tests [OK]."); + PrintAndLogEx(SUCCESS, "\tTest(s) [ %s ]", _GREEN_(OK) ); return TestFail; } From 0fb0c35308366326b8897382da631a28f238fe23 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Jan 2019 18:01:40 +0100 Subject: [PATCH 040/320] CHG: 'mem load' - the possibility to upload default_iclass_keys.dic, default_keys.dic, default_pwd.dic to predefined flashmemory sections. These will be used in pwd / key checking algorithms on device. CHG: 'script run read_pwd_mem.lua' - script now can print those uploaded dictionary files. How to upload pm3 --> mem load f default_iclass_keys i pm3 --> mem load f default_keys m pm3 --> mem load f default_pwd t How to validate / view PM3 -->scr run read_pwd_mem -o 237568 -k 8 pm3 -->scr run read_pwd_mem -o 241664 -k 6 pm3 -->scr run read_pwd_mem -o 245760 -k 4 --- armsrc/appmain.c | 12 ++- armsrc/lfops.c | 2 +- client/cmdflashmem.c | 90 +++++++++++++++++++---- client/cmdflashmem.h | 7 ++ client/cmdhficlass.c | 7 +- client/loclass/fileutils.c | 66 +++++++++++++++++ client/loclass/fileutils.h | 17 ++++- client/scripts/read_pwd_mem.lua | 126 ++++++++++++++++++++++---------- include/common.h | 14 ++-- 9 files changed, 276 insertions(+), 65 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index eed443599..bf4bddef6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1285,10 +1285,20 @@ void UsbPacketReceived(uint8_t *packet, int len) { if (!FlashInit()) { break; } - + Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); + + if ( startidx == DEFAULT_T55XX_KEYS_OFFSET ) + Flash_Erase4k(3, 0xC); + else if (startidx == DEFAULT_MF_KEYS_OFFSET ) + Flash_Erase4k(3, 0xB); + else if (startidx == DEFAULT_ICLASS_KEYS_OFFSET) + Flash_Erase4k(3, 0xA); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + // inside 256b page? if ( (tmp & 0xFF) != 0) { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 0dac64bd1..e690714df 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -103,7 +103,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); - Flash_Erase4k(3, 0xD); + Flash_Erase4k(3, 0xD); res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); if ( res == T55XX_CONFIG_LEN && MF_DBGLEVEL > 1) { diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 2ff68bd3d..6361d48e3 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -50,13 +50,19 @@ int usage_flashmem_read(void){ } int usage_flashmem_load(void){ PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device"); - PrintAndLogEx(NORMAL, "Usage: mem load o f "); + PrintAndLogEx(NORMAL, "Usage: mem load o f m t i"); PrintAndLogEx(NORMAL, " o : offset in memory"); PrintAndLogEx(NORMAL, " f : file name"); + PrintAndLogEx(NORMAL, " m : upload 6 bytes keys (mifare key dictionary)"); + PrintAndLogEx(NORMAL, " i : upload 8 bytes keys (iClass key dictionary)"); + PrintAndLogEx(NORMAL, " t : upload 4 bytes keys (pwd dictionary)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0 PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024 + PrintAndLogEx(NORMAL, " mem load f default_keys m"); + PrintAndLogEx(NORMAL, " mem load f default_pwd t"); + PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i"); return 0; } int usage_flashmem_save(void){ @@ -154,7 +160,8 @@ int CmdFlashMemLoad(const char *Cmd){ uint32_t start_index = 0; char filename[FILE_PATH_SIZE] = {0}; bool errors = false; - uint8_t cmdp = 0; + uint8_t cmdp = 0; + Dictionary_t d = DICTIONARY_NONE; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -171,7 +178,19 @@ int CmdFlashMemLoad(const char *Cmd){ case 'o': start_index = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp += 2; - break; + break; + case 'm': + d = DICTIONARY_MIFARE; + cmdp++; + break; + case 't': + d = DICTIONARY_T55XX; + cmdp++; + break; + case 'i': + d = DICTIONARY_ICLASS; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -181,20 +200,61 @@ int CmdFlashMemLoad(const char *Cmd){ //Validations if (errors || cmdp == 0 ) return usage_flashmem_load(); - - uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); + size_t datalen = 0; - int res = loadFile(filename, "bin", data, &datalen); - //int res = loadFileEML( filename, "eml", data, &datalen); - if ( res ) { - free(data); - return 1; - } + uint16_t keycount = 0; + int res = 0; + uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); - if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogDevice(WARNING, "error, filesize is larger than available memory"); - free(data); - return 1; + switch (d) { + case DICTIONARY_MIFARE: + start_index = DEFAULT_MF_KEYS_OFFSET; + res = loadFileDICTIONARY(filename, "dic", data+2, &datalen, 6, &keycount ); + if ( res || !keycount) { + free(data); + return 1; + } + data[0] = (keycount >> 0) & 0xFF; + data[1] = (keycount >> 8) & 0xFF; + datalen += 2; + break; + case DICTIONARY_T55XX: + start_index = DEFAULT_T55XX_KEYS_OFFSET; + res = loadFileDICTIONARY(filename, "dic", data+2, &datalen, 4, &keycount ); + if ( res || !keycount) { + free(data); + return 1; + } + data[0] = (keycount >> 0) & 0xFF; + data[1] = (keycount >> 8) & 0xFF; + datalen += 2; + break; + case DICTIONARY_ICLASS: + start_index = DEFAULT_ICLASS_KEYS_OFFSET; + res = loadFileDICTIONARY(filename, "dic", data+2, &datalen, 8, &keycount ); + if ( res || !keycount) { + free(data); + return 1; + } + data[0] = (keycount >> 0) & 0xFF; + data[1] = (keycount >> 8) & 0xFF; + datalen += 2; + break; + default: + + res = loadFile(filename, "bin", data, &datalen); + //int res = loadFileEML( filename, "eml", data, &datalen); + if ( res ) { + free(data); + return 1; + } + + if (datalen > FLASH_MEM_MAX_SIZE) { + PrintAndLogDevice(WARNING, "error, filesize is larger than available memory"); + free(data); + return 1; + } + break; } data = realloc(data, datalen); diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 843c17d6f..9f71a4ce0 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -24,6 +24,13 @@ #include "loclass/fileutils.h" //saveFile #include "comms.h" //getfromdevice +typedef enum { + DICTIONARY_NONE = 0, + DICTIONARY_MIFARE, + DICTIONARY_T55XX, + DICTIONARY_ICLASS +} Dictionary_t; + extern int CmdFlashMem(const char *Cmd); extern int CmdFlashMemRead(const char* cmd); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 6cc2aa191..0e62afaf6 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2316,7 +2316,8 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) { while (fgetc(f) != '\n' && !feof(f)) {}; //The line start with # is comment, skip - if( buf[0]=='#' ) continue; + if( buf[0]=='#' ) + continue; // doesn't this only test first char only? if (!isxdigit(buf[0])){ @@ -2329,7 +2330,7 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) { p = realloc(*keys, 8 * (keyitems += 64)); if (!p) { - PrintAndLogEx(NORMAL, _RED_([!])" cannot allocate memory for default keys"); + PrintAndLogEx(ERR, "cannot allocate memory for default keys"); fclose(f); return 2; } @@ -2341,7 +2342,7 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) { memset(buf, 0, sizeof(buf)); } fclose(f); - PrintAndLogEx(NORMAL, _BLUE_([+]) "Loaded " _GREEN_(%2d) " keys from %s", *keycnt, filename); + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_(%2d) " keys from %s", *keycnt, filename); return 0; } diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index b099d6a35..5bac3d2cd 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -453,6 +453,72 @@ out: return retval; } +int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data, size_t* datalen, uint8_t keylen, uint16_t* keycnt ) { + + if ( preferredName == NULL ) return 1; + if ( suffix == NULL ) return 1; + + // t5577 == 4bytes + // mifare == 6 bytes + // iclass == 8 bytes + // default to 6 bytes. + if (keylen != 4 && keylen != 6 && keylen != 8) { + keylen = 6; + } + + // double up since its chars + keylen <<= 1; + + char line[255]; + + size_t counter = 0; + int retval = 0; + int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); + char * fileName = calloc(size, sizeof(char)); + sprintf(fileName,"%s.%s", preferredName, suffix); + + FILE *f = fopen(fileName, "r"); + if ( !f ) { + PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + retval = 1; + goto out; + } + + // read file + while ( fgets(line, sizeof(line), f) ) { + + // add null terminator + line[keylen] = 0; + + // smaller keys than expected is skipped + if (strlen(line) < keylen) + continue; + + + // The line start with # is comment, skip + if( line[0] == '#' ) + continue; + + if (!isxdigit(line[0])){ + PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_(%2d) "HEX symbols", line, keylen); + continue; + } + + uint64_t key = strtoull(line, NULL, 16); + + num_to_bytes(key, keylen >> 1, data + counter); + (*keycnt)++; + memset(line, 0, sizeof(line)); + counter += (keylen >> 1); + } + fclose(f); + PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file %s", *keycnt, fileName); + *datalen = counter; +out: + free(fileName); + return retval; +} + #else //if we're on ARM #endif diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index b73f5fc30..3fc781d2e 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -124,7 +124,7 @@ extern int loadFile(const char *preferredName, const char *suffix, void* data, s */ extern int loadFileEML(const char *preferredName, const char *suffix, void* data, size_t* datalen); -/** STUB +/** * @brief Utility function to load data from a JSON textfile. This method takes a preferred name. * E.g. dumpdata-15.json * @@ -137,6 +137,21 @@ extern int loadFileEML(const char *preferredName, const char *suffix, void* data */ extern int loadFileJSON(const char *preferredName, const char *suffix, void* data, size_t maxdatalen, size_t* datalen); + +/** + * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. + * E.g. default_keys.dic + * + * @param preferredName + * @param suffix the file suffix. Leave out the ".". + * @param data The data array to store the loaded bytes from file + * @param maxdatalen maximum size of data array in bytes + * @param datalen the number of bytes loaded from file + * @param keylen the number of bytes a key per row is + * @return 0 for ok, 1 for failz +*/ +extern int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data, size_t* datalen, uint8_t keylen, uint16_t* keycnt ); + #define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args) #else diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index fbe4d0459..772927c0c 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -1,23 +1,29 @@ local getopt = require('getopt') local bin = require('bin') +copyright = 'Copyright (c) 2018 Bogito. All rights reserved.' author = "Bogito" -version = 'v1.0.0' -desc =[[ +version = 'v1.0.1' +desc = +[[ This script will read the flash memory of RDV4 and print the stored passwords. It was meant to be used as a help tool after using the BogRun standalone mode. + +(Iceman) script adapted to read and print keys in the default dictionary flashmemory sections. ]] -usage = [[ +usage = +[[ Usage: - script run read_pwd_mem -h -o -l + script run read_pwd_mem -h -o -l -k Arguments: - -h : this help - -o : Memory offset. Default is 0. - -l : Length in bytes. Default is 256. + -h : this help + -o : memory offset, default is 0 + -l : length in bytes, default is 256 + -k : key length in bytes <4|6|8> , default is 4 ]] -example =[[ -Examples: +example = +[[ -- This will scan the first 256 bytes of flash memory for stored passwords script run read_pwd_mem @@ -26,61 +32,103 @@ Examples: -- This will scan 32 bytes of flash memory at offset 64 for stored passwords script run read_pwd_mem -o 64 -l 32 + + -- This will print found + script run read_pwd_mem -o 241664 -k 6 ]] - +--- +-- This is only meant to be used when errors occur +local function oops(err) + print("ERROR: ", err) + return nil, err +end +--- -- Usage help local function help() + print(copyright) + print(version) print(desc) print(usage) + print('Example usage:') print(example) end - +--- +-- The main entry point local function main(args) - local data, err, quadlet, pwdcnt + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + + local data, err, quadlet + local cnt = 0 local offset = 0 local length = 256 + local keylength = 4 + local usedkey = false - -- Read the parameters - for o, a in getopt.getopt(args, 'ho:l:') do + for o, a in getopt.getopt(args, 'ho:l:k:') do + + -- help if o == "h" then return help() end + + -- offset if o == "o" then offset = tonumber(a) end + + -- num of bytes to read if o == "l" then length = tonumber(a) end + + -- keylength + if o == "k" then keylength = tonumber(a); usedkey = true end end if length < 0 or length > 256 then - return print('Error: Length is not valid. Must be less than 256') + return oops('Error: Length is not valid. Must be less than 256') end - if ((offset < 0) or (offset % 4 ~= 0)) then - return print('Error: Offset is not valid. Mod-4 values are only allowed.') + if (offset < 0) or (offset % 4 ~= 0) then + return oops('Error: Offset is not valid. Mod-4 values are only allowed.') end - print('Offset: ' .. offset) - print('Length: ' .. length) - print() + print('Memory offset', offset) + print('Length ', length) + print('Key length ', keylength) + print( string.rep('--',20) ) - data, err = core.GetFromFlashMem(offset, length) + if usedkey then length = 4096 end + + data, err = core.GetFromFlashMem(offset, length) + if err then return oops(err) end - if err then - print(err) - return + if usedkey then + + _, keys, s = bin.unpack('SH'..length-2, data) + if keys == 0xFFFF then return "No keys found in section" end + + local kl = keylength * 2 + for i = 1, keys do + + key = string.sub(s, (i - 1) * kl + 1, i * kl ) + print(string.format("[%02d] %s",i, key)) + end + print( string.rep('--',20) ) + print( ('[+] found %d passwords'):format(keys)) + else + + _, s = bin.unpack('H'..length, data) + + local cnt = 0, i + for i = 1, (length/keylength) do + + key = string.sub(s, (i-1)*8+1, i*8) + if key == "FFFFFFFF" then break end + print(string.format("[%02d] %s",i, key)) + cnt = cnt + 1 + end + print( string.rep('--',20) ) + print( ('[+] found %d passwords'):format(cnt)) end - - local count, s = bin.unpack('H'..length, data) - - pwdcnt = 0 - for i = 1,(length/4),1 - do - quadlet = string.sub(s, (i-1)*8+1, i*8) - if quadlet == "FFFFFFFF" then break end - print(string.format("[%02d]",i) .. ' ' .. quadlet) - pwdcnt = pwdcnt + 1 - - end - print() - print('Found passwords: ' .. pwdcnt) - + print( string.rep('--',20) ) end main(args) diff --git a/include/common.h b/include/common.h index 90394448c..d3da792aa 100644 --- a/include/common.h +++ b/include/common.h @@ -90,13 +90,17 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; #ifndef T55XX_CONFIG_OFFSET # define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000) #endif - - #ifndef DEFAULT_MF_KEYS_OFFSET - # define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) + + #ifndef DEFAULT_T55XX_KEYS_OFFSET + # define DEFAULT_T55XX_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) #endif - #ifndef DEFAULT_LF_KEYS_OFFSET - # define DEFAULT_LF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) + #ifndef DEFAULT_MF_KEYS_OFFSET + # define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) + #endif + + #ifndef DEFAULT_ICLASS_KEYS_OFFSET + # define DEFAULT_ICLASS_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x5000) #endif #endif From 6e281a08ed93e664f196aea49f1d922ee2fb5b83 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Jan 2019 11:52:13 +0100 Subject: [PATCH 041/320] CHG: 'hf mf fchk' - speed improvments by tweaking implementation. CHG: 'hf mf fchk' - can use dictionary from flashmem if one is uploaded. (faster) --- armsrc/mifarecmd.c | 128 +++++++++++++++++++++++++++++++++----------- client/cmdhfmf.c | 96 +++++++++++++++++++-------------- client/mifarehost.c | 4 +- client/mifarehost.h | 2 +- 4 files changed, 156 insertions(+), 74 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 7d39b3f29..3e1967b4e 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -17,7 +17,7 @@ #include #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT -# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 //848 // card times out 1ms after wrong authentication (according to NXP documentation) +# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) #endif #ifndef HARDNESTED_PRE_AUTHENTICATION_LEADTIME # define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication @@ -1122,7 +1122,6 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { } void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { - uint8_t status; for (uint8_t s = 0; s < *sectorcnt; s++) { // skip already found A keys @@ -1130,8 +1129,7 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui continue; c->block = FirstBlockOfSector( s ); - status = chkKey( c ); - if ( status == 0 ) { + if ( chkKey( c ) == 0 ) { num_to_bytes(c->key, 6, k_sector[s].keyA); found[(s*2)] = 1; ++*foundkeys; @@ -1142,7 +1140,6 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui } void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { - uint8_t status; for (uint8_t s = 0; s < *sectorcnt; s++) { // skip already found B keys @@ -1150,8 +1147,7 @@ void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui continue; c->block = FirstBlockOfSector( s ); - status = chkKey( c ); - if ( status == 0 ) { + if ( chkKey( c ) == 0 ) { num_to_bytes(c->key, 6, k_sector[s].keyB); found[(s*2)+1] = 1; ++*foundkeys; @@ -1167,7 +1163,12 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found // read Block B, if A is found. for (uint8_t s = 0; s < *sectorcnt; ++s) { + + if ( found[(s*2)] && found[(s*2)+1] ) + continue; + c->block = (FirstBlockOfSector( s ) + NumBlocksPerSector( s ) - 1); + // A but not B if ( found[(s*2)] && !found[(s*2)+1] ){ c->key = bytes_to_num(k_sector[s].keyA, 6); @@ -1187,6 +1188,9 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found } } } + + + // get Chunks of keys, to test authentication against card. // arg0 = antal sectorer // arg0 = first time @@ -1200,7 +1204,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da uint8_t firstchunk = (arg0 >> 8) & 0xF; uint8_t lastchunk = (arg0 >> 12) & 0xF; uint8_t strategy = arg1 & 0xFF; - uint8_t keyCount = arg2 & 0xFF; + uint8_t use_flashmem = (arg1 >> 8) & 0xFF; + uint16_t keyCount = arg2 & 0xFF; uint8_t status = 0; struct Crypto1State mpcs = {0, 0}; @@ -1217,33 +1222,57 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da static uint8_t found[80]; static uint8_t *uid; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); +#ifdef WITH_FLASH + if ( use_flashmem ) { + BigBuf_free(); + uint16_t isok = 0; + uint8_t size[2] = {0x00, 0x00}; + isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET, size, 2); + if ( isok != 2 ) + goto OUT; + + keyCount = size[1] << 8 | size[0]; + + if ( keyCount == 0 && keyCount == 0xFFFF) + goto OUT; + + datain = BigBuf_malloc( keyCount * 6); + if (datain == NULL ) + goto OUT; + + isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET+2, datain, keyCount * 6); + if ( isok != keyCount * 6 ) + goto OUT; + + } +#endif if (uid == NULL || firstchunk) { uid = BigBuf_malloc(10); - if (uid == NULL ) { - if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys: uid malloc failed"); + if (uid == NULL ) goto OUT; - } } + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LEDsoff(); LED_A_ON(); if ( firstchunk ) { - + clear_trace(); set_tracing(false); memset(k_sector, 0x00, 480+10); memset(found, 0x00, sizeof(found)); foundkeys = 0; - + iso14a_card_select_t card_info; if ( !iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (ALL)"); + if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys_fast: Can't select card (ALL)"); goto OUT; } + switch (card_info.uidlen) { case 4 : cascade_levels = 1; break; case 7 : cascade_levels = 2; break; @@ -1262,19 +1291,23 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da chk_data.block = 0; // keychunk loop - depth first one sector. - if ( strategy == 1 ) { + if ( strategy == 1 || use_flashmem) { uint8_t newfound = foundkeys; + uint16_t lastpos = 0; + uint16_t s_point = 0; // Sector main loop // keep track of how many sectors on card. for (uint8_t s = 0; s < sectorcnt; ++s) { - if ( found[(s*2)] && found[(s*2)+1] ) + if ( found[(s*2)] && found[(s*2)+1] ) continue; - for (uint8_t i = 0; i < keyCount; ++i) { - + for (uint16_t i = s_point; i < keyCount; ++i) { + + //if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point); + // Allow button press / usb cmd to interrupt device if (BUTTON_PRESS() && !usb_poll_validate_length()) { goto OUT; @@ -1292,8 +1325,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da // new key chk_data.key = bytes_to_num(datain + i * 6, 6); - // assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector - // skip already found A keys if( !found[(s*2)] ) { chk_data.keyType = 0; @@ -1303,12 +1334,26 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da found[(s*2)] = 1; ++foundkeys; - chkKey_scanA(&chk_data, k_sector, found, §orcnt, &foundkeys); + chkKey_scanA(&chk_data, k_sector, found, §orcnt, &foundkeys); // read Block B, if A is found. chkKey_loopBonly( &chk_data, k_sector, found, §orcnt, &foundkeys); + chk_data.keyType = 1; + chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); + + chk_data.keyType = 0; chk_data.block = FirstBlockOfSector( s ); + + if ( use_flashmem ) { + if ( lastpos != i && lastpos != 0) { + if ( i - lastpos < 0xF) { + s_point = i & 0xFFF0; + } + } else { + lastpos = i; + } + } } } @@ -1322,25 +1367,46 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da ++foundkeys; chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); + + if ( use_flashmem ) { + if ( lastpos != i && lastpos != 0) { + + if ( i - lastpos < 0xF) + s_point = i & 0xFFF0; + } else { + lastpos = i; + } + } } } - + + if ( found[(s*2)] && found[(s*2)+1] ) + break; + } // end keys test loop - depth first // assume1. if no keys found in first sector, get next keychunk from client - if ( newfound-foundkeys == 0 ) + if ( !use_flashmem && (newfound-foundkeys == 0) ) goto OUT; } // end loop - sector } // end strategy 1 + + if ( foundkeys == allkeys ) + goto OUT; - if ( strategy == 2 ) { + if ( strategy == 2 || use_flashmem ) { + // Keychunk loop - for (uint8_t i = 0; i < keyCount; i++) { - + for (uint16_t i = 0; i < keyCount; i++) { + // Allow button press / usb cmd to interrupt device if (BUTTON_PRESS() && !usb_poll_validate_length()) break; + // found all keys? + if ( foundkeys == allkeys ) + goto OUT; + WDT_HIT(); // new key @@ -1349,7 +1415,9 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da // Sector main loop // keep track of how many sectors on card. for (uint8_t s = 0; s < sectorcnt; ++s) { - + + if ( found[(s*2)] && found[(s*2)+1] ) continue; + // found all keys? if ( foundkeys == allkeys ) goto OUT; @@ -1387,8 +1455,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); } } - - } // end loop sectors } // end loop keys } // end loop strategy 2 @@ -1416,7 +1482,7 @@ OUT: set_tracing(false); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - BigBuf_free(); BigBuf_Clear_ext(false); + BigBuf_free(); BigBuf_Clear_ext(false); } else { // partial/none keys found cmd_send(CMD_ACK, foundkeys, 0, 0, 0, 0); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 1bfbf10eb..33e1c6f66 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -170,7 +170,7 @@ int usage_hf14_chk(void){ } int usage_hf14_chk_fast(void){ PrintAndLogEx(NORMAL, "This is a improved checkkeys method speedwise. It checks Mifare Classic tags sector keys against a dictionary file with keys"); - PrintAndLogEx(NORMAL, "Usage: hf mf fchk [h] [t|d] [] []"); + PrintAndLogEx(NORMAL, "Usage: hf mf fchk [h] [t|d|f] [] []"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " all sectors based on card memory, other values than below defaults to 1k"); @@ -179,12 +179,16 @@ int usage_hf14_chk_fast(void){ PrintAndLogEx(NORMAL, " 2 - 2K"); PrintAndLogEx(NORMAL, " 4 - 4K"); PrintAndLogEx(NORMAL, " d write keys to binary file"); - PrintAndLogEx(NORMAL, " t write keys to emulator memory\n"); + PrintAndLogEx(NORMAL, " t write keys to emulator memory"); + PrintAndLogEx(NORMAL, " m use dictionary from flashmemory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab keys.dic -- target 1K using key 1234567890ab, using dictionary file"); PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); +#ifdef WITH_FLASH + PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); +#endif return 0; } int usage_hf14_keybrute(void){ @@ -1136,7 +1140,7 @@ int CmdHF14AMfNested(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); - res = mfCheckKeys_fast( SectorsCnt, true, true, 1, MIFARE_DEFAULTKEYS_SIZE + 1, keyBlock, e_sector); + res = mfCheckKeys_fast( SectorsCnt, true, true, 1, MIFARE_DEFAULTKEYS_SIZE + 1, keyBlock, e_sector, false); uint64_t t2 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", MIFARE_DEFAULTKEYS_SIZE, (float)t2/1000.0 ); @@ -1167,7 +1171,7 @@ int CmdHF14AMfNested(const char *Cmd) { e_sector[sectorNo].foundKey[trgKeyType] = 1; e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6); - res = mfCheckKeys_fast( SectorsCnt, true, true, 2, 1, keyBlock, e_sector); + res = mfCheckKeys_fast( SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); continue; default : PrintAndLogEx(WARNING, "unknown Error.\n"); @@ -1467,8 +1471,8 @@ void shuffle( uint8_t *array, uint16_t len) { int CmdHF14AMfChk_fast(const char *Cmd) { char ctmp = 0x00; - ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_chk_fast(); + ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_chk_fast(); FILE * f; char filename[FILE_PATH_SIZE]={0}; @@ -1481,6 +1485,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) { int clen = 0; int transferToEml = 0, createDumpFile = 0; uint32_t keyitems = MIFARE_DEFAULTKEYS_SIZE; + bool use_flashmemory = false; sector_t *e_sector = NULL; @@ -1501,7 +1506,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) { for (i = 1; param_getchar(Cmd, i); i++) { - ctmp = param_getchar(Cmd, i); + ctmp = tolower(param_getchar(Cmd, i)); clen = param_getlength(Cmd, i); if (clen == 12) { @@ -1523,8 +1528,11 @@ int CmdHF14AMfChk_fast(const char *Cmd) { PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) ); keycnt++; } else if ( clen == 1) { - if (ctmp == 't' || ctmp == 'T') { transferToEml = 1; continue; } - if (ctmp == 'd' || ctmp == 'D') { createDumpFile = 1; continue; } + if (ctmp == 't' ) { transferToEml = 1; continue; } + if (ctmp == 'd' ) { createDumpFile = 1; continue; } +#ifdef WITH_FLASH + if (ctmp == 'm' ) { use_flashmemory = true; continue; } +#endif } else { // May be a dic file if ( param_getstr(Cmd, i, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) { @@ -1574,7 +1582,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) { } } - if (keycnt == 0) { + if (keycnt == 0 && !use_flashmemory) { PrintAndLogEx(SUCCESS, "No key specified, trying default keys"); for (;keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, @@ -1594,37 +1602,45 @@ int CmdHF14AMfChk_fast(const char *Cmd) { // time uint64_t t1 = msclock(); - - // strategys. 1= deep first on sector 0 AB, 2= width first on all sectors - for (uint8_t strategy = 1; strategy < 3; strategy++) { - PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); - // main keychunk loop - for (uint32_t i = 0; i < keycnt; i += chunksize) { - - if (ukbhit()) { - int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); - goto out; - } - - uint32_t size = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; - - // last chunk? - if ( size == keycnt - i) - lastChunk = true; - - int res = mfCheckKeys_fast( sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector); - if ( firstChunk ) - firstChunk = false; - - // all keys, aborted - if ( res == 0 || res == 2 ) - goto out; - } // end chunks of keys - firstChunk = true; - lastChunk = false; - } // end strategy + if ( use_flashmemory ) { + mfCheckKeys_fast( sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory); + } else { + + // strategys. 1= deep first on sector 0 AB, 2= width first on all sectors + for (uint8_t strategy = 1; strategy < 3; strategy++) { + PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); + + + + // main keychunk loop + for (uint32_t i = 0; i < keycnt; i += chunksize) { + + if (ukbhit()) { + int gc = getchar(); (void)gc; + PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + goto out; + } + + uint32_t size = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; + + // last chunk? + if ( size == keycnt - i) + lastChunk = true; + + int res = mfCheckKeys_fast( sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); + + if ( firstChunk ) + firstChunk = false; + + // all keys, aborted + if ( res == 0 || res == 2 ) + goto out; + } // end chunks of keys + firstChunk = true; + lastChunk = false; + } // end strategy + } out: t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0)); diff --git a/client/mifarehost.c b/client/mifarehost.c index fe2495938..2859fc207 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -138,13 +138,13 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc // 1 == // 2 == Time-out, aborting int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, - uint32_t size, uint8_t *keyBlock, sector_t *e_sector) { + uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory) { uint64_t t2 = msclock(); uint32_t timeout = 0; // send keychunk - UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (sectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), strategy, size}}; + UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (sectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), ((use_flashmemory << 8) | strategy), size}}; memcpy(c.d.asBytes, keyBlock, 6 * size); clearCommandBuffer(); SendCommand(&c); diff --git a/client/mifarehost.h b/client/mifarehost.h index 65500ded8..8f0f3f3bf 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -73,7 +73,7 @@ extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key); extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate); extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key); extern int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, - uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector); + uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); extern int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey); From e3f4ef498fcf30d904f46e984cf4f2c077dd6cfe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Jan 2019 12:11:49 +0100 Subject: [PATCH 042/320] CHG: 'hf mf fchk' - textual --- client/cmdhfmf.c | 5 ++--- client/mifarehost.c | 2 +- client/scripts/calypso.lua | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 33e1c6f66..d92b2a1d4 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1604,15 +1604,14 @@ int CmdHF14AMfChk_fast(const char *Cmd) { uint64_t t1 = msclock(); if ( use_flashmemory ) { - mfCheckKeys_fast( sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory); + PrintAndLogEx(SUCCESS, "Using dictionary in flash memory"); + mfCheckKeys_fast( sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory); } else { // strategys. 1= deep first on sector 0 AB, 2= width first on all sectors for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(SUCCESS, "Running strategy %u", strategy); - - // main keychunk loop for (uint32_t i = 0; i < keycnt; i += chunksize) { diff --git a/client/mifarehost.c b/client/mifarehost.c index 2859fc207..0f37f8a8b 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -166,7 +166,7 @@ int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // time to convert the returned data. uint8_t curr_keys = resp.arg[0]; - PrintAndLogEx(NORMAL, "\n[-] Chunk: %.1fs | found %u/%u keys (%u)", (float)(t2/1000.0), curr_keys, (sectorsCnt<<1), size); + PrintAndLogEx(SUCCESS, "\nChunk: %.1fs | found %u/%u keys (%u)", (float)(t2/1000.0), curr_keys, (sectorsCnt<<1), size); // all keys? if ( curr_keys == sectorsCnt*2 || lastChunk ) { diff --git a/client/scripts/calypso.lua b/client/scripts/calypso.lua index ad74c8183..ce90a25fd 100644 --- a/client/scripts/calypso.lua +++ b/client/scripts/calypso.lua @@ -68,9 +68,9 @@ end --- -- This is only meant to be used when errors occur local function oops(err) - print("ERROR: ",err) + print("ERROR: ", err) calypso_switch_off_field() - return nil,err + return nil, err end --- -- Usage help From 0da07fe81c2495125a224eddf339a9c522319467 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 2 Jan 2019 19:31:06 +0200 Subject: [PATCH 043/320] get SFI records --- client/emv/emvcore.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index b582792ac..8b774eaf0 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -335,6 +335,8 @@ int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; + uint8_t sfidata[APDU_RES_LEN] = {0}; + size_t sfidatalen = 0; uint16_t sw = 0; int res; @@ -342,9 +344,47 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO res = EMVSelectPSE(channel, ActivateField, true, PSENum, data, sizeof(data), &datalen, &sw); if (!res){ + if (sw != 0x9000) { + PrintAndLogEx(FAILED, "Select PSE error. APDU error: %04x.", sw); + return 1; + } + struct tlvdb *t = NULL; t = tlvdb_parse_multi(data, datalen); if (t) { + struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0x88, 0x00}); + if (tsfi) { + const struct tlv *tsfi_tlv = tlvdb_get_tlv(tsfi); + uint8_t sfin = tsfi_tlv->value[0]; + PrintAndLogEx(INFO, "* PPSE get SFI: 0x%02x.", sfin); + + for (uint8_t ui = 0x01; ui <= 0x10; ui++) { + PrintAndLogEx(INFO, "* * Get SFI: 0x%02x. num: 0x%02x", sfin, ui); + res = EMVReadRecord(channel, true, sfin, ui, sfidata, sizeof(sfidata), &sfidatalen, &sw, NULL); + + // end of records + if (sw == 0x6a83) { + PrintAndLogEx(INFO, "* * PPSE get SFI. End of records."); + break; + } + + // here must bee an error catch! + if (sw != 0x9000) { + PrintAndLogEx(FAILED, "PPSE get Error. APDU error: %04x.", sw); + break; + } + + if (decodeTLV){ + TLVPrintFromBuffer(sfidata, sfidatalen); + } + + } + + + } + + + int retrycnt = 0; struct tlvdb *ttmp = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0xbf0c, 0x61, 0x00}); if (!ttmp) From a5f8454168600d638354ccbe19ff75f599060777 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 3 Jan 2019 13:41:28 +0200 Subject: [PATCH 044/320] added pse sfi files get --- client/emv/emvcore.c | 84 +++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 8b774eaf0..bc2fa1a1a 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -332,11 +332,38 @@ int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO return res; } +int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { + int retrycnt = 0; + int res = 0; + do { + res = EMVSelect(channel, false, true, AID, AIDLen, Result, MaxResultLen, ResultLen, sw, tlv); + + // retry if error and not returned sw error + if (res && res != 5) { + if (++retrycnt < 3){ + continue; + } else { + // card select error, proxmark error + if (res == 1) { + PrintAndLogEx(WARNING, "Exit..."); + return 1; + } + + retrycnt = 0; + PrintAndLogEx(NORMAL, "Retry failed [%s]. Skiped...", sprint_hex_inrow(AID, AIDLen)); + return res; + } + } + } while (res && res != 5); + + return res; +} + int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; - uint8_t sfidata[APDU_RES_LEN] = {0}; - size_t sfidatalen = 0; + uint8_t sfidata[0x11][APDU_RES_LEN] = {0}; + size_t sfidatalen[0x11] = {0}; uint16_t sw = 0; int res; @@ -360,24 +387,45 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO for (uint8_t ui = 0x01; ui <= 0x10; ui++) { PrintAndLogEx(INFO, "* * Get SFI: 0x%02x. num: 0x%02x", sfin, ui); - res = EMVReadRecord(channel, true, sfin, ui, sfidata, sizeof(sfidata), &sfidatalen, &sw, NULL); + res = EMVReadRecord(channel, true, sfin, ui, sfidata[ui], APDU_RES_LEN, &sfidatalen[ui], &sw, NULL); // end of records if (sw == 0x6a83) { + sfidatalen[ui] = 0; PrintAndLogEx(INFO, "* * PPSE get SFI. End of records."); break; } - // here must bee an error catch! + // error catch! if (sw != 0x9000) { + sfidatalen[ui] = 0; PrintAndLogEx(FAILED, "PPSE get Error. APDU error: %04x.", sw); break; } if (decodeTLV){ - TLVPrintFromBuffer(sfidata, sfidatalen); + TLVPrintFromBuffer(sfidata[ui], sfidatalen[ui]); + } + } + + for (uint8_t ui = 0x01; ui <= 0x10; ui++) { + if (sfidatalen[ui]) { + struct tlvdb *tsfi = NULL; + tsfi = tlvdb_parse_multi(sfidata[ui], sfidatalen[ui]); + if (tsfi) { + struct tlvdb *tsfitmp = tlvdb_find_path(tsfi, (tlv_tag_t[]){0x70, 0x61, 0x00}); + if (!tsfitmp) { + PrintAndLogEx(FAILED, "SFI 0x%02d don't have records.", sfidatalen[ui]); + continue; + } + + // todo: check + PrintAndLogEx(INFO, "OK SFI 0x%02d.", sfidatalen[ui]); + + + } + tlvdb_free(tsfi); } - } @@ -385,7 +433,6 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO - int retrycnt = 0; struct tlvdb *ttmp = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0xbf0c, 0x61, 0x00}); if (!ttmp) PrintAndLogEx(FAILED, "PPSE don't have records."); @@ -393,28 +440,17 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO while (ttmp) { const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x4f, NULL); if (tgAID) { - res = EMVSelect(channel, false, true, (uint8_t *)tgAID->value, tgAID->len, data, sizeof(data), &datalen, &sw, tlv); + res = EMVSelectWithRetry(channel, false, true, (uint8_t *)tgAID->value, tgAID->len, data, sizeof(data), &datalen, &sw, tlv); - // retry if error and not returned sw error - if (res && res != 5) { - if (++retrycnt < 3){ - continue; - } else { - // card select error, proxmark error - if (res == 1) { - PrintAndLogEx(WARNING, "Exit..."); - return 1; - } - - retrycnt = 0; - PrintAndLogEx(NORMAL, "Retry failed [%s]. Skiped...", sprint_hex_inrow(tgAID->value, tgAID->len)); - } - + // if returned sw error + if (res == 5) { // next element ttmp = tlvdb_find_next(ttmp, 0x61); continue; } - retrycnt = 0; + + if (res) + break; // all is ok if (decodeTLV){ From 723298d00cb2628e3f70375e489c7acb5ba59d12 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 3 Jan 2019 19:42:40 +0200 Subject: [PATCH 045/320] added new tlv function --- client/emv/tlv.c | 38 ++++++++++++++++++++++++++++++++++++++ client/emv/tlv.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 35bdb5d4c..a41d98c95 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -25,6 +25,7 @@ #include #include #include +#include #define TLV_TAG_CLASS_MASK 0xc0 #define TLV_TAG_COMPLEX 0x20 @@ -534,3 +535,40 @@ struct tlvdb *tlvdb_elm_get_parent(struct tlvdb *tlvdb) { return tlvdb->parent; } + +bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) +{ + *value = 0; + if (etlv) + { + if (etlv->len == 0) + return true; + + if (etlv->len == 1) + { + *value = etlv->value[0]; + return true; + } + } + return false; +} + +bool tlv_get_int(const struct tlv *etlv, int *value) +{ + *value = 0; + if (etlv) + { + if (etlv->len == 0) + return true; + + if (etlv->len <= 4) + { + for (int i = 0; i < etlv->len; i++) + { + *value += etlv->value[i] * pow(0x100, i); + } + return true; + } + } + return false; +} diff --git a/client/emv/tlv.h b/client/emv/tlv.h index b25b51de2..e3c7c97fa 100644 --- a/client/emv/tlv.h +++ b/client/emv/tlv.h @@ -61,4 +61,7 @@ unsigned char *tlv_encode(const struct tlv *tlv, size_t *len); bool tlv_is_constructed(const struct tlv *tlv); bool tlv_equal(const struct tlv *a, const struct tlv *b); +bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value); +bool tlv_get_int(const struct tlv *etlv, int *value); + #endif From 00d4393af49a5d9a283ae53eaf40545e124adb7e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 3 Jan 2019 19:43:01 +0200 Subject: [PATCH 046/320] tlv_get_uint8 --- client/emv/emvcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index bc2fa1a1a..80affb6c1 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -381,8 +381,8 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO if (t) { struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0x88, 0x00}); if (tsfi) { - const struct tlv *tsfi_tlv = tlvdb_get_tlv(tsfi); - uint8_t sfin = tsfi_tlv->value[0]; + uint8_t sfin = 0; + tlv_get_uint8(tlvdb_get_tlv(tsfi), &sfin); PrintAndLogEx(INFO, "* PPSE get SFI: 0x%02x.", sfin); for (uint8_t ui = 0x01; ui <= 0x10; ui++) { From b5c2ccb78f62d6eb5a5c87aa8c8a61810d514d75 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 3 Jan 2019 20:07:08 +0200 Subject: [PATCH 047/320] pse/ppse works --- client/emv/emvcore.c | 77 +++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 80affb6c1..47705cc60 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -359,6 +359,38 @@ int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, bool Leave return res; } +int EMVCheckAID(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlvdbelm, struct tlvdb *tlv){ + uint8_t data[APDU_RES_LEN] = {0}; + size_t datalen = 0; + int res = 0; + uint16_t sw = 0; + + while (tlvdbelm) { + const struct tlv *tgAID = tlvdb_get_inchild(tlvdbelm, 0x4f, NULL); + if (tgAID) { + res = EMVSelectWithRetry(channel, false, true, (uint8_t *)tgAID->value, tgAID->len, data, sizeof(data), &datalen, &sw, tlv); + + // if returned sw error + if (res == 5) { + // next element + tlvdbelm = tlvdb_find_next(tlvdbelm, 0x61); + continue; + } + + if (res) + break; + + // all is ok + if (decodeTLV){ + PrintAndLogEx(NORMAL, "%s:", sprint_hex_inrow(tgAID->value, tgAID->len)); + TLVPrintFromBuffer(data, datalen); + } + } + tlvdbelm = tlvdb_find_next(tlvdbelm, 0x61); + } + return res; +} + int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; @@ -366,6 +398,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO size_t sfidatalen[0x11] = {0}; uint16_t sw = 0; int res; + bool fileFound = false; // select PPSE res = EMVSelectPSE(channel, ActivateField, true, PSENum, data, sizeof(data), &datalen, &sw); @@ -379,6 +412,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO struct tlvdb *t = NULL; t = tlvdb_parse_multi(data, datalen); if (t) { + // PSE/PPSE with SFI struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0x88, 0x00}); if (tsfi) { uint8_t sfin = 0; @@ -418,49 +452,24 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO PrintAndLogEx(FAILED, "SFI 0x%02d don't have records.", sfidatalen[ui]); continue; } - - // todo: check - PrintAndLogEx(INFO, "OK SFI 0x%02d.", sfidatalen[ui]); - - + res = EMVCheckAID(channel, decodeTLV, tsfitmp, tlv); + fileFound = true; } tlvdb_free(tsfi); } } - - } - + // PSE/PPSE plain (wo SFI) struct tlvdb *ttmp = tlvdb_find_path(t, (tlv_tag_t[]){0x6f, 0xa5, 0xbf0c, 0x61, 0x00}); - if (!ttmp) - PrintAndLogEx(FAILED, "PPSE don't have records."); - - while (ttmp) { - const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x4f, NULL); - if (tgAID) { - res = EMVSelectWithRetry(channel, false, true, (uint8_t *)tgAID->value, tgAID->len, data, sizeof(data), &datalen, &sw, tlv); - - // if returned sw error - if (res == 5) { - // next element - ttmp = tlvdb_find_next(ttmp, 0x61); - continue; - } - - if (res) - break; - - // all is ok - if (decodeTLV){ - PrintAndLogEx(NORMAL, "%s:", sprint_hex_inrow(tgAID->value, tgAID->len)); - TLVPrintFromBuffer(data, datalen); - } - } - - ttmp = tlvdb_find_next(ttmp, 0x61); + if (ttmp) { + res = EMVCheckAID(channel, decodeTLV, ttmp, tlv); + fileFound = true; } + + if (!fileFound) + PrintAndLogEx(FAILED, "PPSE don't have records."); tlvdb_free(t); } else { From a86c6fa1a8cf10dac8b8d4f4849f455e562e38af Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 3 Jan 2019 21:00:07 +0200 Subject: [PATCH 048/320] get rid of math.h ) --- client/emv/tlv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index a41d98c95..013e9735a 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -25,7 +25,6 @@ #include #include #include -#include #define TLV_TAG_CLASS_MASK 0xc0 #define TLV_TAG_COMPLEX 0x20 @@ -565,7 +564,7 @@ bool tlv_get_int(const struct tlv *etlv, int *value) { for (int i = 0; i < etlv->len; i++) { - *value += etlv->value[i] * pow(0x100, i); + *value += etlv->value[i] * (1 << (i * 8)); } return true; } From f23219f3b8d4dd16f88b8ffbfec8e8ea2d60c325 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 5 Jan 2019 20:45:02 +0100 Subject: [PATCH 049/320] FIX: printing percentage char is now standard compliant (@fabled) see https://github.com/iceman1001/proxmark3/pull/272 --- client/cmdhw.c | 2 +- client/ui.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 49cb0025e..a93a940cc 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -74,7 +74,7 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) { if ( mem_avail > 0 ) mem_left = (mem_avail * 1024) - mem_used; - PrintAndLogEx(NORMAL, " --= Nonvolatile Program Memory Size: %uK bytes, Used: %u bytes (%2.0f\%) Free: %u bytes (%2.0f\%)", + PrintAndLogEx(NORMAL, " --= Nonvolatile Program Memory Size: %uK bytes, Used: %u bytes (%2.0f%%) Free: %u bytes (%2.0f%%)", mem_avail, mem_used, mem_avail == 0 ? 0.0f : (float)mem_used/(mem_avail*1024)*100, diff --git a/client/ui.c b/client/ui.c index 3f7e2611f..868545833 100644 --- a/client/ui.c +++ b/client/ui.c @@ -41,7 +41,7 @@ void PrintAndLogOptions(char *str[][2], size_t size, size_t space) { if (i < size-1) strncat(buff, "\n", sizeof(buff)-strlen(buff) -1); } - PrintAndLogEx(NORMAL, buff); + PrintAndLogEx(NORMAL, "%s", buff); } void PrintAndLogEx(logLevel_t level, char *fmt, ...) { @@ -85,7 +85,7 @@ void PrintAndLogEx(logLevel_t level, char *fmt, ...) { // no prefixes for normal if ( level == NORMAL ) { - PrintAndLog(buffer); + PrintAndLog("%s", buffer); return; } @@ -110,10 +110,10 @@ void PrintAndLogEx(logLevel_t level, char *fmt, ...) { token = strtok(NULL, delim); } - PrintAndLog(buffer2); + PrintAndLog("%s", buffer2); } else { snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer); - PrintAndLog(buffer2); + PrintAndLog("%s", buffer2); } } From 411fad13de4717c17aca0af53d6eec39724b01b3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 5 Jan 2019 20:49:46 +0100 Subject: [PATCH 050/320] updates --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64377c383..622ff0f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ 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] + - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman) + - Fix 'printing percentage now standard compliant' (@fabled) + - Add 'emv roca' - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman) - Added TCP ports support (on linux) (@phcoder) - Added HF sniff standalone mode with optional storing of ULC/NTAG/ULEV1 authentication attempts (@bogiton) - Fix 'Lining up plot and control window' (@anticat) From 38853b111f9b61be6f67e1cbd8eeee567cdba4ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 5 Jan 2019 20:59:00 +0100 Subject: [PATCH 051/320] FIX: adding directives to reduce size on systems like Gentoo Hardned (see https://github.com/iceman1001/proxmark3/issues/268) --- armsrc/Makefile | 5 +++-- bootrom/Makefile | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index b69e724e0..76f3a0173 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -122,8 +122,9 @@ APP_CFLAGS += $(ZLIB_CFLAGS) # zlib includes: APP_CFLAGS += -I../zlib -# stdint.h provided locally until GCC 4.5 becomes C99 compliant -APP_CFLAGS += -I. +# stdint.h provided locally until GCC 4.5 becomes C99 compliant, +# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc +APP_CFLAGS += -I. -fno-stack-protector -fno-pie # Compile these in thumb mode (small size) THUMBSRC = start.c \ diff --git a/bootrom/Makefile b/bootrom/Makefile index a579c46d3..c7e879bda 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -25,6 +25,10 @@ VERSIONSRC = version.c # stdint.h provided locally until GCC 4.5 becomes C99 compliant APP_CFLAGS = -I. -fno-strict-aliasing -ffunction-sections -fdata-sections +# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc +APP_CFLAGS += -fno-stack-protector -fno-pie + + # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common/Makefile.common From f99e6a5cae4916166b53109b4b9baea4a119138b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 19:19:30 +0100 Subject: [PATCH 052/320] chg: remove warning --- client/emv/emvcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 47705cc60..621287031 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -394,7 +394,7 @@ int EMVCheckAID(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlvdbel int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; - uint8_t sfidata[0x11][APDU_RES_LEN] = {0}; + uint8_t sfidata[0x11][APDU_RES_LEN]; size_t sfidatalen[0x11] = {0}; uint16_t sw = 0; int res; From 806e5909a73124e7c2db8ce4895fc80e941a7720 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 19:41:29 +0100 Subject: [PATCH 053/320] ADD: 'hf felica list' - updated annotation. --- client/cmdhffelica.c | 2 +- client/cmdhflist.c | 41 +++++++++++ common/protocols.h | 169 ++++++++++++++++++++++--------------------- 3 files changed, 128 insertions(+), 84 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index e8eeceb5e..700f7ae8b 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -66,7 +66,7 @@ int usage_hf_felica_raw(void){ int CmdHFFelicaList(const char *Cmd) { //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); - CmdTraceList("raw"); + CmdTraceList("felica"); return 0; } diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 14dcc6039..e4a7e27b4 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -535,7 +535,48 @@ void annotateLegic(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ } void annotateFelica(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ + switch(cmd[0]){ + case FELICA_POLL_REQ: snprintf(exp,size ,"POLLING");break; + case FELICA_POLL_ACK: snprintf(exp,size ,"POLL ACK");break; + case FELICA_REQSRV_REQ: snprintf(exp,size ,"REQUEST SERVICE");break; + case FELICA_REQSRV_ACK: snprintf(exp,size ,"REQ SERV ACK");break; + case FELICA_REQRESP_REQ: snprintf(exp,size ,"REQUEST RESPONSE");break; + case FELICA_REQRESP_ACK: snprintf(exp,size ,"REQ RESP ACK");break; + case FELICA_RDBLK_REQ: snprintf(exp,size ,"READ BLK");break; + case FELICA_RDBLK_ACK: snprintf(exp,size ,"READ BLK ACK");break; + case FELICA_WRTBLK_REQ: snprintf(exp,size ,"WRITE BLK");break; + case FELICA_WRTBLK_ACK: snprintf(exp,size ,"WRITE BLK ACK");break; + case FELICA_SRCHSYSCODE_REQ: snprintf(exp,size ,"SEARCH SERVICE CODE");break; + case FELICA_SRCHSYSCODE_ACK: snprintf(exp,size ,"SSC ACK");break; + case FELICA_REQSYSCODE_REQ: snprintf(exp,size ,"REQUEST SYSTEM CODE");break; + case FELICA_REQSYSCODE_ACK: snprintf(exp,size ,"RSC ACK");break; + case FELICA_AUTH1_REQ: snprintf(exp,size ,"AUTH 1");break; + case FELICA_AUTH1_ACK: snprintf(exp,size ,"AUTH 1 ACK");break; + case FELICA_AUTH2_REQ: snprintf(exp,size ,"AUTH 2");break; + case FELICA_AUTH2_ACK: snprintf(exp,size ,"AUTH 2 ACK");break; + case FELICA_RDSEC_REQ: snprintf(exp,size ,"READ");break; + case FELICA_RDSEC_ACK: snprintf(exp,size ,"READ ACK");break; + case FELICA_WRTSEC_REQ: snprintf(exp,size ,"WRITE");break; + case FELICA_WRTSEC_ACK: snprintf(exp,size ,"WRITE ACK");break; + case FELICA_REQSRV2_REQ: snprintf(exp,size ,"REQUEST SERVICE v2");break; + case FELICA_REQSRV2_ACK: snprintf(exp,size ,"REQ SERV v2 ACK");break; + case FELICA_GETSTATUS_REQ: snprintf(exp,size ,"GET STATUS");break; + case FELICA_GETSTATUS_ACK: snprintf(exp,size ,"GET STATUS ACK");break; + case FELICA_OSVER_REQ: snprintf(exp,size ,"REQUEST SPECIFIC VERSION");break; + case FELICA_OSVER_ACK: snprintf(exp,size ,"RSV ACK");break; + case FELICA_RESET_MODE_REQ: snprintf(exp,size ,"RESET MODE");break; + case FELICA_RESET_MODE_ACK: snprintf(exp,size ,"RESET MODE ACK");break; + case FELICA_AUTH1V2_REQ: snprintf(exp,size ,"AUTH 1 v2");break; + case FELICA_AUTH1V2_ACK: snprintf(exp,size ,"AUTH 1 v2 ACK");break; + case FELICA_AUTH2V2_REQ: snprintf(exp,size ,"AUTH 2 v2");break; + case FELICA_AUTH2V2_ACK: snprintf(exp,size ,"AUTH 2 v2 ACK");break; + case FELICA_RDSECV2_REQ: snprintf(exp,size ,"READ v2");break; + case FELICA_RDSECV2_ACK: snprintf(exp,size ,"READ v2 ACK");break; + case FELICA_WRTSECV2_REQ: snprintf(exp,size ,"WRITE v2");break; + case FELICA_WRTSECV2_ACK: snprintf(exp,size ,"WRITE v2 ACK");break; + case FELICA_UPDATE_RNDID_REQ: snprintf(exp,size ,"UPDATE RANDOM ID");break; + case FELICA_UPDATE_RNDID_ACK: snprintf(exp,size ,"URI ACK");break; default : snprintf(exp,size ,"?");break; } } diff --git a/common/protocols.h b/common/protocols.h index 0f3ef3407..8db1d481e 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -310,51 +310,51 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. // 6x xx = ERROR // MIFARE DESFire command set: -#define MFDES_CREATE_APPLICATION 0xca -#define MFDES_DELETE_APPLICATION 0xda -#define MFDES_GET_APPLICATION_IDS 0x6a -#define MFDES_SELECT_APPLICATION 0x5a -#define MFDES_FORMAT_PICC 0xfc -#define MFDES_GET_VERSION 0x60 -#define MFDES_READ_DATA 0xbd -#define MFDES_WRITE_DATA 0x3d -#define MFDES_GET_VALUE 0x6c -#define MFDES_CREDIT 0x0c -#define MFDES_DEBIT 0xdc -#define MFDES_LIMITED_CREDIT 0x1c -#define MFDES_WRITE_RECORD 0x3b -#define MFDES_READ_RECORDS 0xbb -#define MFDES_CLEAR_RECORD_FILE 0xeb -#define MFDES_COMMIT_TRANSACTION 0xc7 -#define MFDES_ABORT_TRANSACTION 0xa7 -#define MFDES_GET_FREE_MEMORY 0x6e -#define MFDES_GET_FILE_IDS 0x6f -#define MFDES_GET_ISOFILE_IDS 0x61 -#define MFDES_GET_FILE_SETTINGS 0xf5 -#define MFDES_CHANGE_FILE_SETTINGS 0x5f -#define MFDES_CREATE_STD_DATA_FILE 0xcd -#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb -#define MFDES_CREATE_VALUE_FILE 0xcc -#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1 -#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0 -#define MFDES_DELETE_FILE 0xdf -#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE -#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD -#define MFDES_AUTHENTICATE_AES 0xaa -#define MFDES_CHANGE_KEY_SETTINGS 0x54 -#define MFDES_GET_KEY_SETTINGS 0x45 -#define MFDES_CHANGE_KEY 0xc4 -#define MFDES_GET_KEY_VERSION 0x64 -#define MFDES_AUTHENTICATION_FRAME 0xAF +#define MFDES_CREATE_APPLICATION 0xca +#define MFDES_DELETE_APPLICATION 0xda +#define MFDES_GET_APPLICATION_IDS 0x6a +#define MFDES_SELECT_APPLICATION 0x5a +#define MFDES_FORMAT_PICC 0xfc +#define MFDES_GET_VERSION 0x60 +#define MFDES_READ_DATA 0xbd +#define MFDES_WRITE_DATA 0x3d +#define MFDES_GET_VALUE 0x6c +#define MFDES_CREDIT 0x0c +#define MFDES_DEBIT 0xdc +#define MFDES_LIMITED_CREDIT 0x1c +#define MFDES_WRITE_RECORD 0x3b +#define MFDES_READ_RECORDS 0xbb +#define MFDES_CLEAR_RECORD_FILE 0xeb +#define MFDES_COMMIT_TRANSACTION 0xc7 +#define MFDES_ABORT_TRANSACTION 0xa7 +#define MFDES_GET_FREE_MEMORY 0x6e +#define MFDES_GET_FILE_IDS 0x6f +#define MFDES_GET_ISOFILE_IDS 0x61 +#define MFDES_GET_FILE_SETTINGS 0xf5 +#define MFDES_CHANGE_FILE_SETTINGS 0x5f +#define MFDES_CREATE_STD_DATA_FILE 0xcd +#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb +#define MFDES_CREATE_VALUE_FILE 0xcc +#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1 +#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0 +#define MFDES_DELETE_FILE 0xdf +#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE +#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD +#define MFDES_AUTHENTICATE_AES 0xaa +#define MFDES_CHANGE_KEY_SETTINGS 0x54 +#define MFDES_GET_KEY_SETTINGS 0x45 +#define MFDES_CHANGE_KEY 0xc4 +#define MFDES_GET_KEY_VERSION 0x64 +#define MFDES_AUTHENTICATION_FRAME 0xAF // LEGIC Commands -#define LEGIC_MIM_22 0x0D -#define LEGIC_MIM_256 0x1D -#define LEGIC_MIM_1024 0x3D -#define LEGIC_ACK_22 0x19 -#define LEGIC_ACK_256 0x39 -#define LEGIC_READ 0x01 -#define LEGIC_WRITE 0x00 +#define LEGIC_MIM_22 0x0D +#define LEGIC_MIM_256 0x1D +#define LEGIC_MIM_1024 0x3D +#define LEGIC_ACK_22 0x19 +#define LEGIC_ACK_256 0x39 +#define LEGIC_READ 0x01 +#define LEGIC_WRITE 0x00 void printIclassDumpInfo(uint8_t* iclass_dump); void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb); @@ -379,7 +379,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 #define T55x7_MODULATION_DIPHASE 0x00018000 -#define T55x7_X_MODE 0x00020000 +#define T55x7_X_MODE 0x00020000 #define T55x7_BITRATE_RF_8 0 #define T55x7_BITRATE_RF_16 0x00040000 #define T55x7_BITRATE_RF_32 0x00080000 @@ -406,9 +406,9 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T5555_PSK_RF_8 0x00000200 #define T5555_USE_PWD 0x00000400 #define T5555_USE_AOR 0x00000800 -#define T5555_SET_BITRATE(x) (((x-2)/2)<<12) -#define T5555_GET_BITRATE(x) ((((x >> 12) & 0x3F)*2)+2) -#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2 +#define T5555_SET_BITRATE(x) (((x-2)/2)<<12) +#define T5555_GET_BITRATE(x) ((((x >> 12) & 0x3F)*2)+2) +#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2 #define T5555_FAST_WRITE 0x00004000 #define T5555_PAGE_SELECT 0x00008000 @@ -446,58 +446,61 @@ uint32_t GetT55xxClockBit(uint32_t clock); // FeliCa protocol -#define FELICA_POLL_REQ 0x00 -#define FELICA_POLL_ACK 0x01 +#define FELICA_POLL_REQ 0x00 +#define FELICA_POLL_ACK 0x01 -#define FELICA_REQSRV_REQ 0x02 -#define FELICA_REQSRV_ACK 0x03 +#define FELICA_REQSRV_REQ 0x02 +#define FELICA_REQSRV_ACK 0x03 -#define FELICA_RDBLK_REQ 0x06 -#define FELICA_RDBLK_ACK 0x07 +#define FELICA_REQRESP_REQ 0x04 +#define FELICA_REQRESP_ACK 0x05 -#define FELICA_WRTBLK_REQ 0x08 -#define FELICA_WRTBLK_ACK 0x09 +#define FELICA_RDBLK_REQ 0x06 +#define FELICA_RDBLK_ACK 0x07 -#define FELICA_SRCHSYSCODE_REQ 0x0a -#define FELICA_SRCHSYSCODE_ACK 0x0b +#define FELICA_WRTBLK_REQ 0x08 +#define FELICA_WRTBLK_ACK 0x09 -#define FELICA_REQSYSCODE_REQ 0x0c -#define FELICA_REQSYSCODE_ACK 0x0d +#define FELICA_SRCHSYSCODE_REQ 0x0a +#define FELICA_SRCHSYSCODE_ACK 0x0b -#define FELICA_AUTH1_REQ 0x10 -#define FELICA_AUTH1_ACK 0x11 +#define FELICA_REQSYSCODE_REQ 0x0c +#define FELICA_REQSYSCODE_ACK 0x0d -#define FELICA_AUTH2_REQ 0x12 -#define FELICA_AUTH2_ACK 0x13 +#define FELICA_AUTH1_REQ 0x10 +#define FELICA_AUTH1_ACK 0x11 -#define FELICA_RDSEC_REQ 0x14 -#define FELICA_RDSEC_ACK 0x15 +#define FELICA_AUTH2_REQ 0x12 +#define FELICA_AUTH2_ACK 0x13 -#define FELICA_WRTSEC_REQ 0x16 -#define FELICA_WRTSEC_ACK 0x17 +#define FELICA_RDSEC_REQ 0x14 +#define FELICA_RDSEC_ACK 0x15 -#define FELICA_REQSRV2_REQ 0x32 -#define FELICA_REQSRV2_ACK 0x33 +#define FELICA_WRTSEC_REQ 0x16 +#define FELICA_WRTSEC_ACK 0x17 -#define FELICA_GETSTATUS_REQ 0x38 -#define FELICA_GETSTATUS_ACK 0x39 +#define FELICA_REQSRV2_REQ 0x32 +#define FELICA_REQSRV2_ACK 0x33 -#define FELICA_OSVER_REQ 0x3c -#define FELICA_OSVER_ACK 0x3d +#define FELICA_GETSTATUS_REQ 0x38 +#define FELICA_GETSTATUS_ACK 0x39 -#define FELICA_RESET_MODE_REQ 0x3e -#define FELICA_RESET_MODE_ACK 0x3f +#define FELICA_OSVER_REQ 0x3c +#define FELICA_OSVER_ACK 0x3d -#define FELICA_AUTH1V2_REQ 0x40 -#define FELICA_AUTH1V2_ACK 0x41 +#define FELICA_RESET_MODE_REQ 0x3e +#define FELICA_RESET_MODE_ACK 0x3f -#define FELICA_AUTH2V2_REQ 0x42 -#define FELICA_AUTH2V2_ACK 0x43 +#define FELICA_AUTH1V2_REQ 0x40 +#define FELICA_AUTH1V2_ACK 0x41 -#define FELICA_RDSECV2_REQ 0x44 -#define FELICA_RDSECV2_ACK 0x45 -#define FELICA_WRTSECV2_REQ 0x46 -#define FELICA_WRTSECV2_ACK 0x47 +#define FELICA_AUTH2V2_REQ 0x42 +#define FELICA_AUTH2V2_ACK 0x43 + +#define FELICA_RDSECV2_REQ 0x44 +#define FELICA_RDSECV2_ACK 0x45 +#define FELICA_WRTSECV2_REQ 0x46 +#define FELICA_WRTSECV2_ACK 0x47 #define FELICA_UPDATE_RNDID_REQ 0x4C #define FELICA_UPDATE_RNDID_ACK 0x4D From 0dee369a585e9e2b74152798fe18d4de4f385bd5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 20:28:23 +0100 Subject: [PATCH 054/320] FIX: 'hf tune' - now works... --- armsrc/appmain.c | 6 +++--- client/comms.c | 47 ++++++++++++++++++----------------------------- include/usb_cmd.h | 11 ++++++----- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bf4bddef6..8759f93c4 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -113,7 +113,7 @@ void print_result(char *name, uint8_t *buf, size_t len) { void DbpStringEx(char *str, uint32_t cmd) { #if DEBUG uint8_t len = strlen(str); - cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (byte_t*)str, len); + cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t*)str, len); #endif } @@ -307,10 +307,10 @@ void MeasureAntennaTuningHf(void) { } else { volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; } - DbprintfEx(CMD_MEASURE_ANTENNA_TUNING_HF, "%u mV / %5u V", volt, (uint16_t)(volt/1000)); + DbprintfEx(FLAG_NONEWLINE, "%u mV / %5u V", volt, (uint16_t)(volt/1000)); } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("\n[+] cancelled"); + DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1); } void ReadMem(int addr) { diff --git a/client/comms.c b/client/comms.c index 97af830df..3c2b353b3 100644 --- a/client/comms.c +++ b/client/comms.c @@ -154,36 +154,25 @@ static void UsbCommandReceived(UsbCommand* c) { char s[USB_CMD_DATA_SIZE+1]; memset(s, 0x00, sizeof(s)); size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE); - memcpy(s, c->d.asBytes, len); - - - //#define FLAG_RAWPRINT 0x0111 - //#define FLAG_NOOPT 0x0000 - //#define FLAG_NOLOG 0x0001 - //#define FLAG_NONEWLINE 0x0010 - //#define FLAG_NOPROMPT 0x0100 + memcpy(s, c->d.asBytes, len); uint64_t flag = c->arg[1]; - if (flag > 0) { // FLAG_RAWPRINT) { - switch (flag) { - case FLAG_RAWPRINT: - printf("%s", s); - return; - case FLAG_NONEWLINE: - printf("%s\r", s); - return; - case FLAG_NOLOG: - printf("%s\r\n", s); - return; - } - fflush(stdout); - return; - } - - // print debug line on same row. escape seq \r - if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) { - PrintAndLogEx(NORMAL, "\r#db# %s", s); - } else { - PrintAndLogEx(NORMAL, "#db# %s", s); + + switch (flag) { + case FLAG_RAWPRINT: + printf("%s", s); + break; + case FLAG_NONEWLINE: + printf("\r%s", s); + break; + case FLAG_NOLOG: + printf("%s\r\n", s); + break; + //case FLAG_NOPROMPT: + // break; + case FLAG_NOOPT: + default: + PrintAndLogEx(NORMAL, "#db# %s", s); + break; } fflush(stdout); break; diff --git a/include/usb_cmd.h b/include/usb_cmd.h index d6b240fb6..44d031334 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -300,11 +300,12 @@ typedef struct{ #define FLAG_ICLASS_READER_CEDITKEY 0x40 // Dbprintf flags -#define FLAG_RAWPRINT 0x0111 -#define FLAG_NOOPT 0x0000 -#define FLAG_NOLOG 0x0001 -#define FLAG_NONEWLINE 0x0010 -#define FLAG_NOPROMPT 0x0100 +#define FLAG_RAWPRINT 0x0111 +#define FLAG_NOOPT 0x0000 +#define FLAG_NOLOG 0x0001 +#define FLAG_NONEWLINE 0x0010 +#define FLAG_NOPROMPT 0x0100 + // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: /* Whether a bootloader that understands the common_area is present */ From c37cc81c0067c8f1c08f2cdafaa55d5975ac8799 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 20:42:51 +0100 Subject: [PATCH 055/320] CHG: FeliCa more details --- armsrc/felica.c | 180 ++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index b25653d80..aa6712268 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -71,114 +71,114 @@ static struct { uint8_t *framebytes; //should be enough. maxlen is 255, 254 for data, 2 for sync, 2 for crc // 0,1 -> SYNC, 2 - len, 3-(len+1)->data, then crc -} NFCFrame; +} FelicaFrame; //b2 4d is SYNC, 45645 in 16-bit notation, 10110010 01001101 binary. Frame will not start filling until this is shifted in //bit order in byte -reverse, I guess? [((bt>>0)&1),((bt>>1)&1),((bt>>2)&1),((bt>>3)&1),((bt>>4)&1),((bt>>5)&1),((bt>>6)&1),((bt>>7)&1)] -at least in the mode that I read those in #ifndef SYNC_16BIT -# define SYNC_16BIT 0x4DB2 +# define SYNC_16BIT 0xB24D #endif -static void NFCFrameReset() { - NFCFrame.state = STATE_UNSYNCD; - NFCFrame.posCnt = 0; - NFCFrame.crc_ok = false; - NFCFrame.byte_offset = 0; +static void FelicaFrameReset() { + FelicaFrame.state = STATE_UNSYNCD; + FelicaFrame.posCnt = 0; + FelicaFrame.crc_ok = false; + FelicaFrame.byte_offset = 0; } static void NFCInit(uint8_t *data) { - NFCFrame.framebytes = data; - NFCFrameReset(); + FelicaFrame.framebytes = data; + FelicaFrameReset(); } //shift byte into frame, reversing it at the same time static void shiftInByte(uint8_t bt) { uint8_t j; - for(j=0; j < NFCFrame.byte_offset; j++) { - NFCFrame.framebytes[NFCFrame.posCnt] = ( NFCFrame.framebytes[NFCFrame.posCnt]<<1 ) + (bt & 1); + for(j=0; j < FelicaFrame.byte_offset; j++) { + FelicaFrame.framebytes[FelicaFrame.posCnt] = ( FelicaFrame.framebytes[FelicaFrame.posCnt]<<1 ) + (bt & 1); bt >>= 1; } - NFCFrame.posCnt++; - NFCFrame.rem_len--; - for(j = NFCFrame.byte_offset; j<8; j++) { - NFCFrame.framebytes[NFCFrame.posCnt] = (NFCFrame.framebytes[NFCFrame.posCnt]<<1 ) + (bt & 1); + FelicaFrame.posCnt++; + FelicaFrame.rem_len--; + for(j = FelicaFrame.byte_offset; j<8; j++) { + FelicaFrame.framebytes[FelicaFrame.posCnt] = (FelicaFrame.framebytes[FelicaFrame.posCnt]<<1 ) + (bt & 1); bt >>= 1; } } static void ProcessNFCByte(uint8_t bt) { - switch (NFCFrame.state) { + switch (FelicaFrame.state) { case STATE_UNSYNCD: { //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case if (bt > 0) { - NFCFrame.shiftReg = reflect8(bt); - NFCFrame.state = STATE_TRYING_SYNC; + FelicaFrame.shiftReg = reflect8(bt); + FelicaFrame.state = STATE_TRYING_SYNC; } break; } case STATE_TRYING_SYNC: { if (bt == 0) { //desync - NFCFrame.shiftReg = bt; - NFCFrame.state = STATE_UNSYNCD; + FelicaFrame.shiftReg = bt; + FelicaFrame.state = STATE_UNSYNCD; } else { for (uint8_t i=0; i<8; i++) { - if (NFCFrame.shiftReg == SYNC_16BIT) { + if (FelicaFrame.shiftReg == SYNC_16BIT) { //SYNC done! - NFCFrame.state = STATE_GET_LENGTH; - NFCFrame.framebytes[0] = 0xb2; - NFCFrame.framebytes[1] = 0x4d; //write SYNC - NFCFrame.byte_offset = i; + FelicaFrame.state = STATE_GET_LENGTH; + FelicaFrame.framebytes[0] = 0xb2; + FelicaFrame.framebytes[1] = 0x4d; //write SYNC + FelicaFrame.byte_offset = i; //shift in remaining byte, slowly... for(uint8_t j=i; j<8; j++) { - NFCFrame.framebytes[2] = (NFCFrame.framebytes[2] << 1) + (bt & 1); + FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1); bt >>= 1; } - NFCFrame.posCnt = 2; + FelicaFrame.posCnt = 2; if (i==0) break; } - NFCFrame.shiftReg = (NFCFrame.shiftReg << 1) + (bt & 1); + FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1); bt >>= 1; } //that byte was last byte of sync - if (NFCFrame.shiftReg == SYNC_16BIT) { + if (FelicaFrame.shiftReg == SYNC_16BIT) { //Force SYNC on next byte - NFCFrame.state = STATE_GET_LENGTH; - NFCFrame.framebytes[0] = 0xb2; - NFCFrame.framebytes[1] = 0x4d; - NFCFrame.byte_offset = 0; - NFCFrame.posCnt = 1; + FelicaFrame.state = STATE_GET_LENGTH; + FelicaFrame.framebytes[0] = 0xb2; + FelicaFrame.framebytes[1] = 0x4d; + FelicaFrame.byte_offset = 0; + FelicaFrame.posCnt = 1; } } break; } case STATE_GET_LENGTH: { shiftInByte(bt); - NFCFrame.rem_len = NFCFrame.framebytes[2] - 1; - NFCFrame.len = NFCFrame.framebytes[2] + 4; //with crc and sync - NFCFrame.state = STATE_GET_DATA; + FelicaFrame.rem_len = FelicaFrame.framebytes[2] - 1; + FelicaFrame.len = FelicaFrame.framebytes[2] + 4; //with crc and sync + FelicaFrame.state = STATE_GET_DATA; break; } case STATE_GET_DATA: { shiftInByte(bt); - if (NFCFrame.rem_len <= 0) { - NFCFrame.state = STATE_GET_CRC; - NFCFrame.rem_len = 2; + if (FelicaFrame.rem_len <= 0) { + FelicaFrame.state = STATE_GET_CRC; + FelicaFrame.rem_len = 2; } break; } case STATE_GET_CRC: { shiftInByte(bt); - if ( NFCFrame.rem_len <= 0 ) { + if ( FelicaFrame.rem_len <= 0 ) { // skip sync 2bytes. IF ok, residue should be 0x0000 - NFCFrame.crc_ok = check_crc(CRC_FELICA, NFCFrame.framebytes+2, NFCFrame.len-2); - NFCFrame.state = STATE_FULL; - NFCFrame.rem_len = 0; - if (MF_DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (NFCFrame.crc_ok) ? "OK" : "No" ); + FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2); + FelicaFrame.state = STATE_FULL; + FelicaFrame.rem_len = 0; + if (MF_DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No" ); } break; } @@ -207,7 +207,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // b0 = fc/64 (212kbps) // 0x00 = timeslot // 0x09 0x21 = crc - static uint8_t poll[10] = {0xb2,0x4d,0x06,0x00,0xFF,0xFF,0x00,0x00,0x09,0x21}; + static uint8_t poll[10] = {0xb2,0x4d,0x06,FELICA_POLL_REQ,0xFF,0xFF,0x00,0x00,0x09,0x21}; int len = 20; @@ -219,7 +219,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); // polling card, break if success - if (WaitForFelicaReply(512) && NFCFrame.framebytes[3] == FELICA_POLL_ACK) + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) break; WDT_HIT(); @@ -231,19 +231,19 @@ static uint8_t felica_select_card(felica_card_select_t *card) { return 1; // wrong answer - if (NFCFrame.framebytes[3] != FELICA_POLL_ACK) + if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) return 2; // VALIDATE CRC residue is 0, hence if crc is a value it failed. - if (!check_crc(CRC_FELICA, NFCFrame.framebytes+2, NFCFrame.len-2)) + if (!check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2)) return 3; // copy UID // idm 8 if (card) { - memcpy(card->IDm, NFCFrame.framebytes + 4, 8); - memcpy(card->PMm, NFCFrame.framebytes + 4 + 8, 8); - //memcpy(card->servicecode, NFCFrame.framebytes + 4 + 8 + 8, 2); + memcpy(card->IDm, FelicaFrame.framebytes + 4, 8); + memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8); + //memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2); memcpy(card->code, card->IDm, 2); memcpy(card->uid, card->IDm + 2, 6); memcpy(card->iccode, card->PMm, 2); @@ -389,7 +389,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // power, no modulation FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - NFCFrameReset(); + FelicaFrameReset(); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -401,7 +401,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); ProcessNFCByte(b); - if (NFCFrame.state == STATE_FULL) { + if (FelicaFrame.state == STATE_FULL) { felica_nexttransfertime = MAX( felica_nexttransfertime, @@ -410,19 +410,19 @@ bool WaitForFelicaReply(uint16_t maxbytes) { ; LogTrace( - NFCFrame.framebytes, - NFCFrame.len, + FelicaFrame.framebytes, + FelicaFrame.len, ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER - timeout, ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER, NULL, false ); return true; - } else if (c++ > timeout && NFCFrame.state == STATE_UNSYNCD) { + } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { return false; - } else if (NFCFrame.state == STATE_GET_CRC) { + } else if (FelicaFrame.state == STATE_GET_CRC) { Dbprintf(" Frame: "); - Dbhexdump(16, NFCFrame.framebytes, 0); + Dbhexdump(16, FelicaFrame.framebytes, 0); //return false; } } @@ -526,7 +526,7 @@ void felica_sendraw(UsbCommand *c) { TransmitFor18092_AsReader(buf, buf[2]+4, NULL, 1, 0); arg0 = !WaitForFelicaReply(1024); - cmd_send(CMD_ACK, arg0, 0, 0, NFCFrame.framebytes+2, NFCFrame.len-2); + cmd_send(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes+2, FelicaFrame.len-2); } if ((param & FELICA_NO_DISCONNECT)) @@ -566,21 +566,21 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { ProcessNFCByte(dist); //to be sure we are in frame - if (NFCFrame.state == STATE_GET_LENGTH) { + if (FelicaFrame.state == STATE_GET_LENGTH) { //length is after 48 (PRE)+16 (SYNC) - 64 ticks +maybe offset? not 100% - uint16_t distance = GetCountSspClk() - endframe - 64 + (NFCFrame.byte_offset > 0 ? (8-NFCFrame.byte_offset) : 0); + uint16_t distance = GetCountSspClk() - endframe - 64 + (FelicaFrame.byte_offset > 0 ? (8-FelicaFrame.byte_offset) : 0); *dest = distance >> 8; dest++; *dest = (distance & 0xff); dest++; } //crc NOT checked - if (NFCFrame.state == STATE_FULL) { + if (FelicaFrame.state == STATE_FULL) { endframe = GetCountSspClk(); - //*dest = NFCFrame.crc_ok; //kind of wasteful + //*dest = FelicaFrame.crc_ok; //kind of wasteful dest++; - for(int i=0; i < NFCFrame.len; i++) { - *dest = NFCFrame.framebytes[i]; + for(int i=0; i < FelicaFrame.len; i++) { + *dest = FelicaFrame.framebytes[i]; dest++; if (dest >= destend ) break; @@ -590,9 +590,9 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { if (remFrames <= 0) break; if (dest >= destend ) break; - numbts += NFCFrame.len; + numbts += FelicaFrame.len; - NFCFrameReset(); + FelicaFrameReset(); } } } @@ -621,9 +621,9 @@ void felica_sim_lite(uint64_t nfcid) { num_to_bytes(nfcid, 8, ndef); //prepare our 3 responses... - uint8_t resp_poll0[R_POLL0_LEN] = { 0xb2,0x4d,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; - uint8_t resp_poll1[R_POLL1_LEN] = { 0xb2,0x4d,0x14,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00, 0x88,0xb4,0xb3,0x7f}; - uint8_t resp_readblk[R_READBLK_LEN] = { 0xb2,0x4d,0x1d,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x04,0x01,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x23,0xcb,0x6e}; + uint8_t resp_poll0[R_POLL0_LEN] = { 0xb2,0x4d,0x12,FELICA_POLL_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; + uint8_t resp_poll1[R_POLL1_LEN] = { 0xb2,0x4d,0x14,FELICA_POLL_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00, 0x88,0xb4,0xb3,0x7f}; + uint8_t resp_readblk[R_READBLK_LEN] = { 0xb2,0x4d,0x1d,FELICA_RDBLK_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x04,0x01,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x23,0xcb,0x6e}; //NFC tag 3/ ISo technically. Many overlapping standards DbpString("Felica Lite-S sim start"); @@ -659,26 +659,26 @@ void felica_sim_lite(uint64_t nfcid) { //frtm = GetCountSspClk(); ProcessNFCByte(dist); - if (NFCFrame.state == STATE_FULL) { + if (FelicaFrame.state == STATE_FULL) { - if (NFCFrame.crc_ok) { + if (FelicaFrame.crc_ok) { - if (NFCFrame.framebytes[2] == 6 && NFCFrame.framebytes[3] == 0) { + if (FelicaFrame.framebytes[2] == 6 && FelicaFrame.framebytes[3] == 0) { //polling... there are two types of polling we answer to - if (NFCFrame.framebytes[6] == 0) { + if (FelicaFrame.framebytes[6] == 0) { curresp = resp_poll0; curlen = R_POLL0_LEN; listenmode = false; } - if (NFCFrame.framebytes[6] == 1) { + if (FelicaFrame.framebytes[6] == 1) { curresp = resp_poll1; curlen = R_POLL1_LEN; listenmode = true; } } - if (NFCFrame.framebytes[2] > 5 && NFCFrame.framebytes[3] == 0x06) { + if (FelicaFrame.framebytes[2] > 5 && FelicaFrame.framebytes[3] == 0x06) { //we should rebuild it depending on page size, but... //Let's see first curresp = resp_readblk; @@ -686,10 +686,10 @@ void felica_sim_lite(uint64_t nfcid) { listenmode = false; } //clear frame - NFCFrameReset(); + FelicaFrameReset(); } else { //frame invalid, clear it out to allow for the next one - NFCFrameReset(); + FelicaFrameReset(); } } } @@ -703,7 +703,7 @@ void felica_sim_lite(uint64_t nfcid) { //switch back FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD); - NFCFrameReset(); + FelicaFrameReset(); listenmode = true; curlen = 0; curresp = NULL; @@ -721,8 +721,8 @@ void felica_sim_lite(uint64_t nfcid) { void felica_dump_lite_s() { uint8_t ndef[8]; - uint8_t poll[10] = { 0xb2,0x4d,0x06,0x00,0xff,0xff,0x00,0x00,0x09,0x21}; - uint16_t liteblks[28] = {0x00, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x90,0x91,0x92,0xa0}; + uint8_t poll[10] = { 0xb2,0x4d,0x06,FELICA_POLL_REQ,0xff,0xff,0x00,0x00,0x09,0x21}; + uint16_t liteblks[28] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x90,0x91,0x92,0xa0}; // setup device. felica_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); @@ -740,12 +740,12 @@ void felica_dump_lite_s() { //TransmitFor18092_AsReader(poll, 10, GetCountSspClk()+512, 1, 0); TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); - if (WaitForFelicaReply(512) && NFCFrame.framebytes[3] == FELICA_POLL_ACK) { + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { // copy 8bytes to ndef. - memcpy(ndef, NFCFrame.framebytes + 4, 8); + memcpy(ndef, FelicaFrame.framebytes + 4, 8); // for (c=0; c < 8; c++) - // ndef[c] = NFCFrame.framebytes[c+4]; + // ndef[c] = FelicaFrame.framebytes[c+4]; for (blknum=0; blknum < sizeof(liteblks); ) { @@ -756,15 +756,15 @@ void felica_dump_lite_s() { TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, NULL, 1, 0); // read block - if (WaitForFelicaReply(1024) && NFCFrame.framebytes[3] == FELICA_RDBLK_ACK) { + if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_RDBLK_ACK) { dest[cnt++] = liteblks[blknum]; - uint8_t *fb = NFCFrame.framebytes; + uint8_t *fb = FelicaFrame.framebytes; dest[cnt++] = fb[12]; dest[cnt++] = fb[13]; - //memcpy(dest+cnt, NFCFrame.framebytes + 15, 16); + //memcpy(dest+cnt, FelicaFrame.framebytes + 15, 16); //cnt += 16; for(uint8_t j=0; j < 16; j++) dest[cnt++] = fb[15+j]; @@ -773,8 +773,8 @@ void felica_dump_lite_s() { cntfails = 0; // // print raw log. - // Dbprintf("LEN %u | Dump bytes count %u ", NFCFrame.len, cnt); - Dbhexdump(NFCFrame.len, NFCFrame.framebytes+15, 0); + // Dbprintf("LEN %u | Dump bytes count %u ", FelicaFrame.len, cnt); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes+15, 0); } else { cntfails++; if (cntfails > 12) { From 064a163c99e521a2e64dff51ead91da4bd438234 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 20:50:19 +0100 Subject: [PATCH 056/320] textual --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622ff0f78..6562f7bc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] + - Change 'hf felica list' - started with some FeliCa annotations (@iceman) + - Fix 'hf tune' - now works as expected (@iceman) - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman) - Fix 'printing percentage now standard compliant' (@fabled) - Add 'emv roca' - command to test for ROCA vuln in public RSA modulus (@merlokk / @iceman) From c1237cfa26986558f7ac6a18f380d242331317a4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 6 Jan 2019 21:05:29 +0100 Subject: [PATCH 057/320] FIX: 'lg pcf7931' - improved read code (@sguerrini97) --- CHANGELOG.md | 1 + armsrc/pcf7931.c | 371 +++++++++++++++++++++++++---------------------- armsrc/pcf7931.h | 6 +- 3 files changed, 202 insertions(+), 176 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6562f7bc5..1c7adf3a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Change 'lf pcf7931' - improved read code (@sguerrini97) - Change 'hf felica list' - started with some FeliCa annotations (@iceman) - Fix 'hf tune' - now works as expected (@iceman) - Add 'option to use flash memory to upload dictionary files' (RDV40) (@iceman) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 8405c96ce..c9a76bb3b 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -3,8 +3,7 @@ #define T0_PCF 8 //period for the pcf7931 in us #define ALLOC 16 -int DemodPCF7931(uint8_t **outBlocks) { - +size_t DemodPCF7931(uint8_t **outBlocks) { uint8_t bits[256] = {0x00}; uint8_t blocks[8][16]; uint8_t *dest = BigBuf_get_addr(); @@ -18,7 +17,7 @@ int DemodPCF7931(uint8_t **outBlocks) { int tolerance = clock / 8; int pmc, block_done; int lc, warnings = 0; - int num_blocks = 0; + size_t num_blocks = 0; int lmin=128, lmax=128; uint8_t dir; //clear read buffer @@ -40,8 +39,7 @@ int DemodPCF7931(uint8_t **outBlocks) { i++; } dir = 0; - } - else { + } else { while(i < GraphTraceLen) { if( !(dest[i] < dest[i-1]) && dest[i] < lmin) break; @@ -55,10 +53,8 @@ int DemodPCF7931(uint8_t **outBlocks) { pmc = 0; block_done = 0; - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) - { + for (bitidx = 0; i < GraphTraceLen; i++) { + if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) { lc = i - lastval; lastval = i; @@ -72,8 +68,7 @@ int DemodPCF7931(uint8_t **outBlocks) { lastval = i; pmc = 0; block_done = 1; - } - else { + } else { pmc = i; } } else if (ABS(lc-clock/2) < tolerance) { @@ -84,8 +79,7 @@ int DemodPCF7931(uint8_t **outBlocks) { lastval = i; pmc = 0; block_done = 1; - } - else if(half_switch == 1) { + } else if(half_switch == 1) { bits[bitidx++] = 0; half_switch = 0; } @@ -96,26 +90,25 @@ int DemodPCF7931(uint8_t **outBlocks) { bits[bitidx++] = 1; } else { // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting..."); + if (++warnings > 10) { + Dbprintf("Error: too many detection errors, aborting."); return 0; } } if(block_done == 1) { if(bitidx == 128) { - for(j=0; j<16; j++) { - blocks[num_blocks][j] = 128*bits[j*8+7]+ + for(j = 0; j < 16; ++j) { + blocks[num_blocks][j] = + 128 * bits[j*8 + 7]+ 64*bits[j*8+6]+ 32*bits[j*8+5]+ 16*bits[j*8+4]+ 8*bits[j*8+3]+ 4*bits[j*8+2]+ 2*bits[j*8+1]+ - bits[j*8]; - + bits[j*8] + ; } num_blocks++; } @@ -135,185 +128,209 @@ int DemodPCF7931(uint8_t **outBlocks) { return num_blocks; } -int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; +bool IsBlock0PCF7931(uint8_t *block) { + // assuming all RFU bits are set to 0 + // if PAC is enabled password is set to 0 + if (block[7] == 0x01) + { + if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + return true; + } + else if (block[7] == 0x00) + { + if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + return true; + } + return false; } -int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if( Block[10] == 0 && - Block[11] == 0 && - Block[12] == 0 && - Block[13] == 0) - if ( (Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - return 0; +bool IsBlock1PCF7931(uint8_t *block) { + // assuming all RFU bits are set to 0 + if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0) + if((block[14] & 0x7f) <= 9 && block[15] <= 9) + return true; + + return false; } void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; + int found_blocks = 0; // successfully read blocks + int max_blocks = 8; // readable blocks + uint8_t memory_blocks[8][17]; // PCF content + + uint8_t single_blocks[8][17]; // PFC blocks with unknown position + int single_blocks_cnt = 0; - memset(Blocks, 0, 8*17*sizeof(uint8_t)); + size_t n = 0; // transmitted blocks + uint8_t tmp_blocks[4][16]; // temporary read buffer + + uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found + int errors = 0; // error counter + int tries = 0; // tries counter + + memset(memory_blocks, 0, 8*17*sizeof(uint8_t)); + memset(single_blocks, 0, 8*17*sizeof(uint8_t)); + + int i = 0, j = 0; do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); + i = 0; + + memset(tmp_blocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmp_blocks); if(!n) - error++; - if(error==10 && num_blocks == 0) { + ++errors; + + // exit if no block is received + if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { Dbprintf("Error, no tag or bad tag"); return; } - else if (tries==20 || error==10) { + // exit if too many errors during reading + if (tries > 50 && (2*errors > tries)) { Dbprintf("Error reading the tag"); Dbprintf("Here is the partial content"); goto end; } - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } + ++tries; + continue; + } + + Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + + i = 0; + if(!found_0_1) { + while (i < n - 1) { + if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) { + found_0_1 = 1; + memcpy(memory_blocks[0], tmp_blocks[i], 16); + memcpy(memory_blocks[1], tmp_blocks[i+1], 16); + memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1; + // block 1 tells how many blocks are going to be sent + max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1; + found_blocks = 2; + + Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks); + + // handle the following blocks + for (j = i + 2; j < n; ++j) { + memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16); + memory_blocks[found_blocks][ALLOC] = 1; + ++found_blocks; + } + break; + } + ++i; + } + } else { + // Trying to re-order blocks + // Look for identical block in memory blocks + while (i < n-1) { + // skip all zeroes blocks + if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + for (j = 1; j < max_blocks - 1; ++j) { + if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) { + memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16); + memory_blocks[j+1][ALLOC] = 1; + if (++found_blocks >= max_blocks) goto end; } } } + if (memcmp(tmp_blocks[i+1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + for (j = 0; j < max_blocks; ++j) { + if (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) { + if (j == 0) { + memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16); + memory_blocks[max_blocks - 1][ALLOC] = 1; + } else { + memcpy(memory_blocks[j-1], tmp_blocks[i], 16); + memory_blocks[j-1][ALLOC] = 1; + } + if (++found_blocks >= max_blocks) goto end; + } + } + } + ++i; } } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + ++tries; + if (BUTTON_PRESS()) { + Dbprintf("Button pressed, stopping."); + goto end; + } + } + while (found_blocks != max_blocks); + end: Dbprintf("-----------------------------------------"); Dbprintf("Memory content:"); Dbprintf("-----------------------------------------"); - for(i=0; i", i); } Dbprintf("-----------------------------------------"); + if (found_blocks < max_blocks) { + Dbprintf("-----------------------------------------"); + Dbprintf("Blocks with unknown position:"); + Dbprintf("-----------------------------------------"); + for (i = 0; i < single_blocks_cnt; ++i) + print_result("Block", single_blocks[i], 16); + + Dbprintf("-----------------------------------------"); + } cmd_send(CMD_ACK,0,0,0,0,0); } - -/* Write on a byte of a PCF7931 tag - * @param address : address of the block to write - @param byte : address of the byte to write - @param data : data to write - */ -void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) -{ +static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { uint32_t tab[1024] = {0}; // data times frame uint32_t u = 0; uint8_t parity = 0; bool comp = 0; //BUILD OF THE DATA FRAME - //alimentation of the tag (time for initializing) AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab); - - //PMC - Dbprintf("Initialization delay : %d us", init_delay); AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab); - - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); - //password indication bit AddBitPCF7931(1, tab, l, p); - //password (on 56 bits) - Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7); - AddBytePCF7931(pass1, tab, l, p); - AddBytePCF7931(pass2, tab, l, p); - AddBytePCF7931(pass3, tab, l, p); - AddBytePCF7931(pass4, tab, l, p); - AddBytePCF7931(pass5, tab, l, p); - AddBytePCF7931(pass6, tab, l, p); - AddBytePCF7931(pass7, tab, l, p); - - + AddBytePCF7931(pass[0], tab, l, p); + AddBytePCF7931(pass[1], tab, l, p); + AddBytePCF7931(pass[2], tab, l, p); + AddBytePCF7931(pass[3], tab, l, p); + AddBytePCF7931(pass[4], tab, l, p); + AddBytePCF7931(pass[5], tab, l, p); + AddBytePCF7931(pass[6], tab, l, p); //programming mode (0 or 1) AddBitPCF7931(0, tab, l, p); //block adress on 6 bits - Dbprintf("Block address : %02x", address); - for (u=0; u<6; u++) - { + for (u = 0; u < 6; ++u) { if (address&(1< 0xFFFF){ tab[u] -= 0xFFFF; comp = 0; } } - } SendCmdPCF7931(tab); } +/* Write on a byte of a PCF7931 tag + * @param address : address of the block to write + @param byte : address of the byte to write + @param data : data to write + */ +void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { + Dbprintf("Initialization delay : %d us", init_delay); + Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); + Dbprintf("Block address : %02x", address); + Dbprintf("Byte address : %02x", byte); + Dbprintf("Data : %02x", data); + + uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7}; + + RealWritePCF7931 (password, init_delay, l, p, address, byte, data); +} /* Send a trame to a PCF7931 tags @@ -386,9 +414,7 @@ void SendCmdPCF7931(uint32_t * tab){ Dbprintf("Sending data frame..."); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU ); LED_A_ON(); @@ -405,21 +431,22 @@ void SendCmdPCF7931(uint32_t * tab){ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; AT91C_BASE_TCB->TCB_BCR = 1; - tempo = AT91C_BASE_TC0->TC_CV; for( u = 0; tab[u] != 0; u += 3){ - // modulate antenna HIGH(GPIO_SSC_DOUT); - while(tempo != tab[u]) tempo = AT91C_BASE_TC0->TC_CV; + while (tempo != tab[u]) + tempo = AT91C_BASE_TC0->TC_CV; // stop modulating antenna LOW(GPIO_SSC_DOUT); - while(tempo != tab[u+1]) tempo = AT91C_BASE_TC0->TC_CV; + while (tempo != tab[u+1]) + tempo = AT91C_BASE_TC0->TC_CV; // modulate antenna HIGH(GPIO_SSC_DOUT); - while(tempo != tab[u+2]) tempo = AT91C_BASE_TC0->TC_CV; + while (tempo != tab[u+2]) + tempo = AT91C_BASE_TC0->TC_CV; } LED_A_OFF(); @@ -437,18 +464,16 @@ void SendCmdPCF7931(uint32_t * tab){ * @param l : offset on low pulse width * @param p : offset on low pulse positioning */ - bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ - uint32_t u; - for ( u=0; u<8; u++) - { - if (byte&(1< Date: Mon, 7 Jan 2019 09:32:16 +0100 Subject: [PATCH 058/320] CHG: 'hf 14a antifuzz' - original implementation by @asfabw, reworked a bit - WORK IN PROGRESS - --- armsrc/iso14443a.c | 146 ++++++++++++++++++++++----------------------- armsrc/iso14443a.h | 2 + client/cmdhf14a.c | 29 ++++++--- 3 files changed, 92 insertions(+), 85 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 20225f416..91db762fc 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -14,7 +14,10 @@ #define MAX_ISO14A_TIMEOUT 524288 static uint32_t iso14a_timeout; +uint8_t colpos = 0; int rsamples = 0; +//int ReqCount; +//char CollisionIndicators[10*8]; uint8_t trigger = 0; // the block number for the ISO14443-4 PCB @@ -103,6 +106,8 @@ static uint32_t LastProxToAirDuration; // Sequence D: 11110000 modulation with subcarrier during first half // Sequence E: 00001111 modulation with subcarrier during second half // Sequence F: 00000000 no modulation with subcarrier +// Sequence COLL: 11111111 load modulation over the full bitlenght. +// Tricks the reader to think that multiple cards answer (at least one card with 1 and at least one card with 0). // READER TO CARD - miller // Sequence X: 00001100 drop after half a period // Sequence Y: 00000000 no drop @@ -110,6 +115,7 @@ static uint32_t LastProxToAirDuration; #define SEC_D 0xf0 #define SEC_E 0x0f #define SEC_F 0x00 +#define SEC_COLL 0xff #define SEC_X 0x0c #define SEC_Y 0x00 #define SEC_Z 0xc0 @@ -643,7 +649,9 @@ void RAMFUNC SniffIso14443a(uint8_t param) { //----------------------------------------------------------------------------- // Prepare tag messages //----------------------------------------------------------------------------- -static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) { +static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity, bool collision) { + + uint8_t localCol = 0; ToSendReset(); // Correction bit, might be removed when not needed @@ -651,7 +659,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par ToSendStuffBit(0); ToSendStuffBit(0); ToSendStuffBit(0); - ToSendStuffBit(1); // 1 + ToSendStuffBit(1); // <----- ToSendStuffBit(0); ToSendStuffBit(0); ToSendStuffBit(0); @@ -665,12 +673,15 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par // Data bits for(uint16_t j = 0; j < 8; j++) { - if(b & 1) { + if (collision && (localCol >= colpos)){ + ToSend[++ToSendMax] = SEC_COLL; + } else if(b & 1) { ToSend[++ToSendMax] = SEC_D; } else { ToSend[++ToSendMax] = SEC_E; } b >>= 1; + localCol++; } // Get the parity bit @@ -690,10 +701,13 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par ToSendMax++; } -static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) { +static void CodeIso14443aAsTagEx(const uint8_t *cmd, uint16_t len, bool collision) { uint8_t par[MAX_PARITY_SIZE] = {0}; GetParity(cmd, len, par); - CodeIso14443aAsTagPar(cmd, len, par); + CodeIso14443aAsTagPar(cmd, len, par, collision); +} +static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) { + CodeIso14443aAsTagEx(cmd, len, false); } static void Code4bitAnswerAsTag(uint8_t cmd) { @@ -1680,9 +1694,11 @@ int EmSend4bit(uint8_t resp){ par); return res; } - -int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par){ - CodeIso14443aAsTagPar(resp, respLen, par); +int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par) { + return EmSendCmdParEx(resp, respLen, par, false); +} +int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision){ + CodeIso14443aAsTagPar(resp, respLen, par, collision); int res = EmSendCmd14443aRaw(ToSend, ToSendMax); // do the tracing for the previous reader request and this tag answer: EmLogTrace(Uart.output, @@ -1697,11 +1713,13 @@ int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par){ par); return res; } - int EmSendCmd(uint8_t *resp, uint16_t respLen){ + return EmSendCmdEx(resp, respLen, false); +} +int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision){ uint8_t par[MAX_PARITY_SIZE] = {0x00}; GetParity(resp, respLen, par); - return EmSendCmdPar(resp, respLen, par); + return EmSendCmdParEx(resp, respLen, par, collision); } bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, @@ -1805,45 +1823,21 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { // by fooling the reader there is a collision and forceing the reader to // increase the uid bytes. The might be an overflow, DoS will occure. void iso14443a_antifuzz(uint32_t flags){ - /* - uint8_t uidlen = 4+1+1+2; - if (( flags & 2 ) == 2 ) - uidlen = 7+1+1+2; - if (( flags & 4 ) == 4 ) - uidlen = 10+1+1+2; - - uint8_t *uid = BigBuf_malloc(uidlen); - - // The first response contains the ATQA (note: bytes are transmitted in reverse order). - // Mifare Classic 1K - uint8_t atqa[] = {0x04, 0}; - - if ( (flags & 2) == 2 ) { - uid[0] = 0x88; // Cascade Tag marker - uid[1] = 0x01; - - // Configure the ATQA accordingly - atqa[0] |= 0x40; - } else { - memcpy(response2, data, 4); - // Configure the ATQA accordingly - atqa[0] &= 0xBF; - } // We need to listen to the high-frequency, peak-detected path. iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - // allocate buffers: - uint8_t *received = BigBuf_malloc(MAX_FRAME_SIZE); - uint8_t *receivedPar = BigBuf_malloc(MAX_PARITY_SIZE); - uint16_t counter = 0; - - int len = 0; - - BigBuf_free(); + BigBuf_free_keep_EM(); clear_trace(); set_tracing(true); + 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(8); + LED_A_ON(); for (;;) { WDT_HIT(); @@ -1853,47 +1847,47 @@ void iso14443a_antifuzz(uint32_t flags){ Dbprintf("Anti-fuzz stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); break; } - p_response = NULL; + if ( received[0] == ISO14443A_CMD_WUPA || received[0] == ISO14443A_CMD_REQA) { + resp[0] = 0x04; + resp[1] = 0x00; + + if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { + resp[0] = 0x44; + } + + EmSendCmd(resp, 2); + continue; + } - // look at the command now. - if (received[0] == ISO14443A_CMD_REQA) { // Received a REQUEST - p_response = &responses[0]; - } else if (received[0] == ISO14443A_CMD_WUPA) { // Received a WAKEUP - p_response = &responses[0]; - } else if (received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received request for UID (cascade 1) - p_response = &responses[1]; - } else if (received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) - p_response = &responses[2]; - } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) - p_response = &responses[3]; - } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) - p_response = &responses[4]; - } - if (p_response != NULL) { + // Received request for UID (cascade 1) + if (received[1] >= 0x20 && received[1] <= 0x57 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { + resp[0] = 0x04; + resp[1] = 0x1C; + resp[2] = 0xE1; + resp[3] = 0xCE; + colpos = 0; - EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n); - // do the tracing for the previous reader request and this tag answer: - uint8_t par[MAX_PARITY_SIZE] = {0x00}; - GetParity(p_response->response, p_response->response_n, par); + if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { + resp[0] = 0x88; + colpos = 8; + } - EmLogTrace(Uart.output, - Uart.len, - Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.parity, - p_response->response, - p_response->response_n, - LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, - (LastTimeProxToAirStart + p_response->ProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, - par); + EmSendCmdEx(resp, 4, true); + if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); + + continue; + } else if (received[1] == 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) + if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT_2"); + } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) + } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) + } else { + Dbprintf("unknown command %x", received[0]); } - counter++; } cmd_send(CMD_ACK,1,0,0,0,0); - switch_off(); - Dbprintf("-[ UID until no response [%d]", counter); -*/ + switch_off(); + BigBuf_free_keep_EM(); } static void iso14a_set_ATS_times(uint8_t *ats) { diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index ff34fa577..7f979e531 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -122,8 +122,10 @@ extern void iso14a_set_trigger(bool enable); extern int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen); extern int EmSend4bit(uint8_t resp); extern int EmSendCmd(uint8_t *resp, uint16_t respLen); +extern int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision); extern int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity); extern int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par); +extern int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision); extern int EmSendPrecompiledCmd(tag_response_info_t *response_info); bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index b9d7bfcae..43832e2cf 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -213,11 +213,6 @@ int usage_hf_14a_info(void){ PrintAndLogEx(NORMAL, " n test for nack bug"); return 0; } -int usage_hf_14a_antifuzz(void) { - PrintAndLogEx(NORMAL, "Usage: hf 14a antifuzz [4|7|10]"); - PrintAndLogEx(NORMAL, " determine which anticollision phase the command will target."); - return 0; -} int CmdHF14AList(const char *Cmd) { //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead"); @@ -1183,11 +1178,27 @@ static int waitCmd(uint8_t iSelect) { int CmdHF14AAntiFuzz(const char *cmd) { - if (strlen(cmd) < 1) return usage_hf_14a_antifuzz(); + CLIParserInit("hf 14a antifuzz", + "Tries to fuzz the ISO14443a anticollision phase", + "Usage:\n" + "\thf 14a antifuzz -4\n"); - // read param length - uint8_t arg0 = 4; - + void* argtable[] = { + arg_param_begin, + arg_lit0("4", NULL, "4 byte uid"), + arg_lit0("7", NULL, "7 byte uid"), + arg_lit0(NULL, "10", "10 byte uid"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, false); + + uint8_t arg0 = FLAG_4B_UID_IN_DATA; + if (arg_get_lit(2)) + arg0 = FLAG_7B_UID_IN_DATA; + if (arg_get_lit(3)) + arg0 = FLAG_10B_UID_IN_DATA; + + CLIParserFree(); UsbCommand c = {CMD_ANTIFUZZ_ISO_14443a, {arg0, 0, 0}}; clearCommandBuffer(); SendCommand(&c); From 5a34550ac5b4e490e99f542ec28be6606e1a2f20 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 7 Jan 2019 17:49:09 +0100 Subject: [PATCH 059/320] CHG: printing --- client/comms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/comms.c b/client/comms.c index 3c2b353b3..5beaa0adb 100644 --- a/client/comms.c +++ b/client/comms.c @@ -178,7 +178,7 @@ static void UsbCommandReceived(UsbCommand* c) { break; } case CMD_DEBUG_PRINT_INTEGERS: { - PrintAndLogEx(NORMAL, "#db# %08x, %08x, %08x", c->arg[0], c->arg[1], c->arg[2]); + PrintAndLogEx(NORMAL, "#db# %" PRIx64 ", %" PRIx64 ", %" PRIx64 "", c->arg[0], c->arg[1], c->arg[2]); break; } // iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of From 04893371bc61c9a4f4c98262ec6cc331d3fb1688 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 8 Jan 2019 00:05:00 +0100 Subject: [PATCH 060/320] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fdf02f0a2..4a4503b94 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ This fork now compiles just fine on ## KALI and ARCHLINUX users Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly. - +`sudo apt remove modemmanager` + ## Setup and build for UBUNTU GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04 See https://github.com/Proxmark/proxmark3/wiki/Ubuntu%20Linux @@ -88,6 +89,9 @@ https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh `sudo pacman -Sy base-devel p7zip libusb readline ncurses libjansson-dev arm-none-eabi-newlib --needed` `yaourt -S termcap` +- Remove modemmanager +`sudo apt remove modemmanager` + - Clone fork `git clone https://github.com/RfidResearchGroup/proxmark3.git` From 7271d5afc90bfb1439c6e5c45066b9df5700bd54 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 8 Jan 2019 00:36:33 +0100 Subject: [PATCH 061/320] Update README.md --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4a4503b94..94f7b94d6 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The new universial GUI will work. ## Development This fork now compiles just fine on - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - - Ubuntu 1404, 1510, 1604 + - Ubuntu 1404, 1510, 1604, 1804 - Mac OS X / Homebrew - Docker container @@ -159,7 +159,7 @@ Links - https://github.com/Gator96100/ProxSpace/releases/tag/v2.2 (release v2.2 with gcc v5.3.0 arm-none-eabi-gcc v7.1.0) -### 7. Build and run +### Build and run - Clone fork `git clone https://github.com/RfidResearchGroup/proxmark3.git` @@ -181,5 +181,66 @@ Assuming you have Proxmark3 Windows drivers installed you can run the Proxmark s - Run the client `proxmark3.exe comX` -iceman at host iuse.se -July 2018, Sweden + +## Validating proxmark client functionality + +If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this. + +>[=] UART Setting serial baudrate 460800 +> +>Proxmark3 RFID instrument +> +> [ CLIENT ] +> +> client: iceman build for RDV40 with flashmem; smartcard; +> +> [ ARM ] +> +> bootrom: iceman/master/4517531c-dirty-unclean 2018-12-13 15:42:24 +> +> os: iceman/master/5a34550a-dirty-unclean 2019-01-07 23:04:07 +> +> [ FPGA ] +> +> LF image built for 2s30vq100 on 2018/ 9/ 8 at 13:57:51 +> +> HF image built for 2s30vq100 on 2018/ 9/ 3 at 21:40:23 +> +> [ Hardware ] +> +>--= uC: AT91SAM7S512 Rev B +> +>--= Embedded Processor: ARM7TDMI +> +>--= Nonvolatile Program Memory Size: 512K bytes, Used: 247065 bytes (47%) Free: 277223 bytes (53%) +> +>--= Second Nonvolatile Program Memory Size: None +> +>--= Internal SRAM Size: 64K bytes +> +>--= Architecture Identifier: AT91SAM7Sxx Series +> +>--= Nonvolatile Program Memory Type: Embedded Flash Memory +> +> pm3 --> + +### run the following commands + pm3 --> hw status + pm3 --> hw version + pm3 --> hw tune + +You are now ready to use your newly upgraded proxmark3 device. Many commands uses the **h** parameter to show a help text. The client uses a arcaic command structure which will be hard to grasp at first. Here are some commands to start off with. + + pm3 --> hf + pm3 --> hf 14a info + pm3 --> lf + pm3 --> lf search + +### Quit client + pm3 --> quit + + +## the end + +`iceman at host iuse.se` +`July 2018, Sweden` From 9b7089e71f8ce14353a7239bdedaee3b5cf08967 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 02:16:39 +0100 Subject: [PATCH 062/320] FIX: remove warning of overwriting --- client/ui.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ui.c b/client/ui.c index 868545833..a0151a8db 100644 --- a/client/ui.c +++ b/client/ui.c @@ -48,10 +48,10 @@ void PrintAndLogEx(logLevel_t level, char *fmt, ...) { // skip debug messages if client debugging is turned off i.e. 'DATA SETDEBUG 0' if (g_debugMode == 0 && level == DEBUG) return; - + + char prefix[20] = {0}; char buffer[MAX_PRINT_BUFFER] = {0}; - char buffer2[MAX_PRINT_BUFFER] = {0}; - char prefix[20] = {0}; + char buffer2[MAX_PRINT_BUFFER+20] = {0}; char *token = NULL; int size = 0; // {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG} From 2d5d8c130d9d83276ecf48a6e81fae9d081478c1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 02:22:41 +0100 Subject: [PATCH 063/320] chg: 'hf list 14a' - another 7bit command 0x35 --- client/cmdhflist.c | 1 + common/protocols.h | 1 + 2 files changed, 2 insertions(+) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index e4a7e27b4..7791c5e53 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -159,6 +159,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) { MifareAuthState = masNone; break; case ISO14443A_CMD_RATS: snprintf(exp,size,"RATS"); break; + case ISO14443A_CMD_OPTS: snprintf(exp,size,"OPTIONAL TIMESLOT"); break; case MIFARE_CMD_INC: snprintf(exp,size,"INC(%d)",cmd[1]); break; case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break; case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break; diff --git a/common/protocols.h b/common/protocols.h index 8db1d481e..9696c73e0 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -144,6 +144,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO14443A_CMD_REQA 0x26 #define ISO14443A_CMD_READBLOCK 0x30 #define ISO14443A_CMD_WUPA 0x52 +#define ISO14443A_CMD_OPTS 0x35 #define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93 #define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95 #define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97 From 699a3b71524027bf712a30abdb7af2ea056294c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 02:23:06 +0100 Subject: [PATCH 064/320] FIX: remove overwriting warning --- client/jansson/load.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/client/jansson/load.c b/client/jansson/load.c index 8700919fd..9f73ea02c 100644 --- a/client/jansson/load.c +++ b/client/jansson/load.c @@ -89,7 +89,7 @@ static void error_set(json_error_t *error, const lex_t *lex, { va_list ap; char msg_text[JSON_ERROR_TEXT_LENGTH]; - char msg_with_context[JSON_ERROR_TEXT_LENGTH]; + char msg_with_context[JSON_ERROR_TEXT_LENGTH + 20]; int line = -1, col = -1; size_t pos = 0; @@ -114,9 +114,8 @@ static void error_set(json_error_t *error, const lex_t *lex, if(saved_text && saved_text[0]) { if(lex->saved_text.length <= 20) { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, - "%s near '%s'", msg_text, saved_text); - msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", msg_text, saved_text); + msg_with_context[JSON_ERROR_TEXT_LENGTH + 20 - 1] = '\0'; result = msg_with_context; } } @@ -131,9 +130,8 @@ static void error_set(json_error_t *error, const lex_t *lex, result = msg_text; } else { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, - "%s near end of file", msg_text); - msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", msg_text); + msg_with_context[JSON_ERROR_TEXT_LENGTH + 20 - 1] = '\0'; result = msg_with_context; } } From dac30911a3d69a4c6cd02dd4e774493d465f7e42 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 10:56:56 +0100 Subject: [PATCH 065/320] FIX: remove gcc8.2 warnings --- client/cmdhfmf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d92b2a1d4..985965d72 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -894,9 +894,9 @@ int CmdHF14AMfRestore(const char *Cmd) { uint8_t keyB[40][6]; uint8_t numSectors = 16; uint8_t cmdp = 0; - char keyFilename[FILE_PATH_SIZE]=""; - char dataFilename[FILE_PATH_SIZE]=""; - char szTemp[FILE_PATH_SIZE]=""; + char keyFilename[FILE_PATH_SIZE] = ""; + char dataFilename[FILE_PATH_SIZE] = ""; + char szTemp[FILE_PATH_SIZE-20] = ""; char *fptr; FILE *fdump, *fkeys; @@ -905,7 +905,7 @@ int CmdHF14AMfRestore(const char *Cmd) { case 'h': return usage_hf14_restore(); case 'u': - param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE); + param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE-20); if(keyFilename[0]==0x00) snprintf(keyFilename, FILE_PATH_SIZE, "hf-mf-%s-key.bin", szTemp); if(dataFilename[0]==0x00) @@ -1280,7 +1280,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0}; uint8_t cmdp=0; char filename[FILE_PATH_SIZE], *fptr; - char szTemp[FILE_PATH_SIZE]; + char szTemp[FILE_PATH_SIZE-20]; char ctmp; bool know_target_key = false; @@ -1370,13 +1370,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) { strncpy(filename, fptr, FILE_PATH_SIZE); break; case 'u': - param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE); + param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE-20); snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", szTemp); cmdp++; break; case 'f': - param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE); - strncpy(filename, szTemp, FILE_PATH_SIZE); + param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE-20); + strncpy(filename, szTemp, FILE_PATH_SIZE-20); cmdp++; break; case 'i': From a17bf8e5592c8336a155b5dc4dd016fa0d08b192 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 11:20:42 +0100 Subject: [PATCH 066/320] FIX: remove gcc8.2 warning --- client/util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/util.c b/client/util.c index 22490f62a..5d7ce0370 100644 --- a/client/util.c +++ b/client/util.c @@ -313,11 +313,11 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len) { memset(buf, 0x00, UTIL_BUFFER_SIZE_SPRINT); size_t max_len = (len > 1010) ? 1010 : len; - sprintf(tmp, "%s| ", sprint_hex(data, max_len) ); + snprintf(tmp, UTIL_BUFFER_SIZE_SPRINT, "%s| ", sprint_hex(data, max_len) ); size_t i = 0; - size_t pos = (max_len * 3)+2; - while(i < max_len){ + size_t pos = (max_len * 3) + 2; + while (i < max_len){ char c = data[i]; if ( (c < 32) || (c == 127)) c = '.'; From 11e0c09fdd6e2991f96515c3b7f9f9623686a7fa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 16:48:04 +0100 Subject: [PATCH 067/320] CHG: more definitions --- client/emv/emv_tags.c | 150 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 13 deletions(-) diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 74a37aba6..521598b67 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -175,7 +175,8 @@ static const struct emv_tag emv_tags[] = { // internal { 0x00 , "Unknown ???" }, { 0x01 , "", EMV_TAG_STRING }, // string for headers - { 0x02 , "Raw data", }, // data + { 0x02 , "Raw data" }, // data + { 0x06 , "Object Identifier (OID)" }, { 0x20 , "Cardholder Verification Results (CVR)", EMV_TAG_CVR }, // not standard! { 0x21 , "Input list for Offline Data Authentication" }, // not standard! data for "Offline Data Authentication" come from "read records" command. (EMV book3 10.3) @@ -184,6 +185,9 @@ static const struct emv_tag emv_tags[] = { { 0x42 , "Issuer Identification Number (IIN)" }, { 0x4f , "Application Dedicated File (ADF) Name" }, { 0x50 , "Application Label", EMV_TAG_STRING }, + { 0x51 , "File reference data element" }, + { 0x52 , "Command APDU" }, + { 0x53 , "Discretionary data (or template)" }, { 0x56 , "Track 1 Data" }, { 0x57 , "Track 2 Equivalent Data" }, { 0x5a , "Application Primary Account Number (PAN)" }, @@ -195,6 +199,13 @@ static const struct emv_tag emv_tags[] = { { 0x5f2d, "Language Preference", EMV_TAG_STRING }, { 0x5f30, "Service Code", EMV_TAG_NUMERIC }, { 0x5f34, "Application Primary Account Number (PAN) Sequence Number", EMV_TAG_NUMERIC }, + { 0x5f36, "Transaction Currency Exponent", EMV_TAG_NUMERIC }, + { 0x5f50, "Issuer URL", EMV_TAG_STRING }, + { 0x5f53, "International Bank Account Number (IBAN)" }, + { 0x5f54, "Bank Identifier Code (BIC)" }, + { 0x5f55, "Issuer Country Code (alpha2 format)", EMV_TAG_STRING }, + { 0x5f56, "Issuer Country Code (alpha3 format)", EMV_TAG_STRING }, + { 0x61 , "Application Template" }, { 0x6f , "File Control Information (FCI) Template" }, { 0x70 , "READ RECORD Response Message Template" }, @@ -203,11 +214,14 @@ static const struct emv_tag emv_tags[] = { { 0x73 , "Directory Discretionary Template" }, { 0x77 , "Response Message Template Format 2" }, { 0x80 , "Response Message Template Format 1" }, + { 0x81 , "Amount, Authorised (Binary)" }, { 0x82 , "Application Interchange Profile", EMV_TAG_BITMASK, &EMV_AIP }, { 0x83 , "Command Template" }, { 0x84 , "Dedicated File (DF) Name" }, + { 0x86 , "Issuer Script Command" }, { 0x87 , "Application Priority Indicator" }, { 0x88 , "Short File Identifier (SFI)" }, + { 0x89 , "Authorisation Code" }, { 0x8a , "Authorisation Response Code" }, { 0x8c , "Card Risk Management Data Object List 1 (CDOL1)", EMV_TAG_DOL }, { 0x8d , "Card Risk Management Data Object List 2 (CDOL2)", EMV_TAG_DOL }, @@ -219,14 +233,25 @@ static const struct emv_tag emv_tags[] = { { 0x93 , "Signed Static Application Data" }, { 0x94 , "Application File Locator (AFL)", EMV_TAG_AFL }, { 0x95 , "Terminal Verification Results" }, + { 0x97 , "Transaction Certificate Data Object List (TDOL)" }, + { 0x98 , "Transaction Certificate (TC) Hash Value" }, + { 0x99 , "Transaction Personal Identification Number (PIN) Data" }, { 0x9a , "Transaction Date", EMV_TAG_YYMMDD }, - { 0x9c , "Transaction Type" }, + { 0x9b , "Transaction Status Information" }, + { 0x9c , "Transaction Type", EMV_TAG_NUMERIC }, + { 0x9d , "Directory Definition File (DDF) Name" }, + + { 0x9f01, "Acquirer Identifier", EMV_TAG_NUMERIC }, { 0x9f02, "Amount, Authorised (Numeric)", EMV_TAG_NUMERIC }, - { 0x9f03, "Amount, Other (Numeric)", EMV_TAG_NUMERIC, }, + { 0x9f03, "Amount, Other (Numeric)", EMV_TAG_NUMERIC }, + { 0x9f04, "Amount, Other (Binary)", EMV_TAG_NUMERIC }, + { 0x9f05, "Application Discretionary Data" }, { 0x9f06, "Application Identifier (AID), Terminal. ISO 7816-5" }, { 0x9f07, "Application Usage Control", EMV_TAG_BITMASK, &EMV_AUC }, { 0x9f08, "Application Version Number" }, + { 0x9f09, "Application Version Number - terminal" }, { 0x9f0a, "Application Selection Registered Proprietary Data" }, // https://blog.ul-ts.com/posts/electronic-card-identifier-one-more-step-for-mif-compliance/ + { 0x9f0b, "Cardholder Name Extended", EMV_TAG_STRING }, { 0x9f0d, "Issuer Action Code - Default", EMV_TAG_BITMASK, &EMV_TVR }, { 0x9f0e, "Issuer Action Code - Denial", EMV_TAG_BITMASK, &EMV_TVR }, { 0x9f0f, "Issuer Action Code - Online", EMV_TAG_BITMASK, &EMV_TVR }, @@ -234,11 +259,21 @@ static const struct emv_tag emv_tags[] = { { 0x9f11, "Issuer Code Table Index", EMV_TAG_NUMERIC }, { 0x9f12, "Application Preferred Name", EMV_TAG_STRING }, { 0x9f13, "Last Online Application Transaction Counter (ATC) Register" }, + { 0x9f14, "Lower Consecutive Offline Limit" }, + { 0x9f15, "Merchant Category Code", EMV_TAG_NUMERIC }, + { 0x9f16, "Merchant Identifier", EMV_TAG_STRING }, { 0x9f17, "Personal Identification Number (PIN) Try Counter" }, + { 0x9f18, "Issuer Script Identifier" }, { 0x9f1a, "Terminal Country Code" }, + { 0x9f1b, "Terminal Floor Limit" }, + { 0x9f1c, "Terminal Identification", EMV_TAG_STRING }, + { 0x9f1d, "Terminal Risk Management Data" }, + { 0x9f1e, "Interface Device (IFD) Serial Number", EMV_TAG_STRING }, { 0x9f1f, "Track 1 Discretionary Data", EMV_TAG_STRING }, { 0x9f20, "Track 2 Discretionary Data", EMV_TAG_STRING }, - { 0x9f21, "Transaction Time" }, + { 0x9f21, "Transaction Time" }, + { 0x9f22, "Certification Authority Public Key Index - Terminal" }, + { 0x9f23, "Upper Consecutive Offline Limit" }, { 0x9f26, "Application Cryptogram" }, { 0x9f27, "Cryptogram Information Data", EMV_TAG_CID }, { 0x9f2a, "Kernel Identifier" }, @@ -246,12 +281,21 @@ static const struct emv_tag emv_tags[] = { { 0x9f2e, "ICC PIN Encipherment Public Key Exponent" }, { 0x9f2f, "ICC PIN Encipherment Public Key Remainder" }, { 0x9f32, "Issuer Public Key Exponent" }, + { 0x9f33, "Terminal Capabilities" }, { 0x9f34, "Cardholder Verification Method (CVM) Results" }, { 0x9f35, "Terminal Type" }, { 0x9f36, "Application Transaction Counter (ATC)" }, { 0x9f37, "Unpredictable Number" }, { 0x9f38, "Processing Options Data Object List (PDOL)", EMV_TAG_DOL }, + { 0x9f39, "Point-of-Service (POS) Entry Mode", EMV_TAG_NUMERIC }, + { 0x9f3a, "Amount, Reference Currency" }, + { 0x9f3b, "Application Reference Currency", EMV_TAG_NUMERIC }, + { 0x9f3c, "Transaction Reference Currency Code", EMV_TAG_NUMERIC }, + { 0x9f3d, "Transaction Reference Currency Exponent", EMV_TAG_NUMERIC }, + { 0x9f40, "Additional Terminal Capabilities" }, + { 0x9f41, "Transaction Sequence Counter", EMV_TAG_NUMERIC }, { 0x9f42, "Application Currency Code", EMV_TAG_NUMERIC }, + { 0x9f43, "Application Reference Currency Exponent", EMV_TAG_NUMERIC }, { 0x9f44, "Application Currency Exponent", EMV_TAG_NUMERIC }, { 0x9f45, "Data Authentication Code" }, { 0x9f46, "ICC Public Key Certificate" }, @@ -262,14 +306,22 @@ static const struct emv_tag emv_tags[] = { { 0x9f4b, "Signed Dynamic Application Data" }, { 0x9f4c, "ICC Dynamic Number" }, { 0x9f4d, "Log Entry" }, + { 0x9f4e, "Merchant Name and Location", EMV_TAG_STRING }, { 0x9f4f, "Log Format", EMV_TAG_DOL }, { 0x9f50, "Offline Accumulator Balance" }, { 0x9f51, "Application Currency Code" }, { 0x9f51, "DRDOL" }, + { 0x9f52, "Application Default Action (ADA)" }, { 0x9f52, "Terminal Compatibility Indicator" }, + + { 0x9f53, "Transaction Category Code" }, + { 0x9f54, "DS ODS Card" }, + + { 0x9f55, "Mobile Support Indicator" }, { 0x9f55, "Issuer Authentication Flags" }, + { 0x9f56, "Issuer Authentication Indicator" }, { 0x9f57, "Issuer Country Code" }, { 0x9f58, "Consecutive Transaction Counter Limit (CTCL)" }, @@ -277,27 +329,99 @@ static const struct emv_tag emv_tags[] = { { 0x9f5A, "Application Program Identifier" }, { 0x9f5b, "Issuer Script Results" }, { 0x9f5c, "Cumulative Total Transaction Amount Upper Limit (CTTAUL)" }, + { 0x9f5d, "Application Capabilities Information" }, + { 0x9f5e, "Data Storage Identifier" }, + { 0x9f5f, "DS Slot Availability" }, { 0x9f60, "CVC3 (Track1)" }, { 0x9f61, "CVC3 (Track2)" }, - { 0x9f62, "PCVC3(Track1)" }, - { 0x9f63, "PUNATC(Track1)" }, - { 0x9f64, "NATC(Track1)" }, - { 0x9f65, "PCVC3(Track2)" }, - { 0x9f66, "PUNATC(Track2) / Terminal Transaction Qualifiers (TTQ)", EMV_TAG_BITMASK, &EMV_TTQ }, - { 0x9f67, "NATC(Track2) / MSD Offset" }, + { 0x9f62, "PCVC3 (Track1)" }, + { 0x9f63, "PUNATC (Track1)" }, + { 0x9f64, "NATC (Track1)" }, + { 0x9f65, "PCVC3 (Track2)" }, + { 0x9f66, "PUNATC (Track2) / Terminal Transaction Qualifiers (TTQ)", EMV_TAG_BITMASK, &EMV_TTQ }, + { 0x9f67, "NATC (Track2) / MSD Offset" }, { 0x9f68, "Cardholder verification method list (PayPass)" }, - { 0x9f69, "Card Authentication Related Data" }, + { 0x9f69, "Card Authentication Related Data (UDOL)" }, { 0x9f6a, "Unpredictable Number", EMV_TAG_NUMERIC }, { 0x9f6b, "Track 2 Data" }, { 0x9f6c, "Card Transaction Qualifiers (CTQ)", EMV_TAG_BITMASK, &EMV_CTQ }, + { 0x9f6d, "Mag-stripe Application Version Number (Reader)" }, { 0x9f6e, "Form Factor Indicator" }, - - { 0x9f7c, "Customer Exclusive Data (CED)"}, + { 0x9f6f, "DS Slot Management Control" }, + + { 0x9f70, "Protected Data Envelope 1" }, + { 0x9f71, "Protected Data Envelope 2" }, + { 0x9f72, "Protected Data Envelope 3" }, + { 0x9f73, "Protected Data Envelope 4" }, + { 0x9f74, "Protected Data Envelope 5" }, + { 0x9f75, "Unprotected Data Envelope 1" }, + { 0x9f76, "Unprotected Data Envelope 2" }, + { 0x9f77, "Unprotected Data Envelope 3" }, + { 0x9f78, "Unprotected Data Envelope 4" }, + { 0x9f79, "Unprotected Data Envelope 5" }, + { 0x9f7c, "Merchant Custom Data / Customer Exclusive Data (CED)" }, + { 0x9f7d, "DS Summary 1" }, + { 0x9f7f, "DS Unpredictable Number" }, { 0xa5 , "File Control Information (FCI) Proprietary Template" }, { 0xbf0c, "File Control Information (FCI) Issuer Discretionary Data" }, { 0xdf20, "Issuer Proprietary Bitmap (IPB)" }, + { 0xdf4b, "POS Cardholder Interaction Information" }, + { 0xdf60, "VISA Log Entry" }, + { 0xdf61, "DS Digest H" }, + { 0xdf62, "DS ODS Info" }, + { 0xdf63, "DS ODS Term" }, + + { 0xdf8104, "Balance Read Before Gen AC" }, + { 0xdf8105, "Balance Read After Gen AC" }, + { 0xdf8106, "Data Needed" }, + { 0xdf8107, "CDOL1 Related Data" }, + { 0xdf8108, "DS AC Type" }, + { 0xdf8109, "DS Input (Term)" }, + { 0xdf810a, "DS ODS Info For Reader" }, + { 0xdf810b, "DS Summary Status" }, + { 0xdf810c, "Kernel ID" }, + { 0xdf810d, "DSVN Term" }, + { 0xdf810e, "Post-Gen AC Put Data Status" }, + { 0xdf810f, "Pre-Gen AC Put Data Status" }, + { 0xdf8110, "Proceed To First Write Flag" }, + { 0xdf8111, "PDOL Related Data" }, + { 0xdf8112, "Tags To Read" }, + { 0xdf8113, "DRDOL Related Data" }, + { 0xdf8114, "Reference Control Parameter" }, + { 0xdf8115, "Error Indication" }, + { 0xdf8116, "User Interface Request Data" }, + { 0xdf8117, "Card Data Input Capability" }, + { 0xdf8118, "CVM Capability - CVM Required" }, + { 0xdf8119, "CVM Capability - No CVM Required" }, + { 0xdf811a, "Default UDOL" }, + { 0xdf811b, "Kernel Configuration" }, + { 0xdf811c, "Max Lifetime of Torn Transaction Log Record" }, + { 0xdf811d, "Max Number of Torn Transaction Log Records" }, + { 0xdf811e, "Mag-stripe CVM Capability – CVM Required" }, + { 0xdf811f, "Security Capability" }, + { 0xdf8120, "Terminal Action Code – Default" }, + { 0xdf8121, "Terminal Action Code – Denial" }, + { 0xdf8122, "Terminal Action Code – Online" }, + { 0xdf8123, "Reader Contactless Floor Limit" }, + { 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)" }, + { 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)" }, + { 0xdf8126, "Reader CVM Required Limit" }, + { 0xdf8127, "TIME_OUT_VALUE" }, + { 0xdf8128, "IDS Status" }, + { 0xdf8129, "Outcome Parameter Set" }, + { 0xdf812a, "DD Card (Track1)" }, + { 0xdf812b, "DD Card (Track2)" }, + { 0xdf812c, "Mag-stripe CVM Capability – No CVM Required" }, + { 0xdf812d, "Message Hold Time" }, + + { 0xff8101, "Torn Record" }, + { 0xff8102, "Tags To Write Before Gen AC" }, + { 0xff8103, "Tags To Write After Gen AC" }, + { 0xff8104, "Data To Send" }, + { 0xff8105, "Data Record" }, + { 0xff8106, "Discretionary Data" }, }; static int emv_sort_tag(tlv_tag_t tag) { From ce6320cdc1d130be3e17fbc4fe9f13287869c9f3 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 8 Jan 2019 19:22:27 +0200 Subject: [PATCH 068/320] change sc apdu to be compatible with 14a apdu --- client/cmdsmartcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index a864e2358..fdc825d38 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -533,7 +533,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave int len = smart_responseEx(dataout, true); if ( len < 0 ) { - return 2; + return 1; } // retry From 1fb79486232fc245ddbb0bbfeff226e6eafbe73f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 8 Jan 2019 19:49:31 +0200 Subject: [PATCH 069/320] emv commands now prints channel --- client/emv/cmdemv.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 396918d7e..206401917 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -40,6 +40,17 @@ void ParamLoadDefaults(struct tlvdb *tlvRoot) { TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC } +void PrintChannel(EMVCommandChannel channel) { + switch(channel) { + case ECC_CONTACTLESS: + PrintAndLogEx(INFO, "Channel: CONTACTLESS"); + break; + case ECC_CONTACT: + PrintAndLogEx(INFO, "Channel: CONTACT"); + break; + } +} + int CmdEMVSelect(const char *cmd) { uint8_t data[APDU_AID_LEN] = {0}; int datalen = 0; @@ -67,6 +78,7 @@ int CmdEMVSelect(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(5)) channel = ECC_CONTACT; + PrintChannel(channel); CLIGetHexWithReturn(6, data, &datalen); CLIParserFree(); @@ -114,6 +126,7 @@ int CmdEMVSearch(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(5)) channel = ECC_CONTACT; + PrintChannel(channel); CLIParserFree(); SetAPDULogging(APDULogging); @@ -170,6 +183,7 @@ int CmdEMVPPSE(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(7)) channel = ECC_CONTACT; + PrintChannel(channel); CLIParserFree(); SetAPDULogging(APDULogging); @@ -224,6 +238,7 @@ int CmdEMVGPO(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(6)) channel = ECC_CONTACT; + PrintChannel(channel); CLIGetHexWithReturn(7, data, &datalen); CLIParserFree(); @@ -317,6 +332,7 @@ int CmdEMVReadRecord(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(4)) channel = ECC_CONTACT; + PrintChannel(channel); CLIGetHexWithReturn(5, data, &datalen); CLIParserFree(); @@ -399,6 +415,7 @@ int CmdEMVAC(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(8)) channel = ECC_CONTACT; + PrintChannel(channel); CLIGetHexWithReturn(9, data, &datalen); CLIParserFree(); @@ -481,6 +498,7 @@ int CmdEMVGenerateChallenge(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(3)) channel = ECC_CONTACT; + PrintChannel(channel); CLIParserFree(); SetAPDULogging(APDULogging); @@ -539,6 +557,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(6)) channel = ECC_CONTACT; + PrintChannel(channel); CLIGetHexWithReturn(7, data, &datalen); CLIParserFree(); @@ -722,6 +741,7 @@ int CmdEMVExec(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(11)) channel = ECC_CONTACT; + PrintChannel(channel); uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; CLIParserFree(); @@ -1171,6 +1191,7 @@ int CmdEMVScan(const char *cmd) { EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(11)) channel = ECC_CONTACT; + PrintChannel(channel); uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; uint8_t relfname[250] ={0}; char *crelfname = (char *)relfname; @@ -1493,6 +1514,7 @@ int CmdEMVRoca(const char *cmd) { if (arg_get_lit(2)) channel = ECC_CONTACT; + PrintChannel(channel); // select card uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; From 7bb8c629ba67217d13fe19e604732e9c6d145048 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 20:14:46 +0100 Subject: [PATCH 070/320] fix: remove warnings --- client/cmdhfmf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 985965d72..00e29105f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1294,9 +1294,9 @@ int CmdHF14AMfNestedHard(const char *Cmd) { case 'r': fptr = GenerateFilename("hf-mf-","-nonces.bin"); if (fptr == NULL) - strncpy(filename,"nonces.bin", FILE_PATH_SIZE); + strncpy(filename, "nonces.bin", FILE_PATH_SIZE); else - strncpy(filename,fptr, FILE_PATH_SIZE); + strncpy(filename, fptr, FILE_PATH_SIZE-1); nonce_file_read = true; if (!param_gethex(Cmd, cmdp+1, trgkey, 12)) { @@ -1367,7 +1367,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) { fptr = GenerateFilename("hf-mf-","-nonces.bin"); if (fptr == NULL) return 1; - strncpy(filename, fptr, FILE_PATH_SIZE); + strncpy(filename, fptr, FILE_PATH_SIZE-1); break; case 'u': param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE-20); From d13541791b1ab4315d7d1aeb1d528bdcc8b6d872 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 8 Jan 2019 20:20:16 +0100 Subject: [PATCH 071/320] chg: tlvtag can be 4bytes.. --- client/emv/tlv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/tlv.h b/client/emv/tlv.h index e3c7c97fa..d2a55525f 100644 --- a/client/emv/tlv.h +++ b/client/emv/tlv.h @@ -22,7 +22,7 @@ #include #include -typedef uint16_t tlv_tag_t; +typedef uint32_t tlv_tag_t; struct tlv { tlv_tag_t tag; From 2612cd006a91538d36ba620aa0a6a1089d8680a2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 12:00:06 +0100 Subject: [PATCH 072/320] CHG: bigbuf adaptations --- armsrc/BigBuf.c | 14 +++++----- armsrc/BigBuf.h | 4 +-- armsrc/apps.h | 1 - armsrc/iso14443a.c | 69 +++++++++++++++++++++++++++------------------- armsrc/iso14443b.c | 2 +- 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 8f6bf9ca6..7b49c0619 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -30,8 +30,8 @@ static uint16_t BigBuf_hi = BIGBUF_SIZE; static uint8_t *emulator_memory = NULL; // trace related variables -static uint16_t traceLen = 0; -int tracing = 1; //Last global one.. todo static? +static uint32_t traceLen = 0; +static bool tracing = true; //todo static? // get the address of BigBuf uint8_t *BigBuf_get_addr(void) { @@ -112,7 +112,7 @@ uint16_t BigBuf_max_traceLen(void) { void clear_trace(void) { traceLen = 0; } -void set_tracelen(uint16_t value) { +void set_tracelen(uint32_t value) { traceLen = value; } void set_tracing(bool enable) { @@ -127,7 +127,7 @@ bool get_tracing(void) { * Get the number of bytes traced * @return */ -uint16_t BigBuf_get_traceLen(void) { +uint32_t BigBuf_get_traceLen(void) { return traceLen; } @@ -142,8 +142,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ uint8_t *trace = BigBuf_get_addr(); - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint16_t duration = timestamp_end - timestamp_start; + uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint32_t duration = timestamp_end - timestamp_start; // Return when trace is full if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) { @@ -204,7 +204,7 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP if (!tracing) return false; uint8_t *trace = BigBuf_get_addr(); - uint16_t iLen = nbytes(iBits); + uint32_t iLen = nbytes(iBits); // Return when trace is full if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false; diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index e8c6f5cd4..679eed676 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -36,10 +36,10 @@ extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); extern void BigBuf_print_status(void); -extern uint16_t BigBuf_get_traceLen(void); +extern uint32_t BigBuf_get_traceLen(void); extern void clear_trace(void); extern void set_tracing(bool enable); -extern void set_tracelen(uint16_t value); +extern void set_tracelen(uint32_t value); extern bool get_tracing(void); extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); extern int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader); diff --git a/armsrc/apps.h b/armsrc/apps.h index 1e8524d57..7e45d5e50 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -34,7 +34,6 @@ extern "C" { extern const uint8_t OddByteParity[256]; extern int rsamples; // = 0; -extern int tracing; // = TRUE; extern uint8_t trigger; // This may be used (sparingly) to declare a function to be copied to diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 91db762fc..257c39b1f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -651,7 +651,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { //----------------------------------------------------------------------------- static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity, bool collision) { - uint8_t localCol = 0; + //uint8_t localCol = 0; ToSendReset(); // Correction bit, might be removed when not needed @@ -673,24 +673,32 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par // Data bits for(uint16_t j = 0; j < 8; j++) { - if (collision && (localCol >= colpos)){ + //if (collision && (localCol >= colpos)){ + if (collision) { ToSend[++ToSendMax] = SEC_COLL; - } else if(b & 1) { - ToSend[++ToSendMax] = SEC_D; - } else { - ToSend[++ToSendMax] = SEC_E; + //localCol++; + } else { + if (b & 1) { + ToSend[++ToSendMax] = SEC_D; + } else { + ToSend[++ToSendMax] = SEC_E; + } + b >>= 1; } - b >>= 1; - localCol++; } - // Get the parity bit - if (parity[i>>3] & (0x80>>(i&0x0007))) { - ToSend[++ToSendMax] = SEC_D; - LastProxToAirDuration = 8 * ToSendMax - 4; + if (collision) { + ToSend[++ToSendMax] = SEC_COLL; + LastProxToAirDuration = 8 * ToSendMax; } else { - ToSend[++ToSendMax] = SEC_E; - LastProxToAirDuration = 8 * ToSendMax; + // Get the parity bit + if (parity[i>>3] & (0x80>>(i&0x0007))) { + ToSend[++ToSendMax] = SEC_D; + LastProxToAirDuration = 8 * ToSendMax - 4; + } else { + ToSend[++ToSendMax] = SEC_E; + LastProxToAirDuration = 8 * ToSendMax; + } } } @@ -795,12 +803,12 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe // Make sure we do not exceed the free buffer space if (ToSendMax > max_buffer_size) { Dbprintf("Out of memory, when modulating bits for tag answer:"); - Dbhexdump(response_info->response_n,response_info->response,false); + Dbhexdump(response_info->response_n, response_info->response, false); return false; } // Copy the byte array, used for this modulation to the buffer position - memcpy(response_info->modulation,ToSend,ToSendMax); + memcpy(response_info->modulation, ToSend, ToSendMax); // Store the number of bytes that were used for encoding/modulation and the time needed to transfer them response_info->modulation_n = ToSendMax; @@ -1047,7 +1055,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { // Clean receive command buffer if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { - Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); break; } p_response = NULL; @@ -1836,15 +1844,17 @@ void iso14443a_antifuzz(uint32_t flags){ // allocate buffers: uint8_t *received = BigBuf_malloc(MAX_FRAME_SIZE); uint8_t *receivedPar = BigBuf_malloc(MAX_PARITY_SIZE); - uint8_t *resp = BigBuf_malloc(8); + uint8_t *resp = BigBuf_malloc(20); + memset(resp, 0xFF , 20); + LED_A_ON(); for (;;) { WDT_HIT(); // Clean receive command buffer if (!GetIso14443aCommandFromReader(received, receivedPar, &len)) { - Dbprintf("Anti-fuzz stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); + Dbprintf("Anti-fuzz stopped. Trace length: %d ", BigBuf_get_traceLen()); break; } if ( received[0] == ISO14443A_CMD_WUPA || received[0] == ISO14443A_CMD_REQA) { @@ -1860,21 +1870,24 @@ void iso14443a_antifuzz(uint32_t flags){ } // Received request for UID (cascade 1) - if (received[1] >= 0x20 && received[1] <= 0x57 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { - resp[0] = 0x04; - resp[1] = 0x1C; - resp[2] = 0xE1; - resp[3] = 0xCE; + //if (received[1] >= 0x20 && received[1] <= 0x57 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { + if (received[1] >= 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { + resp[0] = 0xFF; + resp[1] = 0xFF; + resp[2] = 0xFF; + resp[3] = 0xFF; + resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3]; colpos = 0; if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { resp[0] = 0x88; colpos = 8; } - - EmSendCmdEx(resp, 4, true); - if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); + EmSendCmdEx(resp, 5, true); + if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); + LED_D_INV(); + continue; } else if (received[1] == 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT_2"); @@ -3489,7 +3502,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } if (MF_DBGLEVEL >= 1) - Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); cmd_send(CMD_ACK,1,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index edf114134..6167ca785 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -710,7 +710,7 @@ void SimulateIso14443bTag(uint32_t pupi) { ++cmdsReceived; } if (MF_DBGLEVEL >= 2) - Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); switch_off(); //simulate } From 6743e45386770e4e171bee638761144f6d8c529e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 12:05:29 +0100 Subject: [PATCH 073/320] CHG: name changes --- armsrc/felica.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index aa6712268..d1e7bc344 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -29,27 +29,25 @@ static uint32_t felica_timeout; static uint32_t felica_nexttransfertime; static uint32_t felica_lasttime_prox2air_start; -static void felica_setup(uint8_t fpga_minor_mode); +static void iso18092_setup(uint8_t fpga_minor_mode); static uint8_t felica_select_card(felica_card_select_t *card); static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed); bool WaitForFelicaReply(uint16_t maxbytes); -void felica_set_timeout(uint32_t timeout) { +void iso18092_set_timeout(uint32_t timeout) { felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; } -uint32_t felica_get_timeout(void) { +uint32_t iso18092_get_timeout(void) { return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) - 2; } -//random service RW: 0x0009 -//random service RO: 0x000B -#ifndef NFC_MAX_FRAME_SIZE - #define NFC_MAX_FRAME_SIZE 260 +#ifndef FELICA_MAX_FRAME_SIZE + #define FELICA_MAX_FRAME_SIZE 260 #endif //structure to hold outgoing NFC frame -static uint8_t frameSpace[NFC_MAX_FRAME_SIZE+4]; +static uint8_t frameSpace[FELICA_MAX_FRAME_SIZE+4]; //structure to hold incoming NFC frame, used for ISO/IEC 18092-compatible frames static struct { @@ -85,7 +83,7 @@ static void FelicaFrameReset() { FelicaFrame.crc_ok = false; FelicaFrame.byte_offset = 0; } -static void NFCInit(uint8_t *data) { +static void FelicaFrameinit(uint8_t *data) { FelicaFrame.framebytes = data; FelicaFrameReset(); } @@ -105,7 +103,7 @@ static void shiftInByte(uint8_t bt) { } } -static void ProcessNFCByte(uint8_t bt) { +static void Process18092Byte(uint8_t bt) { switch (FelicaFrame.state) { case STATE_UNSYNCD: { //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case @@ -127,7 +125,7 @@ static void ProcessNFCByte(uint8_t bt) { //SYNC done! FelicaFrame.state = STATE_GET_LENGTH; FelicaFrame.framebytes[0] = 0xb2; - FelicaFrame.framebytes[1] = 0x4d; //write SYNC + FelicaFrame.framebytes[1] = 0x4d; FelicaFrame.byte_offset = i; //shift in remaining byte, slowly... for(uint8_t j=i; j<8; j++) { @@ -269,7 +267,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) { if (blocknum > 4 || blocknum <= 0) - Dbprintf("Invalid number of blocks, %d. Up to 4 are allowed.", blocknum); + Dbprintf("Invalid number of blocks, %d != 4", blocknum); uint8_t c = 0, i = 0; @@ -394,13 +392,13 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - uint32_t timeout = felica_get_timeout(); + uint32_t timeout = iso18092_get_timeout(); for(;;) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); - ProcessNFCByte(b); + Process18092Byte(b); if (FelicaFrame.state == STATE_FULL) { felica_nexttransfertime = MAX( @@ -432,7 +430,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" -static void felica_setup(uint8_t fpga_minor_mode) { +static void iso18092_setup(uint8_t fpga_minor_mode) { LEDsoff(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -442,11 +440,13 @@ static void felica_setup(uint8_t fpga_minor_mode) { // Initialize Demod and Uart structs //DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - NFCInit(BigBuf_malloc(NFC_MAX_FRAME_SIZE)); + FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; - felica_set_timeout(2120); // 106 * 20ms maximum start-up time of card + iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card + init_table(CRC_FELICA); + // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -455,8 +455,6 @@ static void felica_setup(uint8_t fpga_minor_mode) { // LSB transfer. Remember to set it back to MSB with AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - - init_table(CRC_FELICA); // Signal field is on with the appropriate LED FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | fpga_minor_mode); @@ -492,7 +490,7 @@ void felica_sendraw(UsbCommand *c) { set_tracing(true); if ((param & FELICA_CONNECT)) { - felica_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); // notify client selecting status. // if failed selecting, turn off antenna and quite. @@ -547,7 +545,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { Dbprintf("Snoop FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); - felica_setup( FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); //the frame bits are slow enough. int n = BigBuf_max_traceLen() / sizeof(uint8_t); // take all memory @@ -563,7 +561,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); - ProcessNFCByte(dist); + Process18092Byte(dist); //to be sure we are in frame if (FelicaFrame.state == STATE_GET_LENGTH) { @@ -643,7 +641,7 @@ void felica_sim_lite(uint64_t nfcid) { AddCrc(resp_poll1, resp_poll1[2]); AddCrc(resp_readblk, resp_readblk[2]); - felica_setup( FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); bool listenmode = true; //uint32_t frtm = GetCountSspClk(); @@ -657,7 +655,7 @@ void felica_sim_lite(uint64_t nfcid) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); //frtm = GetCountSspClk(); - ProcessNFCByte(dist); + Process18092Byte(dist); if (FelicaFrame.state == STATE_FULL) { @@ -725,7 +723,7 @@ void felica_dump_lite_s() { uint16_t liteblks[28] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x90,0x91,0x92,0xa0}; // setup device. - felica_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); uint8_t blknum; bool isOK = false; From 8f18a9abf21b69a91abefb7b949c91dc20abf082 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 12:07:07 +0100 Subject: [PATCH 074/320] CHG: tvl tag length adapted --- client/emv/emvjson.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 116e16da1..f8cccddf2 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -372,13 +372,13 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { size_t buflen = 0; // here max length must be 4, but now tlv_tag_t is 2-byte var. so let it be 2 by now... TODO: needs refactoring tlv_tag_t... - if (!HexToBuffer("TLV Error type:", tlvTag, buf, 2, &buflen)) { + if (!HexToBuffer("TLV Error type:", tlvTag, buf, 4, &buflen)) { json_decref(root); return false; } tlv_tag_t tag = 0; for (int i = 0; i < buflen; i++) { - tag = (tag << 8) + buf[i]; + tag = (tag << 8) | buf[i]; } if (!HexToBuffer("TLV Error value:", tlvValue, buf, sizeof(buf) - 1, &buflen)) { From 96361abd973cbccb0576aa200885cb0b176f3dcb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 12:28:56 +0100 Subject: [PATCH 075/320] FIX: supress gcc warnings like libjansson https://github.com/akheron/jansson/pull/423/files --- client/jansson/Makefile | 2 +- client/jansson/error.c | 2 +- client/jansson/load.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/jansson/Makefile b/client/jansson/Makefile index 7657e35f3..596c1778c 100644 --- a/client/jansson/Makefile +++ b/client/jansson/Makefile @@ -32,7 +32,7 @@ CMDOBJS = $(CFILES:%.c=%.o) CLEAN = $(CMDOBJS) CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function +CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -Wno-format-truncation LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS) LIBS= $(SYSLIBS) $(MYLIBS) DEFAULT_INCLUDES = -I. diff --git a/client/jansson/error.c b/client/jansson/error.c index f5da6b9b0..b94b3a3a1 100644 --- a/client/jansson/error.c +++ b/client/jansson/error.c @@ -25,7 +25,7 @@ void jsonp_error_set_source(json_error_t *error, const char *source) length = strlen(source); if(length < JSON_ERROR_SOURCE_LENGTH) - strncpy(error->source, source, length + 1); + strncpy(error->source, source, JSON_ERROR_SOURCE_LENGTH); else { size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; memcpy(error->source, "...", 3); diff --git a/client/jansson/load.c b/client/jansson/load.c index 9f73ea02c..2f123724e 100644 --- a/client/jansson/load.c +++ b/client/jansson/load.c @@ -89,7 +89,7 @@ static void error_set(json_error_t *error, const lex_t *lex, { va_list ap; char msg_text[JSON_ERROR_TEXT_LENGTH]; - char msg_with_context[JSON_ERROR_TEXT_LENGTH + 20]; + char msg_with_context[JSON_ERROR_TEXT_LENGTH]; int line = -1, col = -1; size_t pos = 0; @@ -115,7 +115,7 @@ static void error_set(json_error_t *error, const lex_t *lex, { if(lex->saved_text.length <= 20) { snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", msg_text, saved_text); - msg_with_context[JSON_ERROR_TEXT_LENGTH + 20 - 1] = '\0'; + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; result = msg_with_context; } } @@ -131,7 +131,7 @@ static void error_set(json_error_t *error, const lex_t *lex, } else { snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", msg_text); - msg_with_context[JSON_ERROR_TEXT_LENGTH + 20 - 1] = '\0'; + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; result = msg_with_context; } } From 4880316ab932d983bda83ff7600b2071e122f24e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 15:20:18 +0200 Subject: [PATCH 076/320] fix hash --- client/emv/emv_pki.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index be4dfa0a7..602dcacce 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -109,10 +109,12 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, } va_end(vl); - if (memcmp(data + data_len - 1 - hash_len, crypto_hash_read(ch), hash_len)) { + uint8_t hash[20] = {0}; + memcpy(hash, crypto_hash_read(ch), hash_len); + if (memcmp(data + data_len - 1 - hash_len, hash, hash_len)) { printf("ERROR: Calculated wrong hash\n"); printf("decoded: %s\n",sprint_hex(data + data_len - 1 - hash_len, hash_len)); - printf("calculated: %s\n",sprint_hex(crypto_hash_read(ch), hash_len)); + printf("calculated: %s\n",sprint_hex(hash, hash_len)); if (strictExecution) { crypto_hash_close(ch); From 010492a87e47326c32040cd5495eb4baf3f2f991 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 17:04:21 +0200 Subject: [PATCH 077/320] input list build fixed --- client/emv/cmdemv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 206401917..a21337d03 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -892,7 +892,7 @@ int CmdEMVExec(const char *cmd) { // Build Input list for Offline Data Authentication // EMV 4.3 book3 10.3, page 96 - if (SFIoffline) { + if (SFIoffline > 0) { if (SFI < 11) { const unsigned char *abuf = buf; size_t elmlen = len; @@ -907,6 +907,8 @@ int CmdEMVExec(const char *cmd) { memcpy(&ODAiList[ODAiListLen], buf, len); ODAiListLen += len; } + + SFIoffline--; } } } From 4a38ab7be4a8c20c761ea5abbb12365ef2734b7b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 17:08:23 +0200 Subject: [PATCH 078/320] small fix --- client/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a21337d03..0cc6614d9 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -870,7 +870,7 @@ int CmdEMVExec(const char *cmd) { uint8_t SFIend = AFL->value[i * 4 + 2]; uint8_t SFIoffline = AFL->value[i * 4 + 3]; - PrintAndLogEx(NORMAL, "* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); + PrintAndLogEx(NORMAL, "* * SFI[%02x] start:%02x end:%02x offline count:%02x", SFI, SFIstart, SFIend, SFIoffline); if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) { PrintAndLogEx(NORMAL, "SFI ERROR! Skipped..."); continue; From e276bf1ce326f88ef8bbebd27ae1d77e7e3ca12e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 16:25:49 +0100 Subject: [PATCH 079/320] FIX: gcc8.1 warnings --- armsrc/tlv.c | 75 ++++++++++++++++++++++++---------------- armsrc/tlv.h | 13 ++++--- client/crypto/asn1dump.c | 4 ++- client/emv/emvjson.c | 1 - client/util.c | 2 +- 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/armsrc/tlv.c b/armsrc/tlv.c index 3da03492f..839b34d66 100644 --- a/armsrc/tlv.c +++ b/armsrc/tlv.c @@ -2,7 +2,7 @@ int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag) { - uint8_t tag[TAG_LENGTH] = {0x00,0x00}; + uint8_t tag[TAG_LENGTH] = {0x00, 0x00, 0x00, 0x00}; uint16_t length = 0; //uint8_t value[VALUE_LENGTH]; uint8_t lenlen = 0; @@ -10,40 +10,44 @@ int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag) int z = 0; //decode tag tag[0] = data[0]; - if((tag[0] & TLV_TAG_NUMBER_MASK) == TLV_TAG_NUMBER_MASK) { //see subsequent bytes + if ((tag[0] & TLV_TAG_NUMBER_MASK) == TLV_TAG_NUMBER_MASK) { //see subsequent bytes i++; - tag[i] = data[i]; - //assume tag is only two bytes long for now - /* - while((data[i] & TLV_TAG_MASK) == TLV_TAG_MASK){ - i++; - tag[i] = data[i]; - } - */ + + tag[i] = data[i]; + + while((data[i] & TLV_TAG_MASK) == TLV_TAG_MASK){ + i++; + tag[i] = data[i]; + } + } i++; //decode length - if((data[i] & TLV_LENGTH_MASK) == TLV_LENGTH_MASK) { + if ((data[i] & TLV_LENGTH_MASK) == TLV_LENGTH_MASK) { lenlen = data[i] ^ TLV_LENGTH_MASK; i++; length = (uint16_t)data[i]; z = 1; - while(z < lenlen){ + while (z < lenlen) { i++; z++; length <<= 8; length += (uint16_t)data[i]; } i++; - } - else { + } else { length = (uint16_t)data[i]; i++; } - //copy results into the structure and return + // copy results into the structure and return memcpy(returnedtag->tag, tag, TAG_LENGTH); - (*returnedtag).valuelength = length; //return length of tag value - (*returnedtag).fieldlength = length + i + 1; //return length of total field + + // return length of tag value + (*returnedtag).valuelength = length; + + // return length of total field + (*returnedtag).fieldlength = length + i + 1; + memcpy(returnedtag->value, &(data[i]), length); return 0; } @@ -51,27 +55,40 @@ int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag) //generate a TLV tag off input data int encode_ber_tlv_item(uint8_t* tag, uint8_t taglen, uint8_t* data, uint32_t datalen, uint8_t* outputtag, uint32_t* outputtaglen) { - if(!tag || !data || !outputtag || !outputtaglen) //null pointer check + if (!tag || !data || !outputtag || !outputtaglen) return 0; - uint8_t datafieldlen = (datalen / 128) + 1; //field length of the tag - uint8_t tlvtotallen = taglen + datafieldlen + datalen; //total length of the tag - uint8_t returnedtag[tlvtotallen]; //buffer for the returned tag + // field length of the tag + uint8_t datafieldlen = (datalen / 128) + 1; + + // total length of the tag + uint8_t tlvtotallen = taglen + datafieldlen + datalen; + + // buffer for the returned tag + uint8_t returnedtag[tlvtotallen]; + uint8_t counter = 0; - memcpy(returnedtag, tag, taglen); //copy tag into buffer + + // copy tag into buffer + memcpy(returnedtag, tag, taglen); counter += taglen; - if(datalen < 128){ // 1 byte length value + + // 1 byte length value + if (datalen < 128){ returnedtag[counter++] = datalen; - } - else{ - returnedtag[counter++] = datafieldlen | 0x80; //high bit set and number of length bytes - for(uint8_t i=datafieldlen; i !=0; i--){ - returnedtag[counter++] = (datalen >> (i * 8)) & 0xFF; //get current byte + } else { + + // high bit set and number of length bytes + returnedtag[counter++] = datafieldlen | 0x80; + + for (uint8_t i = datafieldlen; i !=0; i--) { + // get current byte + returnedtag[counter++] = (datalen >> (i * 8)) & 0xFF; } } memcpy(&returnedtag[counter], data, datalen); *outputtaglen = tlvtotallen; - memcpy(outputtag, returnedtag,tlvtotallen); + memcpy(outputtag, returnedtag, tlvtotallen); return 0; } diff --git a/armsrc/tlv.h b/armsrc/tlv.h index c90756168..de8180cab 100644 --- a/armsrc/tlv.h +++ b/armsrc/tlv.h @@ -6,8 +6,13 @@ #include //structure buffer definitions -#define TAG_LENGTH 2 -#define VALUE_LENGTH 1024 +#ifndef TAG_LENGTH +# define TAG_LENGTH 4 +#endif + +#ifndef VALUE_LENGTH +# define VALUE_LENGTH 1024 +#endif //masks //if TLV_TAG_NUMBER_MASK bits are set, refer to the next byte for the tag number @@ -19,13 +24,13 @@ #define TLV_TAG_MASK 0x80 #define TLV_LENGTH_MASK 0x80 -//tlv tag structure, tag can be max of 2 bytes, length up to 65535 and value 1024 bytes long +//tlv tag structure, tag can be max of 4 bytes, length up to 0xFFFFFFFF and value 1024 bytes long typedef struct { uint8_t tag[TAG_LENGTH]; uint16_t fieldlength; uint16_t valuelength; uint8_t value[VALUE_LENGTH]; -}tlvtag; +} tlvtag; //decode a BER TLV extern int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag); diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 34f4a9fa4..52814f22b 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -24,7 +24,9 @@ #include "util.h" #include "proxmark3.h" -#define PRINT_INDENT(level) {for (int i = 0; i < (level); i++) fprintf(f, " ");} +#ifndef PRINT_INDENT +# define PRINT_INDENT(level) {for (int i = 0; i < (level); i++) fprintf(f, " ");} +#endif enum asn1_tag_t { ASN1_TAG_GENERIC, diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index f8cccddf2..45eb1f430 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -371,7 +371,6 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { uint8_t buf[251] = {0}; size_t buflen = 0; - // here max length must be 4, but now tlv_tag_t is 2-byte var. so let it be 2 by now... TODO: needs refactoring tlv_tag_t... if (!HexToBuffer("TLV Error type:", tlvTag, buf, 4, &buflen)) { json_decref(root); return false; diff --git a/client/util.c b/client/util.c index 5d7ce0370..b22258d44 100644 --- a/client/util.c +++ b/client/util.c @@ -212,7 +212,7 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { } char *sprint_hex(const uint8_t *data, const size_t len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true); return buf; } From 8a514ea8f10f91d7b30dd10017480b5bf20a5868 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Jan 2019 16:28:06 +0100 Subject: [PATCH 080/320] REM: remove unused files --- armsrc/tlv.c | 94 ---------------------------------------------------- armsrc/tlv.h | 38 --------------------- 2 files changed, 132 deletions(-) delete mode 100644 armsrc/tlv.c delete mode 100644 armsrc/tlv.h diff --git a/armsrc/tlv.c b/armsrc/tlv.c deleted file mode 100644 index 839b34d66..000000000 --- a/armsrc/tlv.c +++ /dev/null @@ -1,94 +0,0 @@ -#include - -int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag) -{ - uint8_t tag[TAG_LENGTH] = {0x00, 0x00, 0x00, 0x00}; - uint16_t length = 0; - //uint8_t value[VALUE_LENGTH]; - uint8_t lenlen = 0; - int i = 0; - int z = 0; - //decode tag - tag[0] = data[0]; - if ((tag[0] & TLV_TAG_NUMBER_MASK) == TLV_TAG_NUMBER_MASK) { //see subsequent bytes - i++; - - tag[i] = data[i]; - - while((data[i] & TLV_TAG_MASK) == TLV_TAG_MASK){ - i++; - tag[i] = data[i]; - } - - } - i++; - //decode length - if ((data[i] & TLV_LENGTH_MASK) == TLV_LENGTH_MASK) { - lenlen = data[i] ^ TLV_LENGTH_MASK; - i++; - length = (uint16_t)data[i]; - z = 1; - while (z < lenlen) { - i++; - z++; - length <<= 8; - length += (uint16_t)data[i]; - } - i++; - } else { - length = (uint16_t)data[i]; - i++; - } - // copy results into the structure and return - memcpy(returnedtag->tag, tag, TAG_LENGTH); - - // return length of tag value - (*returnedtag).valuelength = length; - - // return length of total field - (*returnedtag).fieldlength = length + i + 1; - - memcpy(returnedtag->value, &(data[i]), length); - return 0; -} - -//generate a TLV tag off input data -int encode_ber_tlv_item(uint8_t* tag, uint8_t taglen, uint8_t* data, uint32_t datalen, uint8_t* outputtag, uint32_t* outputtaglen) -{ - if (!tag || !data || !outputtag || !outputtaglen) - return 0; - - // field length of the tag - uint8_t datafieldlen = (datalen / 128) + 1; - - // total length of the tag - uint8_t tlvtotallen = taglen + datafieldlen + datalen; - - // buffer for the returned tag - uint8_t returnedtag[tlvtotallen]; - - uint8_t counter = 0; - - // copy tag into buffer - memcpy(returnedtag, tag, taglen); - counter += taglen; - - // 1 byte length value - if (datalen < 128){ - returnedtag[counter++] = datalen; - } else { - - // high bit set and number of length bytes - returnedtag[counter++] = datafieldlen | 0x80; - - for (uint8_t i = datafieldlen; i !=0; i--) { - // get current byte - returnedtag[counter++] = (datalen >> (i * 8)) & 0xFF; - } - } - memcpy(&returnedtag[counter], data, datalen); - *outputtaglen = tlvtotallen; - memcpy(outputtag, returnedtag, tlvtotallen); - return 0; -} - diff --git a/armsrc/tlv.h b/armsrc/tlv.h deleted file mode 100644 index de8180cab..000000000 --- a/armsrc/tlv.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __TLV_H -#define __TLV_H - -#include -#include -#include - -//structure buffer definitions -#ifndef TAG_LENGTH -# define TAG_LENGTH 4 -#endif - -#ifndef VALUE_LENGTH -# define VALUE_LENGTH 1024 -#endif - -//masks -//if TLV_TAG_NUMBER_MASK bits are set, refer to the next byte for the tag number -//otherwise its located in bits 1-5 -#define TLV_TAG_NUMBER_MASK 0x1f -//if TLV_DATA_MASK set then its a 'constructed data object' -//otherwise a 'primitive data object' -#define TLV_DATA_MASK 0x20 -#define TLV_TAG_MASK 0x80 -#define TLV_LENGTH_MASK 0x80 - -//tlv tag structure, tag can be max of 4 bytes, length up to 0xFFFFFFFF and value 1024 bytes long -typedef struct { - uint8_t tag[TAG_LENGTH]; - uint16_t fieldlength; - uint16_t valuelength; - uint8_t value[VALUE_LENGTH]; -} tlvtag; - -//decode a BER TLV -extern int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag); -extern int encode_ber_tlv_item(uint8_t* tag, uint8_t taglen, uint8_t*data, uint32_t datalen, uint8_t* outputtag, uint32_t* outputtaglen); -#endif //__TLV_H From 88b2cf41de9f3793faf942c35de365e6c561f194 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 18:46:55 +0200 Subject: [PATCH 081/320] add description --- client/emv/emvcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 621287031..b672004c3 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -781,7 +781,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(NORMAL, "SDA verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { PrintAndLogEx(WARNING, "Error: SSAD verify error"); From 506da60cad7bf9d952deff2bb855add1369123ff Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 18:47:26 +0200 Subject: [PATCH 082/320] hash init --- client/emv/emv_pki.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index 602dcacce..593c8a00c 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -109,7 +109,8 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, } va_end(vl); - uint8_t hash[20] = {0}; + uint8_t hash[hash_len]; + memset(hash, 0, hash_len); memcpy(hash, crypto_hash_read(ch), hash_len); if (memcmp(data + data_len - 1 - hash_len, hash, hash_len)) { printf("ERROR: Calculated wrong hash\n"); From 20d29f35e5f9e0889539479b1ac5f1f3aa077f65 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 19:32:08 +0200 Subject: [PATCH 083/320] SDA works --- client/emv/emv_pki.c | 43 +++++++++++++++++++++++++++++++++++++++++++ client/emv/emvcore.c | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index 593c8a00c..40edc79e4 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -313,14 +313,57 @@ struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb NULL); } +unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len) { + uint8_t buf[2048] = {0}; + size_t len = 0; + + *sdatl_len = 0; + + const struct tlv *sda_tl = tlvdb_get(db, 0x9f4a, NULL); + if (!sda_tl || sda_tl->len <= 0) + return NULL; + + for (int i = 0; i < sda_tl->len; i++) { + uint32_t tag = sda_tl->value[i]; // here may be multibyte, but now not + const struct tlv *elm = tlvdb_get(db, tag, NULL); + if (elm) { + memcpy(&buf[len], elm->value, elm->len); + len += elm->len; + } + } + + if (len) { + *sdatl_len = len; + unsigned char *value = malloc(len); + memcpy(value, buf, len); + return value; + } + + return NULL; +} + + struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv, bool showData) { size_t data_len; + + // Static Data Authentication Tag List + size_t sdatl_len; + unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len); + struct tlv sda_tdata = { + .tag = 0x00, // dummy tag + .len = sdatl_len, + .value = sdatl + }; + unsigned char *data = emv_pki_decode_message(enc_pk, 3, &data_len, tlvdb_get(db, 0x93, NULL), sda_tlv, + &sda_tdata, NULL); + free(sdatl); // malloc here: emv_pki_sdatl_fill + if (!data || data_len < 5) return NULL; diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index b672004c3..743fa2f9e 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -653,7 +653,7 @@ int trSDA(struct tlvdb *tlv) { struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(NORMAL, "SDA verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { emv_pk_free(issuer_pk); From 4921308d8465051346065f94a4033f2463f63dfd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 21:03:56 +0200 Subject: [PATCH 084/320] some changes in DDA --- client/emv/emvcore.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 743fa2f9e..c4b815715 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -596,7 +596,7 @@ int EMVGenerateChallenge(EMVCommandChannel channel, bool LeaveFieldON, uint8_t * } int EMVInternalAuthenticate(EMVCommandChannel channel, bool LeaveFieldON, uint8_t *DDOL, size_t DDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { - return EMVExchange(channel, LeaveFieldON, (sAPDU){0x00, 0x88, 0x00, 0x00, DDOLLen, DDOL}, Result, MaxResultLen, ResultLen, sw, tlv); + return EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU){0x00, 0x88, 0x00, 0x00, DDOLLen, DDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv); } int MSCComputeCryptoChecksum(EMVCommandChannel channel, bool LeaveFieldON, uint8_t *UDOL, uint8_t UDOLlen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { @@ -682,12 +682,12 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { } const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); - if (!sda_tlv || sda_tlv->len < 1) { +/* if (!sda_tlv || sda_tlv->len < 1) { it may be 0!!!! emv_pk_free(pk); PrintAndLogEx(WARNING, "Error: Can't find input list for Offline Data Authentication. Exit."); return 3; } - +*/ struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { emv_pk_free(pk); @@ -710,7 +710,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLogEx(WARNING, "Error: ICC setrificate not found. Exit."); + PrintAndLogEx(WARNING, "Error: ICC certificate not found. Exit."); return 2; } PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", @@ -725,21 +725,25 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { icc_pk->serial[2] ); - struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv); - if (!icc_pe_pk) { - PrintAndLogEx(WARNING, "WARNING: ICC PE PK recover error. "); + if (tlvdb_get(tlv, 0x9f2d, NULL)) { + struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv); + if (!icc_pe_pk) { + PrintAndLogEx(WARNING, "WARNING: ICC PE PK recover error. "); + } else { + PrintAndLogEx(SUCCESS, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", + icc_pe_pk->rid[0], + icc_pe_pk->rid[1], + icc_pe_pk->rid[2], + icc_pe_pk->rid[3], + icc_pe_pk->rid[4], + icc_pe_pk->index, + icc_pe_pk->serial[0], + icc_pe_pk->serial[1], + icc_pe_pk->serial[2] + ); + } } else { - PrintAndLogEx(SUCCESS, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - icc_pe_pk->rid[0], - icc_pe_pk->rid[1], - icc_pe_pk->rid[2], - icc_pe_pk->rid[3], - icc_pe_pk->rid[4], - icc_pe_pk->index, - icc_pe_pk->serial[0], - icc_pe_pk->serial[1], - icc_pe_pk->serial[2] - ); + PrintAndLogEx(INFO, "ICC PE PK (PIN Encipherment Public Key Certificate) not found.\n"); } // 9F4B: Signed Dynamic Application Data From 56c0dad966fa7d0340333819dfaa1e87fcc13487 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 9 Jan 2019 21:05:52 +0200 Subject: [PATCH 085/320] changes in cert decoding logic --- client/emv/emv_pki.c | 39 +++++++++++++++++++++++++++++++-------- client/emv/emv_pki.h | 1 + 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index 40edc79e4..84224a957 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -41,7 +41,8 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, uint8_t msgtype, size_t *len, const struct tlv *cert_tlv, - ... /* A list of tlv pointers, end with NULL */ + int tlv_count, + ... /* A list of tlv pointers */ ) { struct crypto_pk *kcp; @@ -99,11 +100,11 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, size_t hash_len = crypto_hash_get_size(ch); crypto_hash_write(ch, data + 1, data_len - 2 - hash_len); - va_start(vl, cert_tlv); - while (true) { + va_start(vl, tlv_count); + for (int i = 0; i < tlv_count; i++) { const struct tlv *add_tlv = va_arg(vl, const struct tlv *); if (!add_tlv) - break; + continue; crypto_hash_write(ch, add_tlv->value, add_tlv->len); } @@ -168,6 +169,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, const struct tlv *exp_tlv, const struct tlv *rem_tlv, const struct tlv *add_tlv, + const struct tlv *sdatl_tlv, bool showData ) { @@ -193,9 +195,11 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, data = emv_pki_decode_message(enc_pk, msgtype, &data_len, cert_tlv, + 5, rem_tlv, exp_tlv, add_tlv, + sdatl_tlv, NULL); if (!data || data_len < 11 + pan_length) { printf("ERROR: Can't decode message\n"); @@ -278,9 +282,10 @@ static struct emv_pk *emv_pki_decode_key(const struct emv_pk *enc_pk, const struct tlv *cert_tlv, const struct tlv *exp_tlv, const struct tlv *rem_tlv, - const struct tlv *add_tlv + const struct tlv *add_tlv, + const struct tlv *sdatl_tlv ) { - return emv_pki_decode_key_ex(enc_pk, msgtype, pan_tlv, cert_tlv, exp_tlv, rem_tlv, add_tlv, false); + return emv_pki_decode_key_ex(enc_pk, msgtype, pan_tlv, cert_tlv, exp_tlv, rem_tlv, add_tlv, sdatl_tlv, false); } struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db) @@ -290,17 +295,30 @@ struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb tlvdb_get(db, 0x90, NULL), tlvdb_get(db, 0x9f32, NULL), tlvdb_get(db, 0x92, NULL), + NULL, NULL); } struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv) { - return emv_pki_decode_key(pk, 4, + size_t sdatl_len; + unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len); + struct tlv sda_tdata = { + .tag = 0x00, // dummy tag + .len = sdatl_len, + .value = sdatl + }; + + struct emv_pk *res = emv_pki_decode_key(pk, 4, tlvdb_get(db, 0x5a, NULL), tlvdb_get(db, 0x9f46, NULL), tlvdb_get(db, 0x9f47, NULL), tlvdb_get(db, 0x9f48, NULL), - sda_tlv); + sda_tlv, + &sda_tdata); + + free(sdatl); // malloc here: emv_pki_sdatl_fill + return res; } struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db) @@ -310,6 +328,7 @@ struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb tlvdb_get(db, 0x9f2d, NULL), tlvdb_get(db, 0x9f2e, NULL), tlvdb_get(db, 0x9f2f, NULL), + NULL, NULL); } @@ -358,6 +377,7 @@ struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct t unsigned char *data = emv_pki_decode_message(enc_pk, 3, &data_len, tlvdb_get(db, 0x93, NULL), + 3, sda_tlv, &sda_tdata, NULL); @@ -391,6 +411,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t size_t data_len; unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len, tlvdb_get(db, 0x9f4b, NULL), + 2, dyn_tlv, NULL); @@ -426,6 +447,7 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t size_t data_len; unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len, tlvdb_get(db, 0x9f4b, NULL), + 5, tlvdb_get(db, 0x9f37, NULL), tlvdb_get(db, 0x9f02, NULL), tlvdb_get(db, 0x5f2a, NULL), @@ -502,6 +524,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t size_t data_len = 0; unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len, tlvdb_get(this_db, 0x9f4b, NULL), + 2, un_tlv, NULL); if (!data || data_len < 3) { diff --git a/client/emv/emv_pki.h b/client/emv/emv_pki.h index 6fa7b12e9..f5d80bd6d 100644 --- a/client/emv/emv_pki.h +++ b/client/emv/emv_pki.h @@ -23,6 +23,7 @@ extern void PKISetStrictExecution(bool se); +unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len); struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db); struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv); struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db); From 0ac728f0d47ee644120c8e44df68663595b5be99 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 13:06:56 +0200 Subject: [PATCH 086/320] VSDC path sketch --- client/emv/cmdemv.c | 11 +++++++++-- client/emv/emvcore.c | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 0cc6614d9..708e0d562 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -731,9 +731,9 @@ int CmdEMVExec(const char *cmd) { enum TransactionType TrType = TT_MSD; if (arg_get_lit(7)) - TrType = TT_QVSDCMCHIP; + TrType = TT_QVSDCMCHIP; if (arg_get_lit(8)) - TrType = TT_CDA; + TrType = TT_CDA; if (arg_get_lit(9)) TrType = TT_VSDC; @@ -1130,6 +1130,13 @@ int CmdEMVExec(const char *cmd) { } } + // VSDC + if (GetCardPSVendor(AID, AIDlen) == CV_VISA && (TrType == TT_VSDC)){ + PrintAndLogEx(NORMAL, "\n--> VSDC transaction."); + + + } + DropField(); // Destroy TLV's diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index c4b815715..a7d625af8 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -785,7 +785,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SDA verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(NORMAL, "SDAD verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { PrintAndLogEx(WARNING, "Error: SSAD verify error"); From 8240639d73bf1114c414fc2a6dcb190bc6dabe61 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 13:22:27 +0200 Subject: [PATCH 087/320] fill VSDC with only AC1 --- client/emv/cmdemv.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 708e0d562..46ed20165 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1134,6 +1134,34 @@ int CmdEMVExec(const char *cmd) { if (GetCardPSVendor(AID, AIDlen) == CV_VISA && (TrType == TT_VSDC)){ PrintAndLogEx(NORMAL, "\n--> VSDC transaction."); + PrintAndLogEx(NORMAL, "* * Calc CDOL1"); + struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag + if (!cdol_data_tlv) { + PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV."); + dreturn(6); + } + + PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + + PrintAndLogEx(NORMAL, "* * AC1"); + // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD + res = EMVAC(channel, true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot); + + if (res) { + PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw); + dreturn(7); + } + + if (decodeTLV) + TLVPrintFromBuffer(buf, len); + + PrintAndLogEx(NORMAL, "\n* * Processing online request\n"); + + // authorization response code from acquirer + const char HostResponse[] = "0"; + PrintAndLogEx(NORMAL, "* * Host Response: `%s`", HostResponse); + tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse); + } From 70744d2cbbdf412d97d1624b21c86cf52890c429 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 13:26:15 +0200 Subject: [PATCH 088/320] small fix --- client/emv/cmdemv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 46ed20165..2274f3d69 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1131,7 +1131,7 @@ int CmdEMVExec(const char *cmd) { } // VSDC - if (GetCardPSVendor(AID, AIDlen) == CV_VISA && (TrType == TT_VSDC)){ + if (GetCardPSVendor(AID, AIDlen) == CV_VISA && (TrType == TT_VSDC || TrType == TT_CDA)){ PrintAndLogEx(NORMAL, "\n--> VSDC transaction."); PrintAndLogEx(NORMAL, "* * Calc CDOL1"); @@ -1158,7 +1158,7 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "\n* * Processing online request\n"); // authorization response code from acquirer - const char HostResponse[] = "0"; + const char HostResponse[] = "00"; // 0x3030 PrintAndLogEx(NORMAL, "* * Host Response: `%s`", HostResponse); tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse); From 607bef7ffd2be0403b907f7c720e531c5dbe7161 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 16:22:32 +0200 Subject: [PATCH 089/320] AC Response Format1 --- client/emv/cmdemv.c | 53 ++++++++++++++++++++++++++++++++++++++++++--- client/emv/tlv.c | 15 +++++++++++-- client/emv/tlv.h | 1 + 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 2274f3d69..a30c22aec 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -38,6 +38,9 @@ void ParamLoadDefaults(struct tlvdb *tlvRoot) { TLV_ADD(0x9F6A, "\x01\x02\x03\x04"); //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC + //95:(Terminal Verification Results) len:5 + // all OK TVR + TLV_ADD(0x95, "\x00\x00\x00\x00\x00"); } void PrintChannel(EMVCommandChannel channel) { @@ -685,6 +688,50 @@ void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, } } +void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) { + if (buf[0] == 0x80) { + if (decodeTLV){ + PrintAndLog("GPO response format1:"); + TLVPrintFromBuffer(buf, len); + } + + uint8_t elmlen = len - 2; // wo 0x80XX + + if (len < 4 + 2 || (elmlen - 2) % 4 || elmlen != buf[1]) { + PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len); + } else { + struct tlvdb *tlvElm = NULL; + if (decodeTLV) + PrintAndLog("\n------------ Format1 decoded ------------"); + + // CID (Cryptogram Information Data) + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f27, 1, &buf[2], &tlvElm); + if (decodeTLV) + TLVPrintFromTLV(tlvElm); + + // ATC (Application Transaction Counter) + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f36, 2, &buf[3], &tlvElm); + if (decodeTLV) + TLVPrintFromTLV(tlvElm); + + // AC (Application Cryptogram) + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, min(8, elmlen - 3), &buf[5], &tlvElm); + if (decodeTLV) + TLVPrintFromTLV(tlvElm); + + // IAD (Issuer Application Data) - optional + if (len > 11 + 2) { + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f10, elmlen - 11, &buf[13], &tlvElm); + if (decodeTLV) + TLVPrintFromTLV(tlvElm); + } + } + } else { + if (decodeTLV) + TLVPrintFromBuffer(buf, len); + } +} + int CmdEMVExec(const char *cmd) { uint8_t buf[APDU_RES_LEN] = {0}; size_t len = 0; @@ -1151,9 +1198,9 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw); dreturn(7); } - - if (decodeTLV) - TLVPrintFromBuffer(buf, len); + + // process Format1 (0x80) anf print Format2 (0x77) + ProcessACResponseFormat1(tlvRoot, buf, len, decodeTLV); PrintAndLogEx(NORMAL, "\n* * Processing online request\n"); diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 013e9735a..9722c9311 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -359,12 +359,15 @@ void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) tlvdb->next = other; } -void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value) +void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value, struct tlvdb **tlvdb_elm) { struct tlvdb *telm = tlvdb_find_full(tlvdb, tag); if (telm == NULL) { // new tlv element - tlvdb_add(tlvdb, tlvdb_fixed(tag, len, value)); + struct tlvdb *elm = tlvdb_fixed(tag, len, value); + tlvdb_add(tlvdb, elm); + if (tlvdb_elm) + *tlvdb_elm = elm; } else { // the same tlv structure if (telm->tag.tag == tag && telm->tag.len == len && !memcmp(telm->tag.value, value, len)) @@ -400,11 +403,19 @@ void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, co // free old element with childrens telm->next = NULL; tlvdb_free(telm); + + if (tlvdb_elm) + *tlvdb_elm = tnewelm; } return; } +void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value) +{ + tlvdb_change_or_add_node_ex(tlvdb, tag, len, value, NULL); +} + void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level) { struct tlvdb *next = NULL; diff --git a/client/emv/tlv.h b/client/emv/tlv.h index d2a55525f..1f52e440b 100644 --- a/client/emv/tlv.h +++ b/client/emv/tlv.h @@ -50,6 +50,7 @@ struct tlvdb *tlvdb_find_path(struct tlvdb *tlvdb, tlv_tag_t tag[]); void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other); void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value); +void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value, struct tlvdb **tlvdb_elm); void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level); const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const struct tlv *prev); From 170cf7c67a49eeb3e976e5621ca6ec778c491d98 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 17:06:59 +0200 Subject: [PATCH 090/320] inc timeout of card's response --- common/i2c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/common/i2c.c b/common/i2c.c index 99f8b6e12..25b17b6bc 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -161,10 +161,11 @@ bool WaitSCL_L(void) { return WaitSCL_L_delay(15000); } -// Wait max 300ms or until SCL goes LOW. +// Wait max 1800ms or until SCL goes LOW. +// It timeout reading response from card // Which ever comes first -bool WaitSCL_L_300ms(void){ - volatile uint16_t delay = 310; +bool WaitSCL_L_timeout(void){ + volatile uint16_t delay = 1800; while ( delay-- ) { // exit on SCL LOW if (!SCL_read) @@ -193,7 +194,8 @@ bool I2C_Start(void) { bool I2C_WaitForSim() { - if (!WaitSCL_L_300ms()) + // wait for data from card + if (!WaitSCL_L_timeout()) return false; // 8051 speaks with smart card. From cada4e4877a5c311216416c7425c5623ba39f0ae Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 17:24:45 +0200 Subject: [PATCH 091/320] DDA works --- client/emv/emvcore.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index a7d625af8..5ea9026c2 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -829,9 +829,16 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { if (len < 3 ) { PrintAndLogEx(WARNING, "Error: Internal Authenticate format1 parsing error. length=%d", len); } else { + // parse response 0x80 + struct tlvdb *t80 = tlvdb_parse_multi(buf, len); + const struct tlv * t80tlv = tlvdb_get_tlv(t80); + // 9f4b Signed Dynamic Application Data - dda_db = tlvdb_fixed(0x9f4b, len - 2, buf + 2); + dda_db = tlvdb_fixed(0x9f4b, t80tlv->len, t80tlv->value); tlvdb_add(tlv, dda_db); + + tlvdb_free(t80); + if (decodeTLV){ PrintAndLogEx(NORMAL, "* * Decode response format 1:"); TLVPrintFromTLV(dda_db); From 628eceb5ed7b56a32cffba38e6c4095a45acba32 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 17:44:51 +0200 Subject: [PATCH 092/320] print fix --- client/emv/emvcore.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 5ea9026c2..023035a7d 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -795,7 +795,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { return 4; } - PrintAndLogEx(NORMAL, "\n* Calc DDOL"); + PrintAndLogEx(NORMAL, "\n* * Calc DDOL"); const struct tlv *ddol_tlv = tlvdb_get(tlv, 0x9f49, NULL); if (!ddol_tlv) { ddol_tlv = &default_ddol_tlv; @@ -813,7 +813,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(NORMAL, "DDOL data[%d]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); - PrintAndLogEx(NORMAL, "\n* Internal Authenticate"); + PrintAndLogEx(NORMAL, "\n* * Internal Authenticate"); int res = EMVInternalAuthenticate(channel, true, (uint8_t *)ddol_data_tlv->value, ddol_data_tlv->len, buf, sizeof(buf), &len, &sw, NULL); if (res) { PrintAndLogEx(WARNING, "Internal Authenticate error(%d): %4x. Exit...", res, sw); @@ -840,7 +840,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { tlvdb_free(t80); if (decodeTLV){ - PrintAndLogEx(NORMAL, "* * Decode response format 1:"); + PrintAndLogEx(NORMAL, "* * * Decode response format 1:"); TLVPrintFromTLV(dda_db); } } @@ -875,12 +875,12 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { // 9f4c ICC Dynamic Number const struct tlv *idn_tlv = tlvdb_get(idn_db, 0x9f4c, NULL); if(idn_tlv) { - PrintAndLogEx(NORMAL, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); - PrintAndLogEx(NORMAL, "DDA verified OK."); + PrintAndLogEx(INFO, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); + PrintAndLogEx(INFO, "DDA verified OK."); tlvdb_add(tlv, idn_db); tlvdb_free(idn_db); } else { - PrintAndLogEx(NORMAL, "\nERROR: DDA verify error"); + PrintAndLogEx(ERR, "\nDDA verify error"); tlvdb_free(idn_db); emv_pk_free(pk); From eaedf7f81101e972887ad749cdb99ef29c3188a2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 18:33:21 +0200 Subject: [PATCH 093/320] VSDC up to CDOL2 calc --- client/emv/cmdemv.c | 17 +++++++++++++++++ client/emv/tlv.c | 12 +++++++++++- client/emv/tlv.h | 2 ++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a30c22aec..114aca322 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1209,6 +1209,23 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "* * Host Response: `%s`", HostResponse); tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse); + // needs to send AC2 command (res == ARQC) + uint8_t CID = 0; + tlvdb_get_uint8(tlvRoot, 0x9f27, &CID); + if ((CID & 0xc0) == 0x80) { + PrintAndLogEx(NORMAL, "* * Calc CDOL2"); + struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag + if (!cdol_data_tlv) { + PrintAndLogEx(WARNING, "Error: can't create CDOL2 TLV."); + dreturn(6); + } + + PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + + PrintAndLogEx(NORMAL, "* * AC2"); + + + } } diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 9722c9311..8d1429640 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -469,7 +469,10 @@ const struct tlv *tlvdb_get_inchild(const struct tlvdb *tlvdb, tlv_tag_t tag, co } const struct tlv *tlvdb_get_tlv(const struct tlvdb *tlvdb) { - return &tlvdb->tag; + if (tlvdb) + return &tlvdb->tag; + else + return NULL; } unsigned char *tlv_encode(const struct tlv *tlv, size_t *len) @@ -546,6 +549,13 @@ struct tlvdb *tlvdb_elm_get_parent(struct tlvdb *tlvdb) return tlvdb->parent; } +bool tlvdb_get_uint8(struct tlvdb *tlvRoot, tlv_tag_t tag, uint8_t *value) +{ + const struct tlvdb *tlvdb = tlvdb_get(tlvRoot, tag, NULL); + const struct tlv *tlvelm = tlvdb_get_tlv(tlvdb); + return tlv_get_uint8(tlvelm, value); +} + bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) { *value = 0; diff --git a/client/emv/tlv.h b/client/emv/tlv.h index 1f52e440b..e75bbf986 100644 --- a/client/emv/tlv.h +++ b/client/emv/tlv.h @@ -65,4 +65,6 @@ bool tlv_equal(const struct tlv *a, const struct tlv *b); bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value); bool tlv_get_int(const struct tlv *etlv, int *value); +bool tlvdb_get_uint8(struct tlvdb *tlvRoot, tlv_tag_t tag, uint8_t *value); + #endif From e058d87dc11ec2c3117d8848ea68b54a9c779e65 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 10 Jan 2019 19:28:43 +0200 Subject: [PATCH 094/320] fix CDOL generation and add AC1 print result --- client/emv/cmdemv.c | 35 +++++++++++++++++++++++++---------- client/emv/emv_tags.h | 4 ++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 114aca322..07543241c 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1182,17 +1182,17 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "\n--> VSDC transaction."); PrintAndLogEx(NORMAL, "* * Calc CDOL1"); - struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag - if (!cdol_data_tlv) { + struct tlv *cdol1_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag + if (!cdol1_data_tlv) { PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV."); dreturn(6); } - PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol1_data_tlv->len, sprint_hex(cdol1_data_tlv->value, cdol1_data_tlv->len)); PrintAndLogEx(NORMAL, "* * AC1"); // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD - res = EMVAC(channel, true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot); + res = EMVAC(channel, true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol1_data_tlv->value, cdol1_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw); @@ -1201,7 +1201,17 @@ int CmdEMVExec(const char *cmd) { // process Format1 (0x80) anf print Format2 (0x77) ProcessACResponseFormat1(tlvRoot, buf, len, decodeTLV); - + + uint8_t CID = 0; + tlvdb_get_uint8(tlvRoot, 0x9f27, &CID); + + // AC1 print result + PrintAndLog(""); + if ((CID & EMVAC_AC_MASK) == EMVAC_AAC) PrintAndLogEx(INFO, "AC1 result: AAC (Transaction declined)"); + if ((CID & EMVAC_AC_MASK) == EMVAC_TC) PrintAndLogEx(INFO, "AC1 result: TC (Transaction approved)"); + if ((CID & EMVAC_AC_MASK) == EMVAC_ARQC) PrintAndLogEx(INFO, "AC1 result: ARQC (Online authorisation requested)"); + if ((CID & EMVAC_AC_MASK) == EMVAC_AC_MASK) PrintAndLogEx(INFO, "AC1 result: RFU"); + PrintAndLogEx(NORMAL, "\n* * Processing online request\n"); // authorization response code from acquirer @@ -1210,21 +1220,26 @@ int CmdEMVExec(const char *cmd) { tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse); // needs to send AC2 command (res == ARQC) - uint8_t CID = 0; - tlvdb_get_uint8(tlvRoot, 0x9f27, &CID); if ((CID & 0xc0) == 0x80) { PrintAndLogEx(NORMAL, "* * Calc CDOL2"); - struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag - if (!cdol_data_tlv) { + struct tlv *cdol2_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag + if (!cdol2_data_tlv) { PrintAndLogEx(WARNING, "Error: can't create CDOL2 TLV."); dreturn(6); } - PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len)); + PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol2_data_tlv->len, sprint_hex(cdol2_data_tlv->value, cdol2_data_tlv->len)); PrintAndLogEx(NORMAL, "* * AC2"); +/* // AC2 + PRINT_INDENT(level); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n"); +*/ } } diff --git a/client/emv/emv_tags.h b/client/emv/emv_tags.h index 246fc72d7..f7d9a8476 100644 --- a/client/emv/emv_tags.h +++ b/client/emv/emv_tags.h @@ -25,6 +25,10 @@ # define EMVAC_TC 0x40 # define EMVAC_ARQC 0x80 # define EMVAC_CDAREQ 0x10 +# define EMVAC_AC2_MASK 0x30 +# define EMVAC_AAC2 0x00 +# define EMVAC_TC2 0x10 +# define EMVAC_ARQC2 0x20 // CID # define EMVCID_ADVICE 0x08 From bd0e33fb58151411f56e10da41e112ec528b587e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 10 Jan 2019 18:55:56 +0100 Subject: [PATCH 095/320] chg: 'script run read_pwd_mem' - m|t|i params to simplify printing dictionary items --- client/scripts/read_pwd_mem.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/scripts/read_pwd_mem.lua b/client/scripts/read_pwd_mem.lua index 772927c0c..a0688a639 100644 --- a/client/scripts/read_pwd_mem.lua +++ b/client/scripts/read_pwd_mem.lua @@ -21,6 +21,9 @@ Arguments: -o : memory offset, default is 0 -l : length in bytes, default is 256 -k : key length in bytes <4|6|8> , default is 4 + -m : print Mifare dictionary keys + -t : print t55xx dictionary passwords + -i : print iClass dictionary keys ]] example = [[ @@ -67,7 +70,7 @@ local function main(args) local keylength = 4 local usedkey = false - for o, a in getopt.getopt(args, 'ho:l:k:') do + for o, a in getopt.getopt(args, 'ho:l:k:mti') do -- help if o == "h" then return help() end @@ -80,6 +83,10 @@ local function main(args) -- keylength if o == "k" then keylength = tonumber(a); usedkey = true end + + if o == "m" then keylength =6; usedkey = true; offset = 0x3F000-0x4000; end + if o == "t" then keylength =4; usedkey = true; offset = 0x3F000-0x3000; end + if o == "i" then keylength =8; usedkey = true; offset = 0x3F000-0x5000; end end if length < 0 or length > 256 then From 43d57855a00232ed2de92212d65031ff3d46443b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Jan 2019 12:56:59 +0100 Subject: [PATCH 096/320] CHG: wrong define --- client/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a30c22aec..91a3663f3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -715,7 +715,7 @@ void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, b TLVPrintFromTLV(tlvElm); // AC (Application Cryptogram) - tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, min(8, elmlen - 3), &buf[5], &tlvElm); + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, MIN(8, elmlen - 3), &buf[5], &tlvElm); if (decodeTLV) TLVPrintFromTLV(tlvElm); From f215ebef80c5875d4d5f1fcbe6c569bf9bb8294d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Jan 2019 14:46:27 +0100 Subject: [PATCH 097/320] Refactored 'lf t55xx brute', split it up into two commands. - lf t55xx brute (tries bruteforcing a range of pwds - lf t55xx chk (uses dictionary file or RDV4 flashmem) FIX: adjust lf sim (@marshmellow42) see https://github.com/marshmellow42/proxmark3/commit/7008cf9c15a135a066227635e64f59285eb73a80 "attempt to speed up the loops waiting for carrier signal to go high or low by only checking for a halt (button press or usbpol) every 256th loop iteration. some users were experiencing modulating reactions to be too slow. ADD: 'lf t55xx chk' It uses @marshmellows42 idea behind commit (https://github.com/marshmellow42/proxmark3/commit/6178b085a0374e656cce3849e481fa5800403c2b) With calculating a baseline (read block0 32times and average the signal-ish) and sampling only 1024 signal data. The algo then proceeds to calc the average and keep track of the candidate which is given the most difference in signal data average value. I do some squaring and shifting for this. The candidate is then send back to client to be tested properly with trymodulation like before. This seems to work good on t55xx card which has a ASK configuration. WORK-IN-PROGRESS --- armsrc/appmain.c | 3 + armsrc/apps.h | 2 + armsrc/lfops.c | 153 +++++++++++++++++++++++++++++++++++++++----- client/cmdlft55xx.c | 153 ++++++++++++++++++++++++++++++++------------ client/cmdlft55xx.h | 1 + include/usb_cmd.h | 2 + 6 files changed, 255 insertions(+), 59 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8759f93c4..0bf9ccb9d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -724,6 +724,9 @@ void UsbPacketReceived(uint8_t *packet, int len) { case CMD_T55XX_RESET_READ: T55xxResetRead(); break; + case CMD_T55XX_CHKPWDS: + T55xx_ChkPwds(); + break; case CMD_PCF7931_READ: ReadPCF7931(); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index 7e45d5e50..d17d9ef4b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -103,6 +103,8 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t PwdMode); void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); void T55xxWakeUp(uint32_t Pwd); +void T55xx_ChkPwds(void); + void TurnReadLFOn(uint32_t delay); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e690714df..47f0cb324 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -598,9 +598,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + + uint8_t check = 1; for(;;) { - + if ( numcycles > -1 ) { if ( x != numcycles ) { ++x; @@ -616,9 +618,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle // used as a simple detection of a reader field? while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { WDT_HIT(); - if ( usb_poll_validate_length() || BUTTON_PRESS() ) - goto OUT; - } + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; } if (buf[i]) OPEN_COIL(); @@ -628,9 +632,11 @@ void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycle //wait until SSC_CLK goes LOW while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { WDT_HIT(); - //if ( usb_poll_validate_length() || BUTTON_PRESS() ) - if ( BUTTON_PRESS() ) - goto OUT; + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; } i++; @@ -1489,11 +1495,22 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { // Read one card block in page [page] void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { LED_A_ON(); - bool PwdMode = arg0 & 0x1; - uint8_t Page = (arg0 & 0x2) >> 1; - uint32_t i = 0; - bool RegReadMode = (Block == 0xFF);//regular read mode + bool PwdMode = arg0 & 0x1; + uint8_t Page = ( arg0 & 0x2 ) >> 1; + bool brute_mem = arg0 & 0x4; + uint32_t i = 0; + + // regular read mode + bool RegReadMode = (Block == 0xFF); + + uint8_t start_wait = 4; + size_t samples = 12000; + if ( brute_mem ) { + start_wait = 0; + samples = 1024; + } + //clear buffer now so it does not interfere with timing later BigBuf_Clear_keep_EM(); @@ -1505,7 +1522,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Set up FPGA, 125kHz to power up the tag LFSetupFPGAForADC(95, true); // make sure tag is fully powered up... - WaitMS(4); + WaitMS(start_wait); + // Trigger T55x7 Direct Access Mode with start gap FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); @@ -1529,17 +1547,118 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Turn field on to read the response // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... + // but we want to go past the start and let the repeating data settle in... TurnReadLFOn(210*8); // Acquisition // Now do the acquisition - DoPartialAcquisition(0, true, 12000, 0); + DoPartialAcquisition(0, true, samples, 0); // Turn the field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + if ( !brute_mem ) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); + } +} + +void T55xx_ChkPwds() { + + DbpString("[+] T55XX Check pwds using flashmemory starting"); + + uint8_t ret = 0; + // First get baseline and setup LF mode. + // tends to mess up BigBuf + uint8_t *buf = BigBuf_get_addr(); + + uint32_t b1, baseline = 0; + + // collect baseline for failed attempt + uint8_t x = 32; + while (x--) { + b1 = 0; + T55xxReadBlock(4, 1, 0); + for (uint16_t j=0; j < 1024; ++j) + b1 += buf[j]; + + b1 *= b1; + b1 >>= 8; + baseline += b1; + } + + baseline >>= 5; + Dbprintf("[=] Baseline determined [%u]", baseline); + + + uint8_t *pwds = BigBuf_get_EM_addr(); + bool use_flashmem = true; + uint16_t pwdCount = 0; + uint32_t candidate = 0; + +#ifdef WITH_FLASH + if ( use_flashmem ) { + BigBuf_Clear_EM(); + uint16_t isok = 0; + uint8_t counter[2] = {0x00, 0x00}; + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter) ); + if ( isok != sizeof(counter) ) + goto OUT; + + pwdCount = counter[1] << 8 | counter[0]; + + if ( pwdCount == 0 && pwdCount == 0xFFFF) + goto OUT; + + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET+2, pwds, pwdCount * 4); + if ( isok != pwdCount * 4 ) + goto OUT; + + Dbprintf("[=] Password dictionary count %d ", pwdCount); + } +#endif + + uint32_t pwd = 0, curr = 0, prev = 0; + for (uint16_t i =0; i< pwdCount; ++i) { + + if (BUTTON_PRESS() && !usb_poll_validate_length()) { + goto OUT; + } + + pwd = bytes_to_num(pwds + i * 4, 4); + + + T55xxReadBlock(5, 0, pwd); + + // calc mean of BigBuf 1024 samples. + uint32_t sum = 0; + for (uint16_t j=0; j<1024; ++j) { + sum += buf[j]; + } + + sum *= sum; + sum >>= 8; + + int32_t tmp = (sum - baseline); + curr = ABS(tmp); + + Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr ); + + if ( curr > prev ) { + + + Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd ); + candidate = pwd; + prev = curr; + } + } + + if ( candidate ) + ret = 1; + +OUT: + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,ret,candidate,0,0,0); + LEDsoff(); } void T55xxWakeUp(uint32_t Pwd){ diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index ed8c0464e..29487e026 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -141,21 +141,33 @@ int usage_t55xx_wakup(){ PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); return 0; } -int usage_t55xx_bruteforce(){ - PrintAndLogEx(NORMAL, "This command uses A) bruteforce to scan a number range"); - PrintAndLogEx(NORMAL, " B) a dictionary attack"); +int usage_t55xx_chk(){ + PrintAndLogEx(NORMAL, "This command uses a dictionary attack"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [i <*.dic>]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [i <*.dic>]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " m - use dictionary from flashmemory\n"); + PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce m"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic"); + PrintAndLogEx(NORMAL, ""); + return 0; +} +int usage_t55xx_bruteforce(){ + PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); + PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] "); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); - PrintAndLogEx(NORMAL, " i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx bruteforce aaaaaaaa bbbbbbbb"); - PrintAndLogEx(NORMAL, " lf t55xx bruteforce i default_pwd.dic"); PrintAndLogEx(NORMAL, ""); return 0; } @@ -224,10 +236,9 @@ int CmdT55xxSetConfig(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - tmp = param_getchar(Cmd, cmdp); + tmp = tolower(param_getchar(Cmd, cmdp)); switch(tmp) { case 'h': - case 'H': return usage_t55xx_config(); case 'b': errors |= param_getdec(Cmd, cmdp+1, &bitRate); @@ -292,12 +303,10 @@ int CmdT55xxSetConfig(const char *Cmd) { config.offset = offset; cmdp+=2; break; - case 'Q': case 'q': config.Q5 = true; cmdp++; break; - case 'S': case 's': config.ST = true; cmdp++; @@ -343,8 +352,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32 if (!AquireData(page1, block, usepwd, password) ) return 0; if (!DecodeT55xxBlock()) return 0; - char blk[10]={0}; - sprintf(blk,"%02d", block); + char blk[10] = {0}; + sprintf(blk, "%02d", block); printT55xxBlock(blk); return 1; } @@ -358,22 +367,18 @@ int CmdT55xxReadBlock(const char *Cmd) { bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + switch ( tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_t55xx_read(); case 'b': - case 'B': errors |= param_getdec(Cmd, cmdp+1, &block); cmdp += 2; break; case 'o': - case 'O': override = true; cmdp++; break; case 'p': - case 'P': password = param_get32ex(Cmd, cmdp+1, 0, 16); usepwd = true; cmdp += 2; @@ -1503,23 +1508,68 @@ bool IsCancelled(void) { return false; } -int CmdT55xxBruteForce(const char *Cmd) { - +int CmdT55xxChkPwds(const char *Cmd) { // load a default pwd file. char line[9]; char filename[FILE_PATH_SIZE] = {0}; int keycnt = 0; uint8_t stKeyBlock = 20; uint8_t *keyBlock = NULL, *p = NULL; - uint32_t start_password = 0x00000000; //start password - uint32_t end_password = 0xFFFFFFFF; //end password bool found = false; + uint8_t timeout = 0; memset(line, 0, sizeof(line)); char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_bruteforce(); + if (cmdp == 'h') return usage_t55xx_chk(); + + /* + if ( T55xxReadBlock(7, 0, 0, 0, 0) ) { + + // now try to validate it.. + PrintAndLogEx(WARNING, "\n Block 7 was readable"); + return 1; + } + */ + + uint64_t t1 = msclock(); + if ( cmdp == 'm' ) { + UsbCommand c = {CMD_T55XX_CHKPWDS, {0,0,0} }; + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + + while ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { + timeout++; + printf("."); fflush(stdout); + if (timeout > 180) { + PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); + return 2; + } + } + + if ( resp.arg[0] ) { + PrintAndLogEx(SUCCESS, "\nFound a candidate [ %08X ]. Trying to validate", resp.arg[1]); + + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.arg[1])) { + PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); + return 2; + } + + found = tryDetectModulation(); + if (found) { + PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", resp.arg[1]); + } else { + PrintAndLogEx(NORMAL, "Password NOT found."); + } + } else { + PrintAndLogEx(NORMAL, "Password NOT found."); + } + + goto out; + } + keyBlock = calloc(stKeyBlock, 4); if (keyBlock == NULL) return 1; @@ -1569,7 +1619,7 @@ int CmdT55xxBruteForce(const char *Cmd) { num_to_bytes( strtoll(line, NULL, 16), 4, keyBlock + 4*keycnt); - PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) ); +// PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) ); keycnt++; memset(line, 0, sizeof(line)); } @@ -1609,60 +1659,78 @@ int CmdT55xxBruteForce(const char *Cmd) { } found = tryDetectModulation(); - if ( found ) { - PrintAndLogEx(NORMAL, "Found valid password: [%08X]", testpwd); - //free(keyBlock); - //return 0; - } + if ( found ) + break; + } - PrintAndLogEx(NORMAL, "Password NOT found."); - free(keyBlock); - return 0; + if ( found ) + PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", testpwd); + else + PrintAndLogEx(NORMAL, "Password NOT found."); } + free(keyBlock); + +out: + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0); + return 0; +} + +int CmdT55xxBruteForce(const char *Cmd) { + + uint32_t start_password = 0x00000000; //start password + uint32_t end_password = 0xFFFFFFFF; //end password + uint32_t curr = 0; + bool found = false; + + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_t55xx_bruteforce(); + + uint64_t t1 = msclock(); + // Try to read Block 7, first :) // incremental pwd range search start_password = param_get32ex(Cmd, 0, 0, 16); end_password = param_get32ex(Cmd, 1, 0, 16); + curr = start_password; + if ( start_password >= end_password ) { - free(keyBlock); return usage_t55xx_bruteforce(); } PrintAndLogEx(NORMAL, "Search password range [%08X -> %08X]", start_password, end_password); - - uint32_t i = start_password; - while ((!found) && (i <= end_password)){ + while ((!found) || (curr <= end_password)){ printf("."); fflush(stdout); if (IsCancelled()) { - free(keyBlock); return 0; } - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) { + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr)) { PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); - free(keyBlock); return 0; } found = tryDetectModulation(); if (found) break; - i++; + ++curr; } PrintAndLogEx(NORMAL, ""); if (found) - PrintAndLogEx(NORMAL, "Found valid password: [%08x]", i); + PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", curr); else - PrintAndLogEx(NORMAL, "Password NOT found. Last tried: [%08x]", --i); + PrintAndLogEx(NORMAL, "Password NOT found. Last tried: [ %08X ]", --curr); - free(keyBlock); + t1 = msclock() - t1; + PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0); return 0; } @@ -1959,6 +2027,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"bruteforce", CmdT55xxBruteForce,0, " [i <*.dic>] Simple bruteforce attack to find password"}, {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, + {"chk", CmdT55xxChkPwds, 1, "Check passwords"}, {"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."}, {"deviceconfig", CmdT55xxSetDeviceConfig, 1, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"}, {"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"}, diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 15adab0b6..46de0c359 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -133,6 +133,7 @@ t55xx_conf_block_t Get_t55xx_Config(void); void Set_t55xx_Config(t55xx_conf_block_t conf); extern int CmdLFT55XX(const char *Cmd); +extern int CmdT55xxChk(const char *Cmd); extern int CmdT55xxBruteForce(const char *Cmd); extern int CmdT55xxSetConfig(const char *Cmd); extern int CmdT55xxReadBlock(const char *Cmd); diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 44d031334..a54b27e0f 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -140,6 +140,8 @@ typedef struct{ #define CMD_COTAG 0x0225 #define CMD_SET_LF_T55XX_CONFIG 0x0226 +#define CMD_T55XX_CHKPWDS 0x0230 + /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ // For the 13.56 MHz tags From a5833fe39069d2ec50e90ee3637b27ccd76f7d79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Jan 2019 12:10:31 +0100 Subject: [PATCH 098/320] CHG: remove strange thr 0x43 in LF sampling CHG: refactor cotag init --- armsrc/lfops.c | 29 ++++++------------------- armsrc/lfsampling.c | 53 +++++++++++++++++++-------------------------- 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 47f0cb324..c267db36e 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1548,7 +1548,7 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Turn field on to read the response // 137*8 seems to get to the start of data pretty well... // but we want to go past the start and let the repeating data settle in... - TurnReadLFOn(210*8); + TurnReadLFOn(200*8); // Acquisition // Now do the acquisition @@ -2089,7 +2089,6 @@ void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { //Wait 20ms for write to complete? WaitMS(7); - //Capture response if one exists DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -2113,7 +2112,7 @@ This triggers a COTAG tag to response */ void Cotag(uint32_t arg0) { #ifndef OFF -# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } +# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON # define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } @@ -2122,29 +2121,15 @@ void Cotag(uint32_t arg0) { LED_A_ON(); - // Switching to LF image on FPGA. This might empty BigBuff - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - + LFSetupFPGAForADC(89, true); + //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); - // Set up FPGA, 132kHz to power up the tag - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - // start clock - 1.5ticks is 1us - StartTicks(); - //send COTAG start pulse - ON(740) OFF - ON(3330) OFF - ON(740) OFF + ON(740) OFF(2035) + ON(3330) OFF(2035) + ON(740) OFF(2035) ON(1000) switch(rawsignal) { diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 22171e2c3..96963d389 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -117,21 +117,21 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { * @return the number of bits occupied by the samples. */ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) { - //bigbuf, to hold the aquired raw data signal + uint8_t *dest = BigBuf_get_addr(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); - if (bits_per_sample < 1) bits_per_sample = 1; if (bits_per_sample > 8) bits_per_sample = 8; if (decimation < 1) decimation = 1; - // Use a bit stream to handle the output + // use a bit stream to handle the output BitstreamOut data = { dest , 0, 0}; int sample_counter = 0; uint8_t sample = 0; - //If we want to do averaging + + // if we want to do averaging uint32_t sample_sum =0 ; uint32_t sample_total_numbers = 0; uint32_t sample_total_saved = 0; @@ -139,13 +139,13 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + + // Testpoint 8 (TP8) can be used to trigger oscilliscope LED_D_OFF(); + // threshold either high or low values 128 = center 0. if trigger = 178 if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) { if (cancel_after > 0) { @@ -162,24 +162,26 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag if (averaging) sample_sum += sample; - //Check decimation + // check decimation if (decimation > 1) { sample_counter++; if (sample_counter < decimation) continue; sample_counter = 0; } - //Averaging + // averaging if (averaging && decimation > 1) { sample = sample_sum / decimation; sample_sum =0; } - //Store the sample + // store the sample sample_total_saved ++; - if (bits_per_sample == 8){ + if (bits_per_sample == 8) { dest[sample_total_saved-1] = sample; - data.numbits = sample_total_saved << 3;//Get the return value correct + + // Get the return value correct + data.numbits = sample_total_saved << 3; if (sample_total_saved >= bufsize) break; } else { @@ -190,9 +192,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag if (bits_per_sample > 4) pushBit(&data, sample & 0x08); if (bits_per_sample > 5) pushBit(&data, sample & 0x04); if (bits_per_sample > 6) pushBit(&data, sample & 0x02); - //Not needed, 8bps is covered above - //if (bits_per_sample > 7) pushBit(&data, sample & 0x01); - if ((data.numbits >> 3) +1 >= bufsize) break; + + if ((data.numbits >> 3) + 1 >= bufsize) break; } } } @@ -285,10 +286,8 @@ void doT55x7Acquisition(size_t sample_size) { while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; //43 - LED_D_ON(); - } + + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); @@ -352,11 +351,7 @@ void doCotagAcquisition(size_t sample_size) { while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); @@ -406,12 +401,8 @@ uint32_t doCotagAcquisitionManchester() { uint16_t noise_counter = 0; while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { - WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - + WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); From 459ff6149b815e7a7b2e49ff8dc9ec9fa814839a Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 12 Jan 2019 18:12:58 +0100 Subject: [PATCH 099/320] Update README.md --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index 94f7b94d6..05b9a007f 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,46 @@ You are now ready to use your newly upgraded proxmark3 device. Many commands us pm3 --> quit +### First things on your RDV40 +You will need to run these commands to make sure your rdv4 is prepared + + pm3 --> mem load f default_keys m + pm3 --> mem load f default_pwd t + pm3 --> mem load f default_iclass_keys i + pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p + +### Verify sim module firmware version +To make sure you got the latest sim module firmware. +_Lastest version is v3.10_ + + pm3 --> hw status + +Find version in the long output, look for these two lines + + #db# Smart card module (ISO 7816) + #db# version.................v2.06 + +This version is obselete. The following command upgrades your device sim module firmware. +Don't not turn of your device during the execution of this command. + + pm3 --> sc upgrade f ../tools/simmodule/SIM010.BIN + +You get the following output, this is a successful execution. + + [!] WARNING - Smartcard socket firmware upgrade. + [!] A dangerous command, do wrong and you will brick the smart card socket + [+] Smartcard socket firmware uploading to PM3 + .. + [+] Smartcard socket firmware updating, don't turn off your PM3! + #db# FW 0000 + #db# FW 0080 + #db# FW 0100 + #db# FW 0180 + #db# FW 0200 + #db# FW 0280 + [+] Smartcard socket firmware upgraded successful + + ## the end `iceman at host iuse.se` From fcfbeb6ac362dfba85d6f7e2ab8df80b403cdadd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Jan 2019 18:33:40 +0100 Subject: [PATCH 100/320] textual --- client/cmdlft55xx.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 29487e026..f6c0f3ced 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1553,18 +1553,18 @@ int CmdT55xxChkPwds(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nFound a candidate [ %08X ]. Trying to validate", resp.arg[1]); if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.arg[1])) { - PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); + PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting"); return 2; } found = tryDetectModulation(); if (found) { - PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", resp.arg[1]); + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", resp.arg[1]); } else { - PrintAndLogEx(NORMAL, "Password NOT found."); + PrintAndLogEx(WARNING, "Password NOT found."); } } else { - PrintAndLogEx(NORMAL, "Password NOT found."); + PrintAndLogEx(WARNING, "Password NOT found."); } goto out; @@ -1581,7 +1581,7 @@ int CmdT55xxChkPwds(const char *Cmd) { FILE * f = fopen( filename , "r"); if ( !f ) { - PrintAndLogEx(NORMAL, "File: %s: not found or locked.", filename); + PrintAndLogEx(WARNING, "File: %s: not found or locked.", filename); free(keyBlock); return 1; } @@ -1596,7 +1596,7 @@ int CmdT55xxChkPwds(const char *Cmd) { if( line[0]=='#' ) continue; if (!isxdigit(line[0])) { - PrintAndLogEx(NORMAL, "File content error. '%s' must include 8 HEX symbols", line); + PrintAndLogEx(WARNING, "File content error. '%s' must include 8 HEX symbols", line); continue; } @@ -1627,11 +1627,11 @@ int CmdT55xxChkPwds(const char *Cmd) { fclose(f); if (keycnt == 0) { - PrintAndLogEx(NORMAL, "No keys found in file"); + PrintAndLogEx(WARNING, "No keys found in file"); free(keyBlock); return 1; } - PrintAndLogEx(NORMAL, "Loaded %d keys", keycnt); + PrintAndLogEx(SUCCESS, "Loaded %d keys", keycnt); // loop uint64_t testpwd = 0x00; @@ -1650,10 +1650,10 @@ int CmdT55xxChkPwds(const char *Cmd) { testpwd = bytes_to_num(keyBlock + 4*c, 4); - PrintAndLogEx(NORMAL, "Testing %08X", testpwd); + PrintAndLogEx(INFO, "Testing %08X", testpwd); if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) { - PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); + PrintAndLogEx(INFO, "Aquireing data from device failed. Quitting"); free(keyBlock); return 0; } @@ -1664,9 +1664,9 @@ int CmdT55xxChkPwds(const char *Cmd) { } if ( found ) - PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", testpwd); + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", testpwd); else - PrintAndLogEx(NORMAL, "Password NOT found."); + PrintAndLogEx(WARNING, "Password NOT found."); } free(keyBlock); @@ -1702,7 +1702,7 @@ int CmdT55xxBruteForce(const char *Cmd) { return usage_t55xx_bruteforce(); } - PrintAndLogEx(NORMAL, "Search password range [%08X -> %08X]", start_password, end_password); + PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); while ((!found) || (curr <= end_password)){ @@ -1713,7 +1713,7 @@ int CmdT55xxBruteForce(const char *Cmd) { } if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, curr)) { - PrintAndLogEx(NORMAL, "Aquireing data from device failed. Quitting"); + PrintAndLogEx(WARNING, "Aquireing data from device failed. Quitting"); return 0; } found = tryDetectModulation(); @@ -1725,9 +1725,9 @@ int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(NORMAL, ""); if (found) - PrintAndLogEx(NORMAL, "Found valid password: [ %08X ]", curr); + PrintAndLogEx(SUCCESS, "Found valid password: [ %08X ]", curr); else - PrintAndLogEx(NORMAL, "Password NOT found. Last tried: [ %08X ]", --curr); + PrintAndLogEx(WARNING, "Password NOT found. Last tried: [ %08X ]", --curr); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1/1000.0); From 46cbbe8d05de1704af23f1dda580fddbf6f8efa5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Jan 2019 18:53:11 +0100 Subject: [PATCH 101/320] textual --- client/cmdlft55xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f6c0f3ced..abf8f04ec 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1814,9 +1814,9 @@ int CmdT55xxRecoverPW(const char *Cmd) { PrintAndLogEx(NORMAL, ""); if (found == 1) - PrintAndLogEx(NORMAL, "Found valid password: [%08x]", curr_password); + PrintAndLogEx(SUCCESS, "Found valid password: [%08x]", curr_password); else - PrintAndLogEx(NORMAL, "Password NOT found."); + PrintAndLogEx(WARNING, "Password NOT found."); return 0; } From 20c3cd5ce3d823f56eac432c7115057246c9e611 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 14 Jan 2019 12:02:26 +0100 Subject: [PATCH 102/320] chg: adjusting license according to earlier commits to pm3 offical repo. --- armsrc/optimized_cipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 36b25f593..223d73fea 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -22,7 +22,7 @@ * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. + * by the Free Software Foundation, or, at your option, any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of From adffe298555de6f1c4076fbe7bd7f21e216f3278 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 14 Jan 2019 12:06:05 +0100 Subject: [PATCH 103/320] chg: adjusting license accoring match its .c file --- common/iso15693tools.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 053ca56ca..70382ce04 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -1,5 +1,11 @@ -// ISO15693 commons -// Adrian Dabrowski 2010 and others, GPLv2 +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// ISO15693 other commons +//----------------------------------------------------------------------------- +// Adrian Dabrowski 2010 and otherss // Christian Herrmann 2018 #ifndef ISO15693_H__ From 6f0cc5fa7a8a752b8b93a0ae89ae6379a294f60b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 14 Jan 2019 18:14:15 +0200 Subject: [PATCH 104/320] small fix --- client/emv/cmdemv.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 07543241c..71cf542db 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -715,7 +715,7 @@ void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, b TLVPrintFromTLV(tlvElm); // AC (Application Cryptogram) - tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, min(8, elmlen - 3), &buf[5], &tlvElm); + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, MIN(8, elmlen - 3), &buf[5], &tlvElm); if (decodeTLV) TLVPrintFromTLV(tlvElm); @@ -1233,12 +1233,12 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "* * AC2"); -/* // AC2 - PRINT_INDENT(level); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n"); +/* // AC2 + PRINT_INDENT(level); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n"); */ } From 5a35b0de2aaf1ca9f416603765f456a76ba5a99e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 14 Jan 2019 18:54:18 +0200 Subject: [PATCH 105/320] changed `min` to macro `MIN` --- client/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index a30c22aec..91a3663f3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -715,7 +715,7 @@ void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, b TLVPrintFromTLV(tlvElm); // AC (Application Cryptogram) - tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, min(8, elmlen - 3), &buf[5], &tlvElm); + tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, MIN(8, elmlen - 3), &buf[5], &tlvElm); if (decodeTLV) TLVPrintFromTLV(tlvElm); From 49fc2a56ab43a9058ef539202c18f9b6e145e8b8 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 20 Jan 2019 23:46:03 +0100 Subject: [PATCH 106/320] Update tnp3clone.lua According to post http://www.proxmark.org/forum/viewtopic.php?pid=34046#p34046 Set that ATQA / SAK, set Sector 0 accessrights --- client/scripts/tnp3clone.lua | 64 +++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 2e1ee7019..fcccc042e 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -37,13 +37,12 @@ Arguments: 0020 - Swapforce ]] - -- This is only meant to be used when errors occur -function oops(err) +local function oops(err) print("ERROR: ",err) end -- Usage help -function help() +local function help() print(desc) print("Example usage") print(example) @@ -64,7 +63,7 @@ local function waitCmd() end local function readblock( blocknum, keyA ) - -- Read block 0 + -- Read block N cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA} err = core.SendCommand(cmd:getBytes()) if err then return nil, err end @@ -72,8 +71,9 @@ local function readblock( blocknum, keyA ) if err then return nil, err end return block0 end + local function readmagicblock( blocknum ) - -- Read block 0 + -- Read block N local CSETBLOCK_SINGLE_OPERATION = 0x1F cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum} err = core.SendCommand(cmd:getBytes()) @@ -89,11 +89,13 @@ local function main(args) print( string.rep('--',20) ) local numBlocks = 64 - local cset = 'hf mf csetbl ' + local cset = 'hf mf csetbl ' local csetuid = 'hf mf csetuid ' local cget = 'hf mf cgetbl ' local empty = '00000000000000000000000000000000' - local AccAndKeyB = '7F078869000000000000' + local AccAndKeyB = '7F070869000000000000' + local atqa = '0F01' + local sak = '81' -- Defaults to Gusto local toytype = 'C201' local subtype = '0030' @@ -107,42 +109,54 @@ local function main(args) if o == "l" then return toys.List() end end - if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end - if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end + if #toytype ~= 4 then return oops('[!] Wrong size - toytype. (4hex symbols)') end + if #subtype ~= 4 then return oops('[!] Wrong size - subtype. (4hex symbols)') end -- look up type, find & validate types local item = toys.Find( toytype, subtype) if item then - print( (' Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) ) + print( ('[+] Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) ) else - print('Didn\'t find item type. If you are sure about it, report it in') + print('[-] Didn\'t find item type. If you are sure about it, post on forum') end --15,16 - --13-14 - + --13-14 -- find tag result, err = lib14a.read(false, true) - if not result then return oops(err) end + if not result then return oops(err) end -- load keys local akeys = pre.GetAll(result.uid) - local keyA = akeys:sub(1, 12 ) + local keyA = akeys:sub(1, 12 ) - local b0 = readblock(0,keyA) + local b0 = readblock(0, keyA) if not b0 then - print('failed reading block with factorydefault key. Trying chinese magic read.') + print('[-] failed reading block with factorydefault key. Trying chinese magic read.') b0, err = readmagicblock(0) if not b0 then - oops(err) - return oops('failed reading block with chinese magic command. quitting...') + oops('[!] '..err) + return oops('[!] failed reading block with chinese magic command. Quitting...') end end + core.clearCommandBuffer() + + local b3 = readblock(3, keyA) + if not b3 then + print('[-] failed reading block with factorydefault key. Trying chinese magic read.') + b3, err = readmagicblock(0) + if not b3 then + oops('[!] '..err) + return oops('[!] failed reading block with chinese magic command. Quitting...') + end + end + core.clearCommandBuffer() -- wipe card. - local cmd = (csetuid..'%s 0004 08 w'):format(result.uid) + local cmd = (csetuid..'%s %s %s w'):format(result.uid, atqa, sak) core.console(cmd) - + core.clearCommandBuffer() + local b1 = toytype..string.rep('00',10)..subtype local calc = utils.Crc16(b0..b1) @@ -150,6 +164,7 @@ local function main(args) local cmd = (cset..'1 %s%04x'):format( b1, calcEndian) core.console(cmd) + core.clearCommandBuffer() local pos, key for blockNo = 2, numBlocks-1, 1 do @@ -161,5 +176,10 @@ local function main(args) end end core.clearCommandBuffer() + + -- Set sector trailer S0, since it has different access rights + cmd = ('%s 3 %s%s'):format(cset, keyA, b3:sub(13) ) + core.console(cmd) + core.clearCommandBuffer() end -main(args) \ No newline at end of file +main(args) From 6e99b1e49bf37702eb2fd52ded8847a7fb18b384 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 20 Jan 2019 23:53:54 +0100 Subject: [PATCH 107/320] Update tnp3clone.lua Better to use default template for ST --- client/scripts/tnp3clone.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index fcccc042e..b0cebaf7f 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -178,7 +178,7 @@ local function main(args) core.clearCommandBuffer() -- Set sector trailer S0, since it has different access rights - cmd = ('%s 3 %s%s'):format(cset, keyA, b3:sub(13) ) + cmd = ('%s 3 %s0f0f0f69000000000000'):format(cset, keyA) core.console(cmd) core.clearCommandBuffer() end From 6f3940b22141c0ba53dcdbf1aa605e43e943af86 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 20 Jan 2019 23:55:11 +0100 Subject: [PATCH 108/320] Update tnp3clone.lua Cleanup --- client/scripts/tnp3clone.lua | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index b0cebaf7f..514a091b9 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -140,18 +140,7 @@ local function main(args) end end core.clearCommandBuffer() - - local b3 = readblock(3, keyA) - if not b3 then - print('[-] failed reading block with factorydefault key. Trying chinese magic read.') - b3, err = readmagicblock(0) - if not b3 then - oops('[!] '..err) - return oops('[!] failed reading block with chinese magic command. Quitting...') - end - end - core.clearCommandBuffer() - + -- wipe card. local cmd = (csetuid..'%s %s %s w'):format(result.uid, atqa, sak) core.console(cmd) From 5f2ecf67cdc5bbe380d353905a55812e5a7b0294 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 21 Jan 2019 00:02:33 +0100 Subject: [PATCH 109/320] Update default_pwd.dic --- client/default_pwd.dic | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/default_pwd.dic b/client/default_pwd.dic index dd1364385..87423478b 100644 --- a/client/default_pwd.dic +++ b/client/default_pwd.dic @@ -96,6 +96,7 @@ FABADA11, //china? 69696969, 12121212, 12344321, +1234ABCD, 11112222, 13131313, 10041004, @@ -104,8 +105,8 @@ FABADA11, //china? abcd1234, 20002000, 19721972, -aa55aa55, //amiboo -55aa55aa, //rev amiboo +aa55aa55, // amiboo +55aa55aa, // rev amiboo 4f271149, // seeds ul-ev1 07d7bb0b, // seeds ul-ev1 9636ef8f, // seeds ul-ev1 @@ -113,4 +114,4 @@ b5f44686, // seeds ul-ev1 9E3779B9, // TEA C6EF3720, // TEA 7854794A, // xbox tea constant :) -F1EA5EED, //burtle +F1EA5EED, // burtle From 66c82d16b0671f48b0f2c0b715676099d78b0f35 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Jan 2019 09:02:00 +0100 Subject: [PATCH 110/320] chg: calloc calls --- client/cmdhficlass.c | 6 +++--- client/cmdhflegic.c | 4 ++-- client/cmdhfmf.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 0e62afaf6..f0bfa18a0 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2463,7 +2463,7 @@ static void shave(uint8_t *data, uint8_t len){ data[i] &= 0xFE; } static void generate_rev(uint8_t *data, uint8_t len) { - uint8_t *key = calloc(len,1); + uint8_t *key = calloc(len, sizeof(uint8_t)); PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len)); permute_rev(data, len, key); PrintAndLogEx(SUCCESS, " unpermuted key | %s \n", sprint_hex(key, len)); @@ -2472,8 +2472,8 @@ static void generate_rev(uint8_t *data, uint8_t len) { free(key); } static void generate(uint8_t *data, uint8_t len) { - uint8_t *key = calloc(len,1); - uint8_t *pkey = calloc(len,1); + uint8_t *key = calloc(len, sizeof(uint8_t)); + uint8_t *pkey = calloc(len, sizeof(uint8_t)); PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len)); permute(data, len, pkey); PrintAndLogEx(SUCCESS, "permuted key | %s \n", sprint_hex(pkey, len)); diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 393d73ed0..a31dbd1b1 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -483,7 +483,7 @@ int CmdLegicRdmem(const char *Cmd) { PrintAndLogEx(NORMAL, "Reading %d bytes, from offset %d", len, offset); // allocate receiver buffer - uint8_t *data = malloc(len); + uint8_t *data = calloc(len, sizeof(uint8_t)); if ( !data ){ PrintAndLogEx(WARNING, "Cannot allocate memory"); return 2; @@ -923,7 +923,7 @@ int CmdLegicDump(const char *Cmd){ else sprintf(fnameptr + fileNlen,".bin"); - f = fopen(filename,"wb"); + f = fopen(filename, "wb"); if (!f) { PrintAndLogEx(WARNING, "Could not create file name %s", filename); if (data) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 00e29105f..a02302b15 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2496,7 +2496,7 @@ int CmdHF14AMfESave(const char *Cmd) { blocks = NumOfBlocks(c); bytes = blocks * MFBLOCK_SIZE; - dump = calloc(sizeof(uint8_t), bytes); + dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 1; From fa889900c0458f94d7f812169fccfc0fea6b7638 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Jan 2019 09:31:37 +0100 Subject: [PATCH 111/320] chg: calloc instead of malloc chg: textual chg: extra size checks chg: longer wait for reading mem --- client/cmdhflegic.c | 112 +++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index a31dbd1b1..0f580da9f 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -183,12 +183,11 @@ int CmdLegicInfo(const char *Cmd) { PrintAndLogEx(NORMAL, "Reading tag memory %d b...", card.cardsize); // allocate receiver buffer - uint8_t *data = malloc(card.cardsize); + uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Cannot allocate memory"); return 2; } - memset(data, 0, card.cardsize); int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); if ( status > 0 ) { @@ -480,15 +479,20 @@ int CmdLegicRdmem(const char *Cmd) { uint16_t datalen = 0; sscanf(Cmd, "%x %x %x", &offset, &len, &iv); - PrintAndLogEx(NORMAL, "Reading %d bytes, from offset %d", len, offset); + // sanity checks + if ( len + offset >= MAX_LENGTH ) { + PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", MAX_LENGTH, len + offset); + return -1; + } + + PrintAndLogEx(SUCCESS, "Reading %d bytes, from offset %d", len, offset); // allocate receiver buffer uint8_t *data = calloc(len, sizeof(uint8_t)); if ( !data ){ PrintAndLogEx(WARNING, "Cannot allocate memory"); - return 2; + return -2; } - memset(data, 0, len); int status = legic_read_mem(offset, len, iv, data, &datalen); if ( status == 0 ) { @@ -540,9 +544,9 @@ int CmdLegicRfWrite(const char *Cmd) { } // limit number of bytes to write. This is not a 'restore' command. - if ( (len>>1) > 100 ){ - PrintAndLogEx(NORMAL, "Max bound on 100bytes to write a one time."); - PrintAndLogEx(NORMAL, "Use the 'hf legic restore' command if you want to write the whole tag at once"); + if ( (len >> 1) > 100 ){ + PrintAndLogEx(WARNING, "Max bound on 100bytes to write a one time."); + PrintAndLogEx(WARNING, "Use the 'hf legic restore' command if you want to write the whole tag at once"); errors = true; } @@ -551,7 +555,7 @@ int CmdLegicRfWrite(const char *Cmd) { if (data) free(data); - data = malloc(len >> 1); + data = calloc(len >> 1, sizeof(uint8_t)); if ( data == NULL ) { PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); errors = true; @@ -598,12 +602,12 @@ int CmdLegicRfWrite(const char *Cmd) { // OUT-OF-BOUNDS checks // UID 4+1 bytes can't be written to. if ( offset < 5 ) { - PrintAndLogEx(NORMAL, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); + PrintAndLogEx(WARNING, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); return -2; } if ( len + offset >= card.cardsize ) { - PrintAndLogEx(NORMAL, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset); + PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset); return -2; } @@ -622,7 +626,7 @@ int CmdLegicRfWrite(const char *Cmd) { legic_chk_iv(&IV); - PrintAndLogEx(NORMAL, "Writing to tag"); + PrintAndLogEx(SUCCESS, "Writing to tag"); UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}}; memcpy(c.d.asBytes, data, len); @@ -673,7 +677,7 @@ int CmdLegicCalcCrc(const char *Cmd){ // it's possible for user to accidentally enter "b" parameter // more than once - we have to clean previous malloc if (data) free(data); - data = malloc(len >> 1); + data = calloc(len >> 1, sizeof(uint8_t) ); if ( data == NULL ) { PrintAndLogEx(WARNING, "Can't allocate memory. exiting"); errors = true; @@ -714,10 +718,10 @@ int CmdLegicCalcCrc(const char *Cmd){ switch (type){ case 16: init_table(CRC_LEGIC); - PrintAndLogEx(NORMAL, "Legic crc16: %X", crc16_legic(data, len, uidcrc)); + PrintAndLogEx(SUCCESS, "Legic crc16: %X", crc16_legic(data, len, uidcrc)); break; default: - PrintAndLogEx(NORMAL, "Legic crc8: %X", CRC8Legic(data, len) ); + PrintAndLogEx(SUCCESS, "Legic crc8: %X", CRC8Legic(data, len) ); break; } @@ -733,11 +737,18 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) { - PrintAndLogEx(WARNING, "command execution time out"); - return 1; - } - + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; *outlen = resp.arg[1]; if ( !isOK ) { @@ -762,13 +773,13 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces){ char *spacer = spc + (10-spaces); if ( tagtype == 22 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (outdated)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (outdated)", spacer, tagtype); else if ( tagtype == 256 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (234 bytes)", spacer, tagtype); else if ( tagtype == 1024 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : MIM%d card (1002 bytes)", spacer, tagtype); else - PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); + PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype); return 0; } int legic_get_type(legic_card_select_t *card){ @@ -792,12 +803,12 @@ int legic_get_type(legic_card_select_t *card){ void legic_chk_iv(uint32_t *iv){ if ( (*iv & 0x7F) != *iv ){ *iv &= 0x7F; - PrintAndLogEx(NORMAL, "Truncating IV to 7bits, %u", *iv); + PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv); } // IV must be odd if ( (*iv & 1) == 0 ){ *iv |= 0x01; - PrintAndLogEx(NORMAL, "LSB of IV must be SET %u", *iv); + PrintAndLogEx(INFO, "LSB of IV must be SET %u", *iv); } } void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { @@ -828,11 +839,11 @@ int HFLegicReader(const char *Cmd, bool verbose) { if ( verbose ) PrintAndLogEx(WARNING, "command execution time out"); return 1; case 3: - if ( verbose ) PrintAndLogEx(NORMAL, "legic card select failed"); + if ( verbose ) PrintAndLogEx(WARNING, "legic card select failed"); return 2; default: break; } - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); legic_print_type(card.cardsize, 0); return 0; } @@ -882,14 +893,14 @@ int CmdLegicDump(const char *Cmd){ dumplen = card.cardsize; legic_print_type(dumplen, 0); - PrintAndLogEx(NORMAL, "Reading tag memory %d b...", dumplen); + PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen); UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - PrintAndLogEx(NORMAL, "Command execute time-out"); + PrintAndLogEx(WARNING, "Command execute time-out"); return 1; } @@ -900,12 +911,11 @@ int CmdLegicDump(const char *Cmd){ } uint16_t readlen = resp.arg[1]; - uint8_t *data = malloc(readlen); + uint8_t *data = calloc(readlen, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, readlen); if ( readlen != dumplen ) PrintAndLogEx(WARNING, "Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen); @@ -934,7 +944,7 @@ int CmdLegicDump(const char *Cmd){ fflush(f); fclose(f); free(data); - PrintAndLogEx(NORMAL, "Wrote %d bytes to %s", readlen, filename); + PrintAndLogEx(SUCCESS, "Wrote %d bytes to %s", readlen, filename); return 0; } @@ -982,12 +992,11 @@ int CmdLegicRestore(const char *Cmd){ numofbytes = card.cardsize; // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t) ); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 2; } - memset(data, 0, numofbytes); legic_print_type(numofbytes, 0); @@ -997,7 +1006,7 @@ int CmdLegicRestore(const char *Cmd){ f = fopen(filename,"rb"); if (!f) { - PrintAndLogEx(NORMAL, "File %s not found or locked", filename); + PrintAndLogEx(WARNING, "File %s not found or locked", filename); return 3; } @@ -1018,12 +1027,12 @@ int CmdLegicRestore(const char *Cmd){ fclose(f); if ( bytes_read == 0){ - PrintAndLogEx(NORMAL, "File reading error"); + PrintAndLogEx(WARNING, "File reading error"); free(data); return 2; } - PrintAndLogEx(NORMAL, "Restoring to card"); + PrintAndLogEx(SUCCESS, "Restoring to card"); // transfer to device size_t len = 0; @@ -1049,11 +1058,11 @@ int CmdLegicRestore(const char *Cmd){ free(data); return 1; } - PrintAndLogEx(NORMAL, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len); + PrintAndLogEx(SUCCESS, "Wrote chunk [offset %d | len %d | total %d", i, len, i+len); } free(data); - PrintAndLogEx(NORMAL, "\nWrote %d bytes to card from file %s", numofbytes, filename); + PrintAndLogEx(SUCCESS, "\nWrote %d bytes to card from file %s", numofbytes, filename); return 0; } @@ -1077,12 +1086,11 @@ int CmdLegicELoad(const char *Cmd) { } // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, numofbytes); // set up file len = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE); @@ -1094,7 +1102,7 @@ int CmdLegicELoad(const char *Cmd) { // open file f = fopen(filename,"rb"); if (!f) { - PrintAndLogEx(NORMAL, "File %s not found or locked", filename); + PrintAndLogEx(WARNING, "File %s not found or locked", filename); free(data); return 1; } @@ -1102,7 +1110,7 @@ int CmdLegicELoad(const char *Cmd) { // load file size_t bytes_read = fread(data, 1, numofbytes, f); if ( bytes_read == 0){ - PrintAndLogEx(NORMAL, "File reading error"); + PrintAndLogEx(WARNING, "File reading error"); free(data); fclose(f); f = NULL; @@ -1115,7 +1123,7 @@ int CmdLegicELoad(const char *Cmd) { legic_seteml(data, 0, numofbytes); free(data); - PrintAndLogEx(NORMAL, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename); + PrintAndLogEx(SUCCESS, "\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename); return 0; } @@ -1146,15 +1154,14 @@ int CmdLegicESave(const char *Cmd) { fileNlen = FILE_PATH_SIZE - 5; // set up buffer - uint8_t *data = malloc(numofbytes); + uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 3; } - memset(data, 0, numofbytes); // download emulator memory - PrintAndLogEx(NORMAL, "Reading emulator memory..."); + PrintAndLogEx(SUCCESS, "Reading emulator memory..."); if (!GetFromDevice( BIG_BUF_EML, data, numofbytes, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); @@ -1185,16 +1192,15 @@ int CmdLegicWipe(const char *Cmd){ } // set up buffer - uint8_t *data = malloc(card.cardsize); + uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 2; } - memset(data, 0, card.cardsize); legic_print_type(card.cardsize, 0); - PrintAndLogEx(NORMAL, "Erasing"); + PrintAndLogEx(SUCCESS, "Erasing"); // transfer to device size_t len = 0; @@ -1222,7 +1228,7 @@ int CmdLegicWipe(const char *Cmd){ return 4; } } - PrintAndLogEx(NORMAL, "ok\n"); + PrintAndLogEx(SUCCESS, "ok\n"); return 0; } @@ -1236,7 +1242,7 @@ static command_t CommandTable[] = { {"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and tag info"}, {"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"}, {"dump", CmdLegicDump, 0, "Dump LEGIC Prime tag to binary file"}, - {"restore", CmdLegicRestore, 0, "Restore a dump onto a LEGIC Prime tag"}, + {"restore", CmdLegicRestore, 0, "Restore a dump file onto a LEGIC Prime tag"}, {"rdmem", CmdLegicRdmem, 0, "Read bytes from a LEGIC Prime tag"}, {"sim", CmdLegicRfSim, 0, "Start tag simulator"}, {"write", CmdLegicRfWrite, 0, "Write data to a LEGIC Prime tag"}, From 72942624426a7c57b24bea25f37121dbdcea22d1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Jan 2019 09:59:47 +0100 Subject: [PATCH 112/320] chg: 'script run iso15_magic' - added switch "-a" to swap between iceman styled vs offical styled iso15 raw commands. In order to run this script on official pm3 repo, you will need to copy this script and /client/lualibs/read15.lua file. Read help text for examples script run iso15_magic -h --- client/scripts/iso15_magic.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/client/scripts/iso15_magic.lua b/client/scripts/iso15_magic.lua index 36e8100a8..3923f2b1e 100644 --- a/client/scripts/iso15_magic.lua +++ b/client/scripts/iso15_magic.lua @@ -5,7 +5,7 @@ local utils = require('utils') copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.0.3' +version = 'v1.0.4' desc = [[ This script tries to set UID on a IS15693 SLIX magic card Remember the UID ->MUST<- start with 0xE0 @@ -15,6 +15,8 @@ example = [[ -- ISO15693 slix magic tag script run iso15_magic -u E004013344556677 + + script run iso15_magic -u E004013344556677 -a ]] usage = [[ script run iso15_magic -h -u @@ -22,6 +24,7 @@ script run iso15_magic -h -u Arguments: -h : this help -u : UID (16 hexsymbols) + -a : use offical pm3 repo ISO15 commands instead of iceman fork. ]] local DEBUG = true @@ -82,11 +85,13 @@ function main(args) print() local uid = 'E004013344556677' + local use_iceman = true -- Read the parameters - for o, a in getopt.getopt(args, 'hu:') do + for o, a in getopt.getopt(args, 'hu:a') do if o == "h" then return help() end if o == "u" then uid = a end + if o == "a" then use_iceman = false end end -- uid string checks @@ -103,8 +108,11 @@ function main(args) core.clearCommandBuffer() - magicUID_iceman(block0, block1) - --magicUID_offical(block0, block1) + if use_iceman then + magicUID_iceman(block0, block1) + else + magicUID_offical(block0, block1) + end end main(args) From 8ee857e4ba6d334ca30beefb4241b385abfefa09 Mon Sep 17 00:00:00 2001 From: Iceman Date: Mon, 21 Jan 2019 17:36:58 +0100 Subject: [PATCH 113/320] Update tnp3clone.lua --- client/scripts/tnp3clone.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 514a091b9..b17cf2661 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -93,7 +93,7 @@ local function main(args) local csetuid = 'hf mf csetuid ' local cget = 'hf mf cgetbl ' local empty = '00000000000000000000000000000000' - local AccAndKeyB = '7F070869000000000000' + local AccAndKeyB = '7F0F0869000000000000' local atqa = '0F01' local sak = '81' -- Defaults to Gusto From 601cb0fe0009c02a85b0c98c5649b92ea5e34c1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Jan 2019 22:04:44 +0100 Subject: [PATCH 114/320] chg: 'hf legic dump' - longer timeout --- client/cmdhflegic.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 0f580da9f..c1677d00a 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -899,10 +899,17 @@ int CmdLegicDump(const char *Cmd){ clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { - PrintAndLogEx(WARNING, "Command execute time-out"); - return 1; - } + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { From 063feeae05a5523c6e943efcd3e3b838d915a9e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 21 Jan 2019 22:12:43 +0100 Subject: [PATCH 115/320] CHG: 'hf legic write' CHG: 'hf legic restore' CHG: 'hf legic wipe' - longer timeout for execution --- client/cmdhflegic.c | 50 ++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index c1677d00a..1403060e5 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -634,10 +634,18 @@ int CmdLegicRfWrite(const char *Cmd) { clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "command execution time out"); - return 1; - } + + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag"); @@ -1054,11 +1062,18 @@ int CmdLegicRestore(const char *Cmd){ clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - PrintAndLogEx(WARNING, "command execution time out"); - free(data); - return 1; - } + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + free(data); + return 1; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); @@ -1223,11 +1238,18 @@ int CmdLegicWipe(const char *Cmd){ clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - PrintAndLogEx(WARNING, "command execution time out"); - free(data); - return 3; - } + uint8_t timeout = 0; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + ++timeout; + printf("."); fflush(stdout); + if (timeout > 7) { + PrintAndLogEx(WARNING, "\ncommand execution time out"); + free(data); + return 3; + } + } + PrintAndLogEx(NORMAL, "\n"); + uint8_t isOK = resp.arg[0] & 0xFF; if ( !isOK ) { PrintAndLogEx(WARNING, "Failed writing tag [msg = %u]", resp.arg[1] & 0xFF); From be09793fcda1e2fba280d2ca9bbae5c257092e7a Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 22 Jan 2019 09:45:10 +0100 Subject: [PATCH 116/320] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 05b9a007f..f21a2efdc 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ I have also added this script to the fork. https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh - Run -`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libjansson-dev` +`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi` - Clone fork `git clone https://github.com/RfidResearchGroup/proxmark3.git` @@ -86,7 +86,7 @@ https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh ## Setup and build for ArchLinux - Run -`sudo pacman -Sy base-devel p7zip libusb readline ncurses libjansson-dev arm-none-eabi-newlib --needed` +`sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-newlib --needed` `yaourt -S termcap` - Remove modemmanager From cf006a445fff51e7862fb1c440e22bf67d9d1382 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 22 Jan 2019 11:55:04 +0100 Subject: [PATCH 117/320] Update default_keys.dic ADD: more keys --- client/default_keys.dic | 83 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index 3fb8f07bf..c7186a154 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -711,4 +711,85 @@ FD8705E721B0, 00ada2cd516d, # # -D3F7D3F7D3F7 \ No newline at end of file +D3F7D3F7D3F7 +## +237a4d0d9119, +0ed7846c2bc9, +FFFFD06F83E3, +FFFFAE82366C, +F89C86B2A961, +F83466888612, +ED3A7EFBFF56, +E96246531342, +E1DD284379D4, +DFED39FFBB76, +DB5181C92CBE, +CFC738403AB0, +BCFE01BCFE01, +BA28CFD15EE8, +B0699AD03D17, +AABBCC660429, +A4EF6C3BB692, +A2B2C9D187FB, +9B1DD7C030A1, +9AEDF9931EC1, +8F9B229047AC, +872B71F9D15A, +83BAB5ACAD62, +833FBD3CFE51, +64E2283FCF5E, +64A2EE93B12B, +5D293AFC8D7E, +5554AAA96321, +474249437569, +46868F6D5677, +435330666666, +40E5EA1EFC00, +37D4DCA92451, +2012053082AD, +2011092119F1, +200306202033, +1795902DBAF9, +17505586EF02, +022FE48B3072, +013940233313, +1A2B3C4D5E6F, +123456ABCDEF, +FFFFD06F83E3, +FFFFAE82366C, +F89C86B2A961, +F83466888612, +ED3A7EFBFF56, +E96246531342, +E1DD284379D4, +DFED39FFBB76, +DB5181C92CBE, +CFC738403AB0, +BCFE01BCFE01, +BA28CFD15EE8, +B0699AD03D17, +AABBCC660429, +A4EF6C3BB692, +A2B2C9D187FB, +9B1DD7C030A1, +9AEDF9931EC1, +8F9B229047AC, +872B71F9D15A, +83BAB5ACAD62, +833FBD3CFE51, +64E2283FCF5E, +64A2EE93B12B, +5D293AFC8D7E, +5554AAA96321, +474249437569, +46868F6D5677, +435330666666, +40E5EA1EFC00, +37D4DCA92451, +2012053082AD, +2011092119F1, +200306202033, +1795902DBAF9, +17505586EF02, +022FE48B3072, +013940233313, From e885ec737df6dea50be909b8fe948e39e1e624e4 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 22 Jan 2019 12:03:53 +0100 Subject: [PATCH 118/320] Update default_keys.dic --- client/default_keys.dic | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index c7186a154..ffbdb3cbd 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -735,55 +735,17 @@ A2B2C9D187FB, 9AEDF9931EC1, 8F9B229047AC, 872B71F9D15A, -83BAB5ACAD62, 833FBD3CFE51, -64E2283FCF5E, -64A2EE93B12B, 5D293AFC8D7E, 5554AAA96321, 474249437569, -46868F6D5677, 435330666666, -40E5EA1EFC00, -37D4DCA92451, -2012053082AD, -2011092119F1, -200306202033, -1795902DBAF9, -17505586EF02, -022FE48B3072, -013940233313, 1A2B3C4D5E6F, 123456ABCDEF, -FFFFD06F83E3, -FFFFAE82366C, -F89C86B2A961, -F83466888612, -ED3A7EFBFF56, -E96246531342, -E1DD284379D4, -DFED39FFBB76, -DB5181C92CBE, -CFC738403AB0, -BCFE01BCFE01, -BA28CFD15EE8, -B0699AD03D17, -AABBCC660429, -A4EF6C3BB692, -A2B2C9D187FB, -9B1DD7C030A1, -9AEDF9931EC1, -8F9B229047AC, -872B71F9D15A, 83BAB5ACAD62, -833FBD3CFE51, 64E2283FCF5E, 64A2EE93B12B, -5D293AFC8D7E, -5554AAA96321, -474249437569, 46868F6D5677, -435330666666, 40E5EA1EFC00, 37D4DCA92451, 2012053082AD, From 0bec6038b733e1e0221d100c2746c5d4e710612a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 23 Jan 2019 10:57:49 +0100 Subject: [PATCH 119/320] CHG: adjusted compiling for older devices --- armsrc/lfops.c | 4 ++-- client/cmdflashmem.h | 4 ++++ client/emv/emvcore.c | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c267db36e..d750fccbe 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1591,11 +1591,11 @@ void T55xx_ChkPwds() { uint8_t *pwds = BigBuf_get_EM_addr(); - bool use_flashmem = true; uint16_t pwdCount = 0; uint32_t candidate = 0; -#ifdef WITH_FLASH +#ifdef WITH_FLASH + bool use_flashmem = true; if ( use_flashmem ) { BigBuf_Clear_EM(); uint16_t isok = 0; diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 9f71a4ce0..ee661bf18 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -8,6 +8,8 @@ // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- +#ifdef WITH_FLASH + #ifndef CMDFLASHMEM_H__ #define CMDFLASHMEM_H__ @@ -38,4 +40,6 @@ extern int CmdFlashMemLoad(const char* cmd); extern int CmdFlashMemSave(const char* cmd); extern int CmdFlashMemWipe(const char *Cmd); extern int CmdFlashMemInfo(const char *Cmd); +#endif + #endif \ No newline at end of file diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 5ea9026c2..77d288eaa 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -262,8 +262,12 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField } break; case ECC_CONTACT: +#ifdef WITH_SMARTCARD //int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); res = ExchangeAPDUSC(data, (IncludeLe?6:5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); +#else + res = 1; +#endif if (res) { return res; } From 61ebdbde6b65601f997dae4c5f606c75ce3837e8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 23 Jan 2019 11:01:11 +0100 Subject: [PATCH 120/320] CHG: adjusting compiling for older devices --- client/cmdflashmem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 6361d48e3..d3aaff19e 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -7,6 +7,8 @@ //----------------------------------------------------------------------------- // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- +#ifdef WITH_FLASH + #include "cmdflashmem.h" #include "mbedtls/rsa.h" @@ -604,3 +606,5 @@ int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); return 0; } + +#endif \ No newline at end of file From 5e13c7e58879d3823f5f182ab27ba7b31508e2bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 23 Jan 2019 12:18:07 +0100 Subject: [PATCH 121/320] ADD: Found a bunch more dictionary files, from a link on the forum. --- client/dictionaries/bmp_sort_keys.dic | 1000 ++++++++++++++++++++++ client/dictionaries/icbpm_sort_keys.dic | 1001 +++++++++++++++++++++++ client/dictionaries/mrzd_sort_keys.dic | 57 ++ 3 files changed, 2058 insertions(+) create mode 100644 client/dictionaries/bmp_sort_keys.dic create mode 100644 client/dictionaries/icbpm_sort_keys.dic create mode 100644 client/dictionaries/mrzd_sort_keys.dic diff --git a/client/dictionaries/bmp_sort_keys.dic b/client/dictionaries/bmp_sort_keys.dic new file mode 100644 index 000000000..0f8acdcf3 --- /dev/null +++ b/client/dictionaries/bmp_sort_keys.dic @@ -0,0 +1,1000 @@ +002DE0301481, +004173272D18, +0058A4884CA5, +00BAC32761D8, +00BB79731B00, +00E8C85DB172, +02096124DA70, +024988BC4D5E, +0271B7C4B015, +028137A705DB, +02827C286AB4, +02C10DA600D0, +0340643D5E27, +037A5DA4682B, +037AC43CBD9D, +037B9B8AA219, +037EE3DE21B7, +0380A9A3CBDE, +03D10A75B56A, +03E8CD22E691, +04109ED8EA79, +04361330B35C, +043D8B66D569, +045E5588845C, +048DE5148DE7, +0490921D0194, +04B717BD92EB, +04D49C76623B, +051518B3301E, +0529E8827A52, +052B16064085, +05DC4016B500, +06124317A9A6, +06147D199266, +0670AEB833CE, +0686A9E6D6E0, +06A34E5E6639, +06B78AD0C4BB, +0710E7818AB8, +07121B8C633A, +07176713C0ED, +0793533A5087, +081D1B1C3110, +0849495E1CCA, +09429512046E, +0966C3B28E04, +098A92C3660A, +098B48278122, +099672009EEA, +0A7632943926, +0AEE126549DA, +0B3B8C2833BC, +0B733C13E2C9, +0B764247D00E, +0BE811559D69, +0C208AD4E4B3, +0C270BC0BDDC, +0C5D782CB183, +0C82C94EB11B, +0CCDE948878A, +0CCE39820AAE, +0CDE3E716B32, +0CE06C96DB4C, +0CE87813E389, +0D3385CEA152, +0D5C5B8BCC5B, +0DB0A87AB882, +0DE247593B93, +0E0AD1796003, +0E62E6CAC3D3, +106E2D6E55E6, +1096A7830C82, +11549C141AD9, +116A92C793D6, +116C31526819, +11C68052AAE9, +1234B5BE8E78, +1268C7D104E1, +12A21B5671A8, +13359D5AE9A5, +1426EC62BB6C, +144489B1056E, +14A22C112090, +14C9BBB5361B, +14EB6286AC57, +14EE72B27223, +153BB53ACE71, +157B03405B38, +15A45083D24E, +15DACCE8D5EC, +16124677BBC5, +16373A44D5D7, +1663659384DC, +167828B6105C, +16B25A453093, +1706B1BE25C7, +171B15888483, +17BC8EED9A0C, +17C6299D5A37, +17E9C4C416EB, +1804087C7166, +1841CC4E3E79, +18AB05761CC5, +18ADAAC2B08B, +18E566417E5C, +191390328752, +1A47959E7DB4, +1A9A970CC370, +1B095E78BB33, +1B1717043D2B, +1B1A054566D9, +1B4654AE9454, +1B9CD1ED3420, +1B9E00780953, +1BB6A9CE71E2, +1C1250A36A13, +1C2316079532, +1C2855ED7A10, +1CD1AE73CA8C, +1CD3D4E690B7, +1D0322005969, +1D09B23EB116, +1D67A32045ED, +1D89D900968A, +1DAE8D2CEA5C, +1E1873799CD7, +1E60CE7C5179, +1E6A67909B8D, +1E8516585792, +1EB0864E9134, +1ECE3D04A020, +2009828E4A21, +200A6A3AA65D, +20188A599582, +20267CB20256, +20628CA7D92D, +2077C980EB2E, +2089B5D68B27, +209481EC6256, +20B6691C64B1, +20CC5A00C677, +211473555436, +2170E9D0D448, +219529A90EDD, +21A5B6481B7D, +224A308017D1, +227D16EA455A, +22A1245CA266, +22A95CB798DC, +230E26964171, +231173B68E46, +2332BB9A2452, +234323BC2992, +234E50256146, +235C9338D5B6, +23789D9ADD0D, +23997DD240AB, +23A5BA53AD4D, +23BB58853461, +24CAD4153036, +24CE79506842, +25228ED714BC, +257377227B34, +2584287A0174, +2616192EEB22, +265C03B50877, +26D641E834DC, +27073B57132B, +279060E3DEE9, +284BA0A0A29C, +285C6604C5B4, +28B20331245A, +28D042242A83, +28DDD4C3E9C4, +292C2CCD157E, +299ABB519354, +2A41BE015C1D, +2A4A55052A51, +2A94CBCD7A6E, +2AB6536187C7, +2B2D2DC3D319, +2BD607CA70B2, +2C6C7957EB3E, +2C9E9E4D0895, +2D2A97DD45E3, +2D41850A8AA6, +2DAC030D1AB9, +2E12426D8847, +2E25AD1D6D8D, +2E2E85E0E6C9, +2E4340CC1C63, +2E6803BE2E11, +2EB24B573DCD, +2EC6450A47C7, +2ECDA9A5EA96, +2EDE1C155023, +302D5D37342B, +303645E47667, +303B30A460E8, +3048EBB8A18E, +30BD652BED24, +30CCE5ECB397, +310241E1CB36, +312670228372, +319E8895EAB5, +31E3A933BC4A, +3250D2E661DA, +32560224418D, +32589E221D10, +326657A8E9C0, +329AC7C59311, +32A091B89995, +3312C094BD20, +336C8CBA5AE2, +34240649314A, +3493D84E6317, +349A347186D7, +349BEAC5210E, +34A939B49EDC, +34CC7E36C8C4, +34D71347877E, +34DC25B4D0CE, +35895EB472C4, +358A6A398211, +360A08C66042, +36306A9CA571, +37284428A250, +377EC8A78B8D, +37BD90A68613, +37E602347133, +382DE6AB2D1A, +385D498B5390, +38B67589E47D, +393CCCCCDA4A, +39682B3E10B5, +397619525709, +39A83A32909B, +3A5834C46513, +3A70C7A4BCE4, +3A818D01E093, +3AA5AC1CDC21, +3AAE07339954, +3B4497052B42, +3B784087DB2D, +3B86A20C16EA, +3B8E321AB1B4, +3BC4A3099B0D, +3BC741376E71, +3C4C95D0A0C7, +3C84B55A5E54, +3C888A88C59D, +3D5C8240B2D2, +3DB004172BE7, +3E23271C1C15, +3E3188294ED1, +3E84144A770E, +3EA227893101, +3EB914E70076, +3EE6D4A85643, +40DABA780B41, +4119340759A2, +415210E0C6BB, +416D21717779, +41B1839829A9, +4201A36DE766, +4261A795D5A7, +42AA0B29626E, +430265958BEB, +4317C5C16EAD, +431D799E0C89, +4342794AD7BB, +4387ADE263DB, +43982124C310, +4436CB060568, +44449507B736, +44E858C82975, +459BC12982B1, +45AE5DDA9830, +45C414CDC347, +45CE4E504C06, +461744C8EABD, +46D012CA3BEC, +47170BD112B6, +47C43D5DD234, +47CD4AC26271, +47D410D1C7C4, +4808C5AD0115, +485BEEDBC293, +486001404A80, +488CCC60B70A, +49204E3CA169, +495657C78147, +4970714D53D9, +4AA715A0BBB4, +4B9901AEC16E, +4BE0B912A5A3, +4CBC34D10D83, +4CD3ACABC6A3, +4CE00134DE1E, +4CEB27151C49, +4D02A3D7CE48, +4D13683C7960, +4D1A263BA48B, +4D23919463A3, +4D9763C083D9, +4DAC8EE52C68, +4DCB89C7B2E6, +4DD9D9B637C4, +4DE6CB63A920, +4DEBA10CC85D, +4E232A8C2E30, +4E2879A411E7, +4EA7B0BED74B, +4EB8761372EA, +4EC2B23135AB, +4EC71DB088DE, +4EC9AB4B5519, +50179E461EE6, +50265ED9D468, +5047DC2975BE, +508357498162, +508BE54D326E, +510A8C52AAC4, +511335CC92CD, +518229589A81, +5184D04315D7, +51B4AE31B246, +526EDB918BEE, +529CE44BEBCC, +52A843082BB3, +52AE9A909674, +5313E9079489, +532DE5E7E0E9, +535508AA6C91, +53691569B669, +540A5B789761, +547B86E57596, +54C649075B57, +552249203848, +55430B5318E9, +5570D22DC66B, +55710879E113, +55D2E4AC0446, +56207539825A, +564664475726, +566441C5C28C, +56A7930913C3, +56C944B04618, +56D455A8BBEA, +5726991C8C28, +5726AA3BE37B, +573314090BA5, +577C31903867, +577C528E786C, +57AD9604ED24, +580C377283C7, +587329CE3EBE, +587C34557B36, +58B11E803B58, +5902E4DCC95D, +5A060A64C535, +5A36898CA7C5, +5A4740D952EC, +5A6ED7966868, +5A99578CAA13, +5AAD6814E68B, +5B065568048A, +5B6CE0B3AD0A, +5B70E0B11758, +5B926E3751EB, +5B9CA63C4267, +5BDC1391B289, +5C1D3898D537, +5C34B8E4A456, +5C36456EA1E5, +5C43A75C65A0, +5C5752328A47, +5C9D20250D74, +5CBA3CEE351A, +5CD5E98A2864, +5CE0EB9C01B6, +5D384E6A4145, +5D9DB8445155, +5DE8717BB640, +5E1A4EE98748, +5E45A227B391, +5E8E50B3048B, +5EB0EA0A9412, +6032C47B7676, +60E0C84ADDEE, +612A447A2149, +612D81821854, +616B820EAD01, +616D75A4A022, +61DE2B085AC9, +62312EC272A0, +6232C5262CC6, +62B7C7C9B0D0, +62C531C6E29C, +63E6AAAB4433, +644ABCC3DD12, +64AE7BEA1784, +6515B38077D6, +65972038CC25, +65E120DE5E55, +66141DDE8320, +66718BD91332, +668082242328, +668920AEE063, +6696C4332D46, +66C9880D1DC2, +67150CB11E95, +671737BA0054, +673551D0A99E, +676D682C4336, +678B98AA2E86, +6847808E63EE, +6887A122AA62, +6888C514DEAD, +688BD5B7B4E9, +68A99E258692, +68C312391560, +68C9D33E3735, +6900A069E3D7, +690155BE8D8E, +69174742042D, +69B9CE233517, +6A0B123D7595, +6AB8E2B49E25, +6ABD4C4A72D9, +6B1CC539A1B2, +6B30B6B0925D, +6B638C1C950D, +6BAAAB1D4589, +6BAD01EBE736, +6BB4ED5E1682, +6CA178E036DA, +6CE210B529C4, +6D23D505D2B1, +6D3CBD12BC6D, +6D83563EB521, +6D98AB9CCC71, +6E3D7366E78C, +6E5582237608, +6E6602904925, +6E77B8EB6444, +6E978A7B16C6, +6EEC05EB651C, +70284824B26C, +702CDACE0C14, +704E1B85BED8, +70BB123776D6, +70CCC3A2D7C0, +716A747CB931, +7173E199A420, +71BC9C9E31E4, +71CAEEA3B771, +71D8BA423D55, +72253C7DD951, +7260377CD286, +7280858E8B20, +72913BDAB647, +72B5B87BBC6E, +72C83B1D098A, +72DA8050A38E, +735C2AB60A97, +736B602A93D9, +738D7833E7DE, +73E7B22D6E54, +74133B1E2DED, +74A929877793, +74E3670C045A, +7531E3E2A41C, +7542A9B65EB4, +7564993C91C7, +760ED0AB626E, +762E0E021E38, +763D7E6BB40E, +764B38E2903D, +768016001C8D, +76A616C3D42C, +76AE99D9A294, +76BAAA710D25, +76E3B23696BC, +77322DD2E184, +77B40902B6D9, +77C0AC14972D, +77C1CE0E7674, +77D7B7E2C8BA, +78279397A68E, +7836593AB838, +783859EB51A6, +78CCDB50C193, +7932684154AE, +79604362370E, +796630ED27B3, +799E4E270953, +79A00573947A, +79B798D66B01, +7A0455D0A7EC, +7A33D19B7248, +7B0A8AE18817, +7B0BA045AB35, +7B0DE8504D57, +7B21781EC649, +7B7224C1AB79, +7B90C2BA9B23, +7BB90D382672, +7BBC9DC92836, +7C09DC408C47, +7C418B493454, +7C491D518242, +7C7A86CC727C, +7CE836EBD228, +7D49042C530D, +7E5744EC286C, +7E680A48C383, +7EC45CCEC35A, +7EDADA19EB57, +8005BD088847, +8022E705B640, +8031E3565825, +80499BAA5959, +807466CCBAB5, +810518578380, +810D24CB13CC, +812B02C34A64, +8163A5DDE1CD, +8186CE2B363E, +81DE6062B9D7, +822017D8929A, +8247C78188C5, +8270D538D5E8, +82D8E8DDE296, +831207CA6E8A, +83378A077357, +83A05B477535, +840160379EEE, +84044BAB78A7, +84366C6D7781, +8442CC9AA777, +8470AAD30447, +8498740493BB, +84A35A698E93, +84ABDE484425, +84B24DBB9A67, +84B723B2A237, +852BEB133D74, +854501E98239, +854A0ED2E77D, +85A066D39785, +8619557091AA, +86228C3742A4, +8637BB3BA795, +8642D9310B46, +86538085966D, +86EE9C410811, +870A042C1B34, +873B47C457E6, +873CE44DDC6B, +874D123262E7, +87513C960770, +877641436923, +878A091B74B7, +87927467808B, +88C2E39B5990, +88D252AC1A8A, +891EDA20BDEA, +89267DEE07ED, +892CB89ACCC6, +8A2423E9D100, +8A6BC2E3811B, +8A8EB5771EE9, +8A906B4B3211, +8AB21B524C5C, +8AB823BDC2AE, +8AC3B2ADE77B, +8AC4317D049B, +8ACD6B86EC44, +8AD966CA3B4D, +8B0A3B3DCDD4, +8B1B6C705C1A, +8B1C75E27153, +8B2A5E0332A1, +8B6216E412DB, +8B7CCA9DB004, +8B9999AE9703, +8BABAD9A65C6, +8C32D0AE3DB7, +8C99807368A5, +8CC1133D7D5B, +8CD2C872187A, +8D0563B86DD4, +8D43D81E37B4, +8D96A800B21A, +8D97B475C957, +8DA62EC0C524, +8DACA1BC0636, +8DE3B131D728, +8E55316D3B3D, +8EE497C9A869, +90210DDAB57D, +9026977EB8A6, +903AA4305025, +9083158A49A1, +9092D12E7967, +90D8713352D1, +911E097A27A9, +9140EC087241, +918A67D05479, +919B1D357E91, +9210BBA2AB26, +9224B6555E30, +9226D4D1236A, +922E7955CC67, +929CC86B1B26, +929E1556110E, +9302DEB79C5A, +9384841B4702, +93B4BD1CB47C, +93D985D55712, +940B37939AC6, +94673AE73823, +947A8147E0AE, +94CD6A4B6391, +94CEEAC5A8D7, +95ABD3A7C631, +95E1C233EDE2, +9607AE17AD09, +960C98566E52, +96435BD1D29B, +965D66E19245, +965D72659982, +9695167B4149, +96D0C3996714, +97274C21BD6C, +973186B345BB, +973A28C983A3, +979686C51AB6, +97992CE2DD31, +97E9D0C89DA8, +97EB8A44C49D, +98314DC363C5, +9860DC044565, +988D023C15A5, +9917BDA7B4D7, +9996A233442A, +9A2132B5B625, +9A694755A978, +9A7911ECC275, +9AA1E6CE588C, +9ABCCD2AE7C7, +9B39A60D3841, +9C0630361CC5, +9C4E19AB64B1, +9CE96BADE4D8, +9D442B28BD11, +9D4C35AE1A08, +9E02910C691A, +9E46407C9024, +9E74D104ACEA, +9EDD416A7912, +A026642D13AD, +A12908B38536, +A16EE9666D5A, +A199132A4043, +A1AEC2B58BBA, +A1BE42A15EDE, +A1D0844C2C63, +A1E0103A1879, +A253602B9445, +A2B019B46CB9, +A2BBCC3B546C, +A2C325A73A9C, +A2CB60E815A0, +A314B97C1A6A, +A3647146C335, +A3A580799BB4, +A3D30CC8EB97, +A402B5137D86, +A42158CC74B5, +A435DD64AD17, +A4693D21013B, +A479A91EED49, +A4B30D146A01, +A5142D626200, +A54056E87CBB, +A57DBD287491, +A588C918E327, +A593071D4758, +A5CC0EE7B9E3, +A6375E98A5B5, +A666347B3B4B, +A6A203994202, +A6BAE1A1520D, +A6E9885AA49D, +A705087E89A8, +A7072D4324C7, +A745AD7D6789, +A750456E7C5E, +A783A8774651, +A787C822020C, +A78BB575EAC5, +A7905680A254, +A805534D84E9, +A86C2595A1C3, +A89903B6ADDB, +A9182707A219, +A9391782A846, +A96B08E3A50B, +A98DEB0733C9, +A9C37CE71D23, +AA2D69C757D9, +AA4E4558A9EE, +AA6C835C9124, +AAC0C35C43EB, +AB30CB2CB354, +AB6191DB240A, +AB8953D3560C, +ABBB521319E6, +AC47461358D7, +AC58C25A1559, +AC7D4B201D92, +AD061A23287D, +AD105D52DB36, +AD4EA84D7185, +AD5038D15490, +AD97523144B2, +ADB24E78784B, +ADCBD453B232, +AE516A187825, +AE52116C234C, +AE817239CAB5, +AEA5A5A0E46B, +AECC93678543, +B0452769A83C, +B04D71906C60, +B0805C191424, +B09172DDBE43, +B13AE369390C, +B14080E570D1, +B1419B62772C, +B14775DEA2E2, +B188BA649EA1, +B1BB0DB95C67, +B1BB19BDD424, +B1E8B5054DAD, +B1EBB537CC0D, +B2174092CDC5, +B2554CC8AD6E, +B2C5A2E88304, +B312E56ED250, +B37B48D8C1C5, +B39C699CD208, +B3B121208E34, +B3C3C6E4395B, +B410B958C3B8, +B4204546A74E, +B45171C5A67D, +B4B103E693ED, +B4DACABCAB07, +B506567A2B84, +B51083D5C2BD, +B54D7674CB90, +B570E5EA1DA3, +B598984AD584, +B5D7E1135821, +B60D053A36D9, +B63957593E23, +B64558CAC0C9, +B68175BCA864, +B6CD1A3EC5BC, +B72468A7710D, +B75176C82A8B, +B7AA0CA5D94A, +B7B9D7E523B8, +B808D87AB75C, +B93A6432E51A, +B941A9D99B6C, +B9DA40920237, +BA6C2E10086A, +BA7384AB949E, +BA8DEEE045E8, +BADC2149EC42, +BB1924266B36, +BB41640E6340, +BBB475DB2B03, +BBD4C4699719, +BC0B2C897267, +BC7BEE6B71C4, +BC8B21AD8802, +BCA2D8118631, +BCB7A7006400, +BCBC6637499B, +BCBD2B8BE4B3, +BD213E28C568, +BD32E4EC7080, +BD401D63C3E9, +BD463C3693A4, +BD749E85586A, +BD7CA11B9551, +BD96355CBE36, +BD9E6EB7B524, +BDADE6111218, +BDB576D1E88C, +BDB5DC09C522, +BE19C75D6B7E, +BE5B3ED935AC, +BEA20C972E70, +BEEB4A159B37, +C01E8740DE38, +C0411C28857D, +C045544AD1E4, +C04660B76831, +C0C4CA21B876, +C0E0E092C8B4, +C0EE394D3D95, +C14601C6B411, +C16EBAE928B2, +C189A791A85B, +C1ACDB8C1890, +C1C55A7A99EA, +C1D72A47755A, +C1D8B91D65AA, +C1E6149B386D, +C22D8E2B1E37, +C23E999B6298, +C314E31A670D, +C3D275A9B8C7, +C3EE19B61C89, +C427B93DC2ED, +C443EEC4330D, +C477B966D328, +C4C6CAE4784C, +C55875BCB82C, +C581CA998910, +C5ABC0A455C5, +C5BE33E6B1E2, +C629E0D34581, +C65194543D6B, +C67B8E869D90, +C6BC3B9CCB41, +C7034BC581A6, +C748500B6947, +C757C15E9E0D, +C798A8465ACB, +C7B6702AC17B, +C849133B7CCC, +C870C98A4E91, +C90B7AD266D3, +C90D996C3A2D, +C953797CCE61, +C9639352EEC8, +C983685AA86B, +C9CCA6D095A3, +C9CE81D47EDB, +C9D449AD9970, +CA0D9CCC4C38, +CA277AC09859, +CA56EB045188, +CAB92B865BAD, +CAE8572C2657, +CB1CE185575C, +CB2ECC3D9C22, +CB642A081A89, +CBBAD2DA0EC5, +CC1B5BD45315, +CC2C02300D34, +CC559969D0CC, +CC5646BD7AEB, +CC6A93BD93D1, +CC726DD08765, +CCBBAB6504A4, +CCC1EA3E27B8, +CD16EAB946E9, +CDB4EEE02E14, +CDC21E1E1EC7, +CE09B3870EA2, +CE5AA0C8B5A8, +CE63DE29E069, +D0368B24CA49, +D0489010A72C, +D075379A21A6, +D09893B4EE04, +D0A7A2787570, +D0B8C06C02E4, +D106E94A4C3B, +D11E7D1BBEEA, +D12B25B8DDE2, +D1972D6CE2C3, +D1B91D224946, +D2752E53679D, +D35B2B75CC52, +D40E935117A2, +D4C37528DC05, +D4C818A5455E, +D4CD56DB8AEB, +D5190BD5CED6, +D55E5AA3406D, +D576E9D856D9, +D5E444E9D82D, +D61A3231790D, +D669B3AE1E11, +D6C075899D06, +D6C3503456C4, +D7AC70A05A0C, +D80A37B6D7ED, +D82E6938C58C, +D85E51344EB6, +D8809EB9BA7D, +D8913C2D48E9, +D9109460D912, +D94E36427E20, +D97E55B1816A, +D99425130C1A, +D99C3222A190, +D9A207103ED7, +D9C70CC5818A, +DA3379D12773, +DA705702248C, +DA818C56CE43, +DAE1888DCC0B, +DBA0A2DCA8E0, +DBD9799E15B1, +DC242193D7E3, +DCB5AC62946C, +DCB75AEC61A0, +DD6E0587A821, +DD7B1A7C6A82, +DDA22A189095, +DDDAE53AA711, +DDE7304E78B6, +DE1B4DA681B9, +DEAC67E2D7C1, +DEB7D7E4C62B, +E127434AB3B7, +E1ACC6742AB7, +E1E59574ADBC, +E1EA6BAA03D9, +E222553A59A2, +E2230B8E84C9, +E33E807EC3BA, +E341574B2E32, +E42868808B70, +E43562C624B0, +E43D54DC3511, +E466090D2123, +E47069DA0C44, +E49DD6062901, +E4ACA0ADBA0D, +E4B976AD6687, +E526BB7888DB, +E53354B71B10, +E57581CE8617, +E61A1DA5A60E, +E6293BDA5EDC, +E64C2A07CA9B, +E6600C4D6A44, +E6655B6425DC, +E6BADC631036, +E70143BE0091, +E75E07A010D1, +E76962E3B8B4, +E8028A6DCC90, +E80C5E3E8227, +E8779E40450E, +E8A9E2D87D36, +E8B5A0BDD993, +E933DA9735C4, +E93A2E63189D, +E9447637E40D, +E94836269887, +E94D82A564BA, +E98DC3B561B5, +E9EB2DE57AE9, +EA490920877D, +EA4C494C9353, +EA9B1695DD91, +EAD0E31A6834, +EB16B6462B66, +EB276C9AB68D, +EB3C9732C3BA, +EB44DDC408CE, +EB8536C958B2, +EBC825C186B3, +EC1A55BB58EB, +EC2B12107313, +EC8CB5758097, +ECD4C42EA3D1, +ED22B7115435, +ED2CE17A590C, +ED65A9B6469C, +ED6748113E0D, +ED8CEB8B7102, +EDCE0890472D, +EDD4A2EA7493, +EE17C426D25E, +EE487A4C806E, +EE5931913A8D, +EED56840AEBA, diff --git a/client/dictionaries/icbpm_sort_keys.dic b/client/dictionaries/icbpm_sort_keys.dic new file mode 100644 index 000000000..b4a635d44 --- /dev/null +++ b/client/dictionaries/icbpm_sort_keys.dic @@ -0,0 +1,1001 @@ + +00383D96411D, +005307DB7853, +009A4C4C6C49, +00C447B8A2D2, +01124119AB54, +0117BAE4D8D9, +018861488381, +0267B4922681, +02974B9786C9, +02A46AC9233A, +02BED876BD48, +02D8A7729ED3, +02EB32B92D30, +03C34821DE9A, +03D87397E9A8, +042CDEE5D0BA, +044ED79417E1, +04524659496E, +04602A40C037, +048451A79DA1, +0490AD0C9283, +04E16965C142, +05138E278443, +052B99EC186E, +056D4B5D2915, +0578E317C419, +05865124E5CA, +0599E014139E, +05DB68DB9364, +066C127C208D, +06966B31A285, +06B577E0E480, +071B57D258CE, +072B300309C9, +0759955331EE, +0769855EEC13, +079B8DA54DB1, +082B68A67491, +0832E4783600, +08506533E741, +0853A982D793, +08629D1DD0D6, +087C0CDA3B46, +08AE4ECD7CE3, +0965220D2ECE, +09A14A80754E, +09ACEA48DD0D, +09DB8EE5458C, +09E6CB76C080, +0A44A754B592, +0A7328887DC2, +0A906663EE1C, +0AB08938E3DA, +0AD8AD0739A6, +0B00220EAE75, +0B1960681E79, +0B31815E6A7C, +0B3690D4B122, +0BB8414CB6EA, +0BEC525E3463, +0C296648344D, +0CB6CC83AC45, +0CCAD03DDBC6, +0D6C26AB25CD, +0DC9143735D1, +0DE8A36CBBCC, +0E175033BD77, +0E6478123917, +0E7D4AC83133, +0E8420B04083, +0EA607E1C4E3, +105743704432, +107A6AB6B305, +110BB6D5539D, +1114A47CC39A, +116AA873ACC8, +120616C6208E, +120C83C06317, +12343D71106C, +123A082E2AEA, +12E50BE60524, +133DC845505E, +138153A4351A, +1395C108B6B6, +1428C04BAAD1, +147D93848C70, +14A353C60820, +1504C1846399, +1523A1E39D03, +1532A2511A8B, +157308368E8E, +16065CC411E0, +1637D8ACA71E, +1639134699C7, +167358BB268E, +168DE72B3B5A, +16A05D5C31C3, +16B4442EAE97, +17197B247A4A, +1774DB1A8CA1, +17820DAA47B2, +1782BEDBD347, +17B561AA82B4, +17C548CBC3A6, +17DA5C873BC5, +18025130661E, +184B95B4E3C6, +18A3196D364B, +18A97BD26818, +18BE810A83DD, +18C3AC2A7E90, +194D4E1DE89D, +196E279BE9A9, +1A2C8D855336, +1A3A76ED470A, +1A55D4849951, +1A9872D00EC9, +1ACD5433BBDD, +1ADC527D5BDA, +1AE29C8CD672, +1B14CAC3D0C2, +1B20A6E1D06B, +1B30A7825B23, +1B3E45AEE657, +1B75E7B007DB, +1B9DABDEBAE0, +1BAB19D01495, +1BD3119E0363, +1BDA0D87A575, +1CD38D77090B, +1D12BBB575B1, +1E1A0DB8729C, +1E2DE60A477A, +1E3C71643766, +1E6ED46CE258, +1EE60A4A8D22, +200D45263629, +2013899194BB, +206CE78E0C6C, +20B51C977E54, +2142B57D369D, +2172D827D3E2, +2178ED80D581, +21B4BE97AE07, +21B91A26133A, +21C7650673CD, +220D815D366A, +22C2176E1CD6, +22C3AB41B123, +233D7B324CEE, +2340CBD61A71, +2348251AD23E, +2381B8214025, +23BAE8DA1AC5, +23C317B8D6DA, +243A41574A39, +248EA5E91987, +2491457885A7, +255A9E590BCC, +257192699E32, +25892216C620, +2595E5B1DE76, +25AE69DED1B4, +25BA8775B3C4, +25D967D4DD35, +25DB996D56ED, +25EE21CDE4B9, +2625E408276B, +26B744C673DB, +26C6D38B8257, +26D787613684, +27689527E201, +27743B5A5736, +27D1635ED1B3, +27D5B8D2642E, +28035CA5B300, +2812EB6A427C, +28133B46730A, +281499DD16A0, +281DD9E6C98E, +2870E08CEDBA, +28B8685B1B22, +28C3D17E4DEC, +2953C63E9E58, +295D3C9A8B28, +297B74853CAA, +29ACACC2828E, +29EA97BC4A6B, +29EB3CA1C0DE, +2A079CC2AD37, +2A27E0602400, +2A45A0D8D6EE, +2A47CDD3A322, +2A4C4DB1D71D, +2AA82B4B6711, +2ABD68BDC5A3, +2AE7BDB10CB4, +2B051C90BE82, +2B490231E063, +2BAB94372644, +2C03252C10E7, +2C3EE5E98804, +2CB671E6365D, +2CC55B46705B, +2CD09D3C0A1B, +2CECBC323E31, +2D302827C9B4, +2D716C9C467B, +2D8856109732, +2E15681A4355, +2E79209B9519, +2EEE063290C1, +301C9AA3DECA, +30C520D6A2B9, +30D6324910AB, +3113AADC9D6B, +3124ACA5491C, +315AD0D6E6D2, +31A16DAC864D, +31EC44581294, +32DE3CD81C24, +32E532232C29, +33256E443128, +33293485AD61, +33305B0365AA, +3343B72BAA71, +3372C9C5D4AE, +33754E0D1687, +33A444334869, +33B54345C32E, +34002AAEE45D, +343C556CEE59, +3444DDE6D7E5, +345B62452538, +3495A04A9270, +34EB673C863B, +35123500C1EA, +353A7167576B, +3599856810B2, +35E7DE9899EE, +35EDABB506D8, +36C54912D10E, +36CA0101B6DC, +36D268442846, +373E5827E0B8, +376D6C446746, +37E2EAE635B5, +381B0A70E135, +3862B259DC71, +386676C44A13, +3905679DEEC4, +39070618BB17, +394181105544, +395D38815892, +39A00E856381, +39C0E2ED99B5, +3A1E82E2CDB7, +3A5D13E05B6A, +3A6DE2081CDD, +3A8498924010, +3A9D49E8BEB2, +3AD0EE1031A9, +3B052E65D40A, +3B4986981212, +3B4C51ACC53D, +3B99486097C6, +3BB36BC22CE4, +3BB4B3025B79, +3BBB7BD8D7B7, +3C09C971D835, +3C4A12E7A107, +3C633B3474DD, +3CB9E31D6022, +3CD344A7EB21, +3CD8C6705954, +3CE887B9D091, +3D5EA1C71953, +3D89120EB993, +3D9C3245AE76, +3DED9D496478, +3E0913A96E74, +3E34909990B5, +3E7DD7953DDD, +3EEB33434C1A, +4015D16B5C1C, +401C81A72C56, +40E7B8D60242, +41016C0CB8DE, +4124864B0D40, +415BAA0CAB15, +418184DBB4A0, +419513740558, +4195EE7238CC, +41B727883B27, +41BC44A8C3C6, +41DDC3A48EEA, +420445087613, +42068108DE36, +4245921D73CA, +42A959953C45, +430E67734C18, +4314D9D03B95, +43166BCA83EB, +43400A093A7E, +434CE764DE91, +43595AC786EE, +438099331C1E, +43814087A7B5, +438C3CD95B58, +43B3E895B281, +44074C461042, +444D37149B20, +44A04DAA30CB, +4537282554C5, +4584EACB6087, +45DB3799C150, +45E599AE38EA, +462305611C4A, +4636195CDA2D, +46752993E2E9, +4684316440D6, +46C7246C1958, +4751A5274848, +4761E34CB054, +476388408D8E, +478947735B45, +47AD81972D5B, +47C23398EA52, +47E9D4D4BE35, +4812AEC4B01A, +48276645A4EA, +48644467A214, +489C783B3514, +48C860AA4B74, +495C6639575B, +49681C20A00D, +49E8249DD677, +49E93C110AA1, +4A24470C19C5, +4A4755BC4A2A, +4A4D5E3A9011, +4A65D627625C, +4A6B36C5BCCC, +4AB725ED89B5, +4B39E3923D0D, +4B59316C10E0, +4C275C8BB2DA, +4C2E9455D296, +4C44DB1D0C3A, +4C67059B0006, +4CA30E1A298A, +4CA74DAC7C01, +4CB212D72D57, +4CD3B228EBB4, +4CE1972E090C, +4CEE1794E0EA, +4D06DBCA167E, +4D2CC85EB338, +4D40BC7A44DB, +4D769DA515D3, +4D79C95DAD2D, +4DBAC8ECE167, +4E3CB839E87D, +4E3D548E1267, +4E8250E29617, +4E94C7962769, +5038884E4178, +505B5A8EB20A, +50642C36DA00, +5083664D8C09, +50B77DA96DE2, +511E269A9BAE, +51798AEAAE9E, +51ED5833AB6D, +525335E4CD34, +5261CDDA279E, +526E55542A54, +529C16A720AB, +52A230B1C50E, +52AADA374811, +52D20D6E3E35, +534BB4A6984E, +5352CCC3DCD2, +540B15E8019D, +54AA2915E815, +558DB8891A90, +55A691710B48, +55D1E91B1D35, +55D95774E9A0, +563C6B96D59D, +567032E13B54, +56741B108D22, +57029D991123, +5714E9D33034, +5734CD8A65DA, +5785EE00049E, +57B8B111491D, +57CC9D0AA32B, +57D7D4D746DA, +583C936DCB4B, +586B470A43B3, +5876E1D34183, +58B6AE62DB88, +58C35C8BC9AB, +597E98000ED4, +59DB4DBB5D7A, +5A150653E624, +5A211CE57C4B, +5A6272CDBE9C, +5ACB8043C10C, +5B41CEBC2213, +5B59BCC4321E, +5BA03479BB8C, +5BC64C42281C, +5C9B1A8E31CD, +5C9BD0AC1DB1, +5D223E990AD8, +5D8C3A5C5761, +5DA57EACA38C, +5E41DD5D1154, +5E6ABB51EC75, +5E7CC04C3A58, +5E810C48C8D8, +5E8943D9A836, +5ED616273468, +60100DD0E023, +6033A1C0E431, +6088A566CC60, +60B20ADA0471, +60B8411D876E, +60C742D8D9C0, +6135433CC5EA, +6153ADD80A15, +61718ED2C94D, +6175241B035A, +61780BCB0C57, +61B701698050, +61C4E56629A3, +61D59C284952, +61E57B490A55, +622E5E0812D7, +6251CE7E547A, +62953A89B137, +62D6EAA06CD6, +630228659A47, +632931BE8EC7, +63539BB89DEE, +636CB69BB10C, +63783393E20D, +639DB16995B7, +63AA2A5B076C, +63B636458E94, +6443E64DCC4B, +64695084C575, +6493D06D5710, +649B302A97C5, +64B8632B54D4, +654BACB21C3B, +65A3D5823819, +65DEDABD1B34, +6608944EE186, +665B8B24C20D, +6685D0BE19E0, +66933A9E7982, +674C7BB59A16, +675E35EE359E, +67AA98E362C9, +67D47C1B6425, +67DE22850162, +67E8B986B2A7, +681EA28BA6CD, +6828B52B6507, +6874E54471E8, +6879B1CA44A3, +68C00A810D41, +68C9E8AA5C3E, +697A8ED07418, +69B5357A617A, +6A7B3A7B6735, +6AA40421D23C, +6AB676B4DB9D, +6B00420BE41C, +6B0B7B967871, +6B9D041136B4, +6BB1A14768A8, +6BCAE24D9700, +6C0458728774, +6C57CBD51995, +6C5E10B86CDE, +6CA491A8C7B8, +6CBC25C1DA2E, +6CD430D99958, +6CEC27647CC0, +6D4D29CEB9B5, +6D6E9A6B725D, +6D801AC74572, +6D97408C6D60, +6DDE6E871C64, +6DEA848B6195, +6E05B5C44A54, +6E751666AE9A, +6E7DBCDA05B3, +7004BA1763ED, +7016ECD01559, +7076D48D5E49, +7091621EA016, +709311997549, +70984C14D3DB, +70D73BE22CDD, +70D9461C5E90, +712BC18422CB, +712E6CAA74A4, +7164042BA89E, +7175E14A4D62, +718B39561350, +718BDA352E28, +719B1418323E, +71A8D54D82B3, +71DC30168C27, +7221E016597B, +7234CC6BD65D, +727A80DD5296, +72B393D6E8A9, +732C9BE4DDBA, +736B4A835B2B, +73EA81968900, +740AB5126199, +741A31054E6B, +74498C1D4B3D, +745276053CB6, +74684B0B4B1D, +74772915E24C, +74A24BE33BE2, +74A778236D5A, +74AA58008A31, +74C27A96CB3A, +754AD5773746, +756C15E54212, +759403A563D8, +759D2130312B, +75A0E10D8C84, +75A807E46B96, +75E454785C6C, +76078A25C088, +76140285B768, +763D835BD5ED, +767C33468C72, +76962C07EC9E, +76984E62CCE4, +769AE4646931, +76E5DA67A1EC, +7708D5CAD58B, +77383BAA4D90, +7789E646A556, +779A248E098C, +77DB71037644, +77E0A57DD456, +7853D464E2A4, +78EA6EB04463, +7909427EC8B9, +7910A31ECD19, +79271963B6E8, +793D98517D33, +79B7A4C58DE0, +79B9148761B3, +7A2893B75AD1, +7A4C61A1B48D, +7A7469B69C6A, +7AA84B1A527D, +7B00211CA416, +7B118EABC7BB, +7B1D9A2E22AA, +7B583D350740, +7B9D3A6BD061, +7C2DAC2CC775, +7C4CBBD2DDE1, +7CD52B5B8E77, +7D412100532B, +7D46C149DAD9, +7D4CA630E229, +7DAC0E83D335, +7DC935E220A0, +7DCA66BACA13, +7E30778792D2, +7E43C3BAB3CB, +7E475BA186E6, +7EE2A624851A, +80CED5362B2C, +80D2CC78E10B, +80D62251E20C, +816875D55ED1, +81950D0517AC, +81B519418C3E, +8211571B9D16, +823C7CC6E06A, +826DD63B9032, +827303C574B5, +82C5ADED4B81, +82E344329D34, +83588E140165, +835D33B48113, +8384148AE52D, +8394B57153D6, +83A0184757C0, +83D86835B48B, +8502EE9A7E85, +852C2B72659D, +8534A6CE0911, +85ABD94CD7A9, +85DA8099CD7E, +85E0B6B26945, +864CA2A6BE93, +868A33A44447, +86EDEABCC357, +87DDD5A188EE, +8830379B50B7, +883803A3360C, +883DA78EC87D, +88482A12C2C6, +888EBD3DB945, +88D026793359, +88DD4B7C5991, +8931DC3733D4, +894D8E2DCDEE, +897B845C2680, +89B638BD909E, +89D2C28BE578, +8A1869848D1A, +8A39D09508C9, +8ACCC7290C8C, +8AD8B41EC218, +8B028B7E6D60, +8B6A95C7D2E2, +8BA1226EBA21, +8BD586B21ABC, +8C0EA504B635, +8CA939DC6DE4, +8CAE5D688443, +8CEC639E64DC, +8DECE0DD29DE, +8E0EC762E883, +8E958D8B8C52, +8EB64D710C88, +8ED4A17717D9, +8EE9D9C03A0D, +9014E1430AEB, +90965DEBC8B9, +90E56E616DDD, +912CD8E04437, +912E33563E1B, +918048032247, +919402EC39CB, +91D28E2B126D, +9216EEE5B677, +9232215296B2, +925A070E9096, +925A5521D48D, +92CC200886A2, +932035869655, +937144459949, +93B260DBC70A, +94552B863E37, +95327A0A3600, +954275CDD7E0, +957E6EE3EB55, +95B920CACC84, +96382E1C8E12, +964E8E5338BD, +96706C8D6ECC, +96759A0D5566, +96D5213C5DDB, +97300764797A, +973BDDBE7434, +974838AE17A0, +9752A6B316D5, +97926543783B, +97EB373096CA, +982D6054B83D, +989D127BD496, +98A54AD58A43, +98A92128364C, +98CD5AA2A4DB, +98E8C543688E, +99207A00AA4A, +99243E754CB8, +9925893ABAC7, +9937553A965E, +9976E6ADE0C9, +9982E3E6A4A0, +9984C1A3229E, +99C487AB85EC, +99E2A19C9673, +9A05EBE41D7D, +9A138D1A5CB7, +9A179148B824, +9A6EC0A9ECB8, +9A720CBD7BB1, +9AB22BBDDD87, +9AC43B5A06D8, +9AD8150BE648, +9AD97423190D, +9B4ADDDEB749, +9B7603341727, +9C45237377BE, +9D090AE1A15E, +9D59641E40A5, +9DA4528CEB8C, +9DA728164176, +9DAC62A346B7, +9E0E9D983B9A, +9E5271763D3D, +9EE95586D024, +9EEE39E00CBB, +A04671256EE2, +A091485B4B5D, +A1B5577ED36E, +A1EB280E3901, +A2789E1DD888, +A293A90AE72C, +A309E3AEBDB9, +A3196E77B072, +A31E72DCC826, +A34DEA01690E, +A36031D6ECB2, +A38044A3E18E, +A421D7A04C4B, +A424C686CA39, +A44590A779A5, +A47AD3895C63, +A5041E8B8E22, +A50DC0830AA5, +A52B8929D665, +A5BCBA6BE592, +A61D5137E6B3, +A6344C0418DC, +A690A817B9D9, +A7E3B3459240, +A81E6D3C8E11, +A8C0BE436685, +A8DE205120A8, +A91E2BE6C308, +A9258D6B06B5, +A992B5E070C1, +AAC6E3205D48, +AB101546634E, +AB6EE0761ACA, +AB9BCA200547, +AC4BC5B2D3C0, +AC7A0B47B03E, +AC88B26AC1D0, +ACAEB3456AD9, +ACB906631D8A, +ACE07B45C0C5, +AD1992AE37CA, +AD5586744A60, +AD674E4ADB79, +ADA093B06831, +AE7C3AE5334A, +AE9EB8CAB2C3, +AEAE9E5CE65D, +B002D1BDC29B, +B0463E703098, +B063B209BB20, +B0788BE3BAA4, +B0C3B3299090, +B128298D9073, +B160677E7035, +B19D3D57176A, +B1CCDB7999B9, +B231AA398B90, +B250E9590215, +B28BE0D819ED, +B292C9554CBA, +B2D8485C2460, +B31763D9D0DE, +B328014DDD6A, +B378C424C9E2, +B3D8C03C78E0, +B41D18E3B980, +B46824B972E9, +B50383A32302, +B509D631967C, +B56CA847A7C3, +B56EC9A20D28, +B5B763215C82, +B6550EAC573A, +B66060201705, +B6614EBEAAA2, +B6A18CBD4DA6, +B6ABB62E437E, +B6C6558E58CA, +B7009204D512, +B71D5B22B1C2, +B7392DD1E497, +B7709ED7CE60, +B7A26320A491, +B7A9DA22E9C6, +B7DEC863369D, +B7E9A91174CB, +B8178A34E2DC, +B83092098A7D, +B84C50E56DEC, +B89BD135E935, +B8E87380D361, +B9485A9648C6, +B9ED829C22AE, +BA227EE91818, +BA7BBD9683B1, +BA8224EA7A80, +BA84C974B356, +BAD293A45C8A, +BB850C7E4934, +BBC1256810A4, +BC1CD369549E, +BC5C76E5909C, +BC66E9270049, +BC6AB08B03CC, +BC74CA2C2B06, +BC7C64828C1D, +BCCC3A719013, +BD06E96EB7D7, +BD196D0A74E0, +BE02790E84AC, +BE1266314B9D, +BE518C742B74, +BE5695316117, +BE5D8EBA120D, +BE8286DA7D12, +BE9CE00EE4DD, +C003962B3462, +C0067E095049, +C015A21E0146, +C03BC03AD437, +C06CE7D57A0D, +C07EE1E10B56, +C0885A29251E, +C198163ABECE, +C1EB7337A035, +C225479C7064, +C2740E1665A8, +C27924128A00, +C2A701656B8B, +C2C30D21C53E, +C2CBB2ACD38D, +C38D19A9C8D1, +C3B1BB7E7492, +C3BA2438A981, +C3CD74758DE2, +C4033B3BB1D7, +C404D280640E, +C4467DE80B2D, +C46A048C88DD, +C52877867C05, +C56D005E258E, +C56D052D5533, +C5BB2CCCB9C3, +C5C272694A1E, +C6121BC4A29C, +C65EEAE02433, +C661C4AE1DD1, +C76C94B495CA, +C7BD49777A79, +C7CD131E9B60, +C7E35D6294BA, +C8E173DB04CC, +C95855AE08E8, +C98147E69033, +C99A004E6133, +C9E893C4090B, +CA119C79A197, +CA309D2CBC41, +CA4BAA390BC4, +CA92DD257E21, +CA968EBEB9C7, +CADED0C50AC4, +CB18774EA550, +CB1999D19E10, +CB75C1BAE669, +CC2517AB2346, +CC2AC1AD29CA, +CD11359C7A90, +CD14C8553CB9, +CD333295BBE2, +CD3DB8C27E5C, +CDA811AD5055, +CDABDCA23986, +CDCA8BD7B002, +CE0456AB0DCE, +CE58AE1C51E9, +CE76E8A600DC, +CE95875316C8, +CEB105E65289, +CEB651752D4C, +CEE02D97E5BD, +D023DB35ED05, +D0BE546CC06B, +D0CE7EB0D379, +D10329D366C8, +D15C004DBC8D, +D16E6B668254, +D1CEEC977644, +D1DC0E1CC09E, +D2550925679B, +D28B2D42DE1A, +D2926519AC09, +D313116A45B4, +D3DC10453857, +D431C8C73BDC, +D4C67846791C, +D5629384CE7D, +D5ABE7180600, +D62A4A0E57C2, +D660CE9E3080, +D66AE9282140, +D6A91C14AC47, +D6E23B4E75C6, +D726C4979654, +D76DE12943B4, +D7A405AD9E4E, +D7BD3AE48E93, +D7D49700BBCC, +D7E8A5089E7A, +D84C81EE910D, +D8545199A949, +D86243C1380E, +D88A12EB3622, +D89B5EA419C1, +D8A3690B0115, +D94646A4C65B, +D982B4846A96, +DA303BADB013, +DAD9A48A8C33, +DAEB5D63920B, +DB01A99DD94C, +DB22BB7D6818, +DB37160CBB4B, +DB7E3687E450, +DC7697E37A9B, +DCC44C4E9269, +DCCE477E785E, +DD68DE9CDA5A, +DE1B08C6D94B, +DE41BBD7E68D, +DE6E04AE4475, +DE8CD4277A9E, +DEA8098D6E51, +DEB2BEE8858A, +DEB550958AD9, +E045E6309471, +E0E21213C611, +E0E457054B62, +E1097C69DA4A, +E1EA831EA514, +E20716902884, +E2C9CB14C06C, +E33B66EA2705, +E34C5B12BABA, +E38A1C654E82, +E3905BA54194, +E3E3919444CA, +E4450EC1010C, +E49A03306224, +E5100AC4C6C3, +E5124DB665A6, +E5491B5E3DD6, +E5BE9C989A29, +E5C3A9A27D3E, +E65111EB1E40, +E65792427D4C, +E7004C5EA94A, +E705087DECBB, +E7CB93E68155, +E81512343BAD, +E8428C8B0740, +E859EBC22318, +E87267A508DB, +E886AE7D1BE0, +E8B008239600, +E8C4B4A4E482, +E8D53410B736, +E902964DA28D, +E9203D5BD2DA, +E9526CACA8B2, +E9C11D763BEC, +EA3BDAA4E498, +EA61AC8B4969, +EA8E8ADC26B9, +EB5588EAE5E8, +EBA964C07075, +EC71B679D3AA, +ECB4019ADD97, +ED14D0A14B0C, +ED296C79266C, +EDBA3C943EA8, +EDC7CEBD4000, +EDE2747DA6C3, +EE3029556CEB, +EE49610E6121, +EEB704D69BCA, +EED69A391464, diff --git a/client/dictionaries/mrzd_sort_keys.dic b/client/dictionaries/mrzd_sort_keys.dic new file mode 100644 index 000000000..025f1b995 --- /dev/null +++ b/client/dictionaries/mrzd_sort_keys.dic @@ -0,0 +1,57 @@ +010203040506, +013940233313, +022FE48B3072, +123456789ABC, +123456ABCDEF, +17505586EF02, +1795902DBAF9, +1A2B3C4D5E6F, +1A982C7E459A, +200306202033, +2011092119F1, +2012053082AD, +37D4DCA92451, +40E5EA1EFC00, +435330666666, +46868F6D5677, +474249437569, +4D3A99C351DD, +533CB6C723F6, +5554AAA96321, +587EE5F9350F, +5A1B85FCE20A, +5D293AFC8D7E, +64A2EE93B12B, +64E2283FCF5E, +714C5C886E97, +833FBD3CFE51, +83BAB5ACAD62, +872B71F9D15A, +8F9B229047AC, +8FD0A4F256E9, +9AEDF9931EC1, +9B1DD7C030A1, +A0478CC39091, +A0A1A2A3A4A5, +A2B2C9D187FB, +A4EF6C3BB692, +AABBCC660429, +AABBCCDDEEFF, +ABCDEF123456, +B0699AD03D17, +B0B1B2B3B4B5, +BA28CFD15EE8, +BCFE01BCFE01, +C0C1C2C3C4C5, +CFC738403AB0, +D0D1D2D3D4D5, +D3F7D3F7D3F7, +DB5181C92CBE, +DFED39FFBB76, +E1DD284379D4, +E96246531342, +ED3A7EFBFF56, +F83466888612, +F89C86B2A961, +FFFFAE82366C, +FFFFD06F83E3, From bccdde01236498fa19b4b82e15b5a1a80dc6d6cb Mon Sep 17 00:00:00 2001 From: RFID Research Group Date: Thu, 24 Jan 2019 11:49:04 +0100 Subject: [PATCH 122/320] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3b04ea5f8..940722506 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,9 @@ --- name: Bug report about: Create a report to help us improve +title: '' +labels: '' +assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..ff12e62f1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[idea]" +labels: Request, enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 4fe4d74bfe99dbcb57d98fa93805d7acb0c7f61e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 25 Jan 2019 11:42:52 +0100 Subject: [PATCH 123/320] FIX: 'emv roca' - not executing when client is compiled without WITH_SMARTCARD functionality, like for old devices see https://github.com/RfidResearchGroup/proxmark3/issues/85 --- client/emv/cmdemv.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 91a3663f3..453d08a20 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1599,6 +1599,14 @@ int CmdEMVRoca(const char *cmd) { if (arg_get_lit(2)) channel = ECC_CONTACT; PrintChannel(channel); + +#ifndef WITH_SMARTCARD + // not compiled with smartcard functionality, we need to exit + if ( channel == ECC_CONTACT ) { + PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting."); + return 0; + } +#endif // select card uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; From 803aab74311d5c61c00247c2268b2a410d79e218 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 25 Jan 2019 11:58:00 +0100 Subject: [PATCH 124/320] FIX: 'hf legic sim' - longer timeout for writes? (@drandreas) see https://github.com/RfidResearchGroup/proxmark3/issues/83 --- armsrc/legicrf.c | 62 ++++++++++++++++++++++----------------------- armsrc/legicrfsim.c | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 00d284926..958d3421a 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -61,7 +61,7 @@ static inline uint8_t rx_byte_from_fpga() { WDT_HIT(); // wait for byte be become available in rx holding register - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { return AT91C_BASE_SSC->SSC_RHR; } } @@ -81,7 +81,7 @@ static inline uint8_t rx_byte_from_fpga() { // To reduce CPU time the amplitude is approximated by using linear functions: // am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq)) // -// Note: The SSC receiver is never synchronized the calculation my be performed +// Note: The SSC receiver is never synchronized the calculation may be performed // on a i/q pair from two subsequent correlations, but does not matter. static inline int32_t sample_power() { int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q); @@ -100,7 +100,7 @@ static inline int32_t sample_power() { static inline bool rx_bit() { int32_t power; - for(size_t i = 0; i<5; ++i) { + for (size_t i = 0; i<5; ++i) { power = sample_power(); } @@ -120,12 +120,12 @@ static inline void tx_bit(bool bit) { // insert pause LOW(GPIO_SSC_DOUT); last_frame_end += RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; HIGH(GPIO_SSC_DOUT); // return to high, wait for bit periode to end last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; } //----------------------------------------------------------------------------- @@ -143,13 +143,13 @@ static void tx_frame(uint32_t frame, uint8_t len) { // wait for next tx timeslot last_frame_end += RWD_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; // transmit frame, MSB first - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { bool bit = (frame >> i) & 0x01; tx_bit(bit ^ legic_prng_get_bit()); legic_prng_forward(1); @@ -158,7 +158,7 @@ static void tx_frame(uint32_t frame, uint8_t len) { // add pause to mark end of the frame LOW(GPIO_SSC_DOUT); last_frame_end += RWD_TIME_PAUSE; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; HIGH(GPIO_SSC_DOUT); // log @@ -173,19 +173,19 @@ static uint32_t rx_frame(uint8_t len) { // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; uint32_t frame = 0; - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { frame |= (rx_bit() ^ legic_prng_get_bit()) << i; legic_prng_forward(1); // rx_bit runs only 95us, resync to TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; } // log @@ -203,23 +203,23 @@ static bool rx_ack() { // hold sampling until card is expected to respond last_frame_end += TAG_FRAME_WAIT; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; uint32_t ack = 0; - for(uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) { + for (uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) { // sample bit ack = rx_bit(); legic_prng_forward(1); // rx_bit runs only 95us, resync to TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; // check if it was an ACK - if(ack) { + if (ack) { break; } } @@ -282,7 +282,7 @@ static void init_reader(bool clear_mem) { // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier. legic_mem = BigBuf_get_EM_addr(); - if(legic_mem) { + if (legic_mem) { memset(legic_mem, 0x00, LEGIC_CARD_MEMSIZE); } @@ -309,7 +309,7 @@ static uint32_t setup_phase(uint8_t iv) { // Switch on carrier and let the card charge for 5ms. last_frame_end += 7500; - while(GET_TICKS < last_frame_end) { }; + while (GET_TICKS < last_frame_end) { }; legic_prng_init(0); tx_frame(iv, 7); @@ -359,7 +359,7 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) { // check received against calculated crc uint8_t calc_crc = calc_crc4(cmd, cmd_sz, byte); - if(calc_crc != crc) { + if (calc_crc != crc) { Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc); return -1; } @@ -399,15 +399,15 @@ void LegicRfInfo(void) { // establish shared secret and detect card type uint8_t card_type = setup_phase(0x01); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // read UID - for(uint8_t i = 0; i < sizeof(card.uid); ++i) { + for (uint8_t i = 0; i < sizeof(card.uid); ++i) { int16_t byte = read_byte(i, card.cmdsize); - if(byte == -1) { + if (byte == -1) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -417,7 +417,7 @@ void LegicRfInfo(void) { // read MCC and check against UID int16_t mcc = read_byte(4, card.cmdsize); int16_t calc_mcc = CRC8Legic(card.uid, 4);; - if(mcc != calc_mcc) { + if (mcc != calc_mcc) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -436,19 +436,19 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // do not read beyond card memory - if(len + offset > card.cardsize) { + if (len + offset > card.cardsize) { len = card.cardsize - offset; } - for(uint16_t i = 0; i < len; ++i) { + for (uint16_t i = 0; i < len; ++i) { int16_t byte = read_byte(offset + i, card.cmdsize); - if(byte == -1) { + if (byte == -1) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } @@ -468,26 +468,26 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) { init_reader(false); // uid is not writeable - if(offset <= WRITE_LOWERLIMIT) { + if (offset <= WRITE_LOWERLIMIT) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // establish shared secret and detect card type uint8_t card_type = setup_phase(iv); - if(init_card(card_type, &card) != 0) { + if (init_card(card_type, &card) != 0) { cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; } // do not write beyond card memory - if(len + offset > card.cardsize) { + if (len + offset > card.cardsize) { len = card.cardsize - offset; } // write in reverse order, only then is DCF (decremental field) writable - while(len-- > 0 && !BUTTON_PRESS()) { - if(!write_byte(len + offset, data[len], card.addrsize)) { + while (len-- > 0 && !BUTTON_PRESS()) { + if (!write_byte(len + offset, data[len], card.addrsize)) { Dbprintf("operation failed | %02X | %02X | %02X", len + offset, len, data[len]); cmd_send(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 1816a29ca..d51747555 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -46,7 +46,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ #define RWD_TIME_PAUSE 4 /* 18.9us */ #define RWD_TIME_1 21 /* RWD_TIME_PAUSE 18.9us off + 80.2us on = 99.1us */ #define RWD_TIME_0 13 /* RWD_TIME_PAUSE 18.9us off + 42.4us on = 61.3us */ -#define RWD_CMD_TIMEOUT 40 /* 40 * 99.1us (arbitrary value) */ +#define RWD_CMD_TIMEOUT 80 /* 80 * 99.1us (arbitrary value) */ #define RWD_MIN_FRAME_LEN 6 /* Shortest frame is 6 bits */ #define RWD_MAX_FRAME_LEN 23 /* Longest frame is 23 bits */ From 730a7e8044bb08c4df93b7b80d429581864130a3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 25 Jan 2019 13:48:53 +0100 Subject: [PATCH 125/320] FIX: 'hf legic sim' - needed even more timeout. see https://github.com/RfidResearchGroup/proxmark3/issues/83 --- armsrc/legicrfsim.c | 61 ++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index d51747555..86448275f 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -46,7 +46,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ #define RWD_TIME_PAUSE 4 /* 18.9us */ #define RWD_TIME_1 21 /* RWD_TIME_PAUSE 18.9us off + 80.2us on = 99.1us */ #define RWD_TIME_0 13 /* RWD_TIME_PAUSE 18.9us off + 42.4us on = 61.3us */ -#define RWD_CMD_TIMEOUT 80 /* 80 * 99.1us (arbitrary value) */ +#define RWD_CMD_TIMEOUT 120 /* 120 * 99.1us (arbitrary value) */ #define RWD_MIN_FRAME_LEN 6 /* Shortest frame is 6 bits */ #define RWD_MAX_FRAME_LEN 23 /* Longest frame is 23 bits */ @@ -59,8 +59,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ // Returns true if a pulse/pause is received within timeout static inline bool wait_for(bool value, const uint32_t timeout) { - while((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { - if(GetCountSspClk() > timeout) { + while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { + if (GetCountSspClk() > timeout) { return false; } } @@ -81,12 +81,12 @@ static inline int8_t rx_bit() { uint32_t bit_start = last_frame_end; // wait for pause to end - if(!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) { + if (!wait_for(RWD_PULSE, bit_start + RWD_TIME_1*3/2)) { return -1; } // wait for next pause - if(!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) { + if (!wait_for(RWD_PAUSE, bit_start + RWD_TIME_1*3/2)) { return -1; } @@ -94,7 +94,7 @@ static inline int8_t rx_bit() { last_frame_end = GetCountSspClk(); // check for code violation (bit to short) - if(last_frame_end - bit_start < RWD_TIME_PAUSE) { + if (last_frame_end - bit_start < RWD_TIME_PAUSE) { return -1; } @@ -122,7 +122,7 @@ static inline int8_t rx_bit() { static inline void tx_bit(bool bit) { LED_C_ON(); - if(bit) { + if (bit) { // modulate subcarrier HIGH(GPIO_SSC_DOUT); } else { @@ -132,7 +132,7 @@ static inline void tx_bit(bool bit) { // wait for tx timeslot to end last_frame_end += TAG_BIT_PERIOD; - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; LED_C_OFF(); } @@ -150,13 +150,13 @@ static void tx_frame(uint32_t frame, uint8_t len) { // wait for next tx timeslot last_frame_end += TAG_FRAME_WAIT; legic_prng_forward(TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1); - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; // transmit frame, MSB first - for(uint8_t i = 0; i < len; ++i) { + for (uint8_t i = 0; i < len; ++i) { bool bit = (frame >> i) & 0x01; tx_bit(bit ^ legic_prng_get_bit()); legic_prng_forward(1); @@ -174,7 +174,7 @@ static void tx_ack() { // wait for ack timeslot last_frame_end += TAG_ACK_WAIT; legic_prng_forward(TAG_ACK_WAIT/TAG_BIT_PERIOD - 1); - while(GetCountSspClk() < last_frame_end) { }; + while (GetCountSspClk() < last_frame_end) { }; // backup ts for trace log uint32_t last_frame_start = last_frame_end; @@ -206,19 +206,19 @@ static int32_t rx_frame(uint8_t *len) { last_frame_end -= 2; // wait for first pause (start of frame) - for(uint8_t i = 0; true; ++i) { + for (uint8_t i = 0; true; ++i) { // increment prng every TAG_BIT_PERIOD last_frame_end += TAG_BIT_PERIOD; legic_prng_forward(1); // if start of frame was received exit delay loop - if(wait_for(RWD_PAUSE, last_frame_end)) { + if (wait_for(RWD_PAUSE, last_frame_end)) { last_frame_end = GetCountSspClk(); break; } // check for code violation - if(i > RWD_CMD_TIMEOUT) { + if (i > RWD_CMD_TIMEOUT) { return -1; } } @@ -227,19 +227,19 @@ static int32_t rx_frame(uint8_t *len) { uint32_t last_frame_start = last_frame_end; // receive frame - for(*len = 0; true; ++(*len)) { + for (*len = 0; true; ++(*len)) { // receive next bit LED_B_ON(); int8_t bit = rx_bit(); LED_B_OFF(); // check for code violation and to short / long frame - if((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) { + if ((bit < 0) && ((*len < RWD_MIN_FRAME_LEN) || (*len > RWD_MAX_FRAME_LEN))) { return -1; } // check for code violation caused by end of frame - if(bit < 0) { + if (bit < 0) { break; } @@ -256,7 +256,6 @@ static int32_t rx_frame(uint8_t *len) { // log uint8_t cmdbytes[] = {*len, BYTEx(frame, 0), BYTEx(frame, 1), BYTEx(frame, 2)}; LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true); - return frame; } @@ -267,7 +266,7 @@ static int32_t rx_frame(uint8_t *len) { static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) { p_card->tagtype = cardtype; - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: p_card->cmdsize = 6; p_card->addrsize = 5; @@ -338,7 +337,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) { // wait for iv int32_t iv = rx_frame(&len); - if((len != 7) || (iv < 0)) { + if ((len != 7) || (iv < 0)) { return -1; } @@ -346,7 +345,7 @@ static int32_t setup_phase(legic_card_select_t *p_card) { legic_prng_init(iv); // reply with card type - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: tx_frame(0x0D, 6); break; @@ -360,12 +359,12 @@ static int32_t setup_phase(legic_card_select_t *p_card) { // wait for ack int32_t ack = rx_frame(&len); - if((len != 6) || (ack < 0)) { + if ((len != 6) || (ack < 0)) { return -1; } // validate data - switch(p_card->tagtype) { + switch (p_card->tagtype) { case 0: if(ack != 0x19) return -1; break; @@ -399,12 +398,12 @@ static int32_t connected_phase(legic_card_select_t *p_card) { // wait for command int32_t cmd = rx_frame(&len); - if(cmd < 0) { + if (cmd < 0) { return -1; } // check if command is LEGIC_READ - if(len == p_card->cmdsize) { + if (len == p_card->cmdsize) { // prepare data uint8_t byte = legic_mem[cmd >> 1]; uint8_t crc = calc_crc4(cmd, p_card->cmdsize, byte); @@ -416,7 +415,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) { } // check if command is LEGIC_WRITE - if(len == p_card->cmdsize + 8 + 4) { + if (len == p_card->cmdsize + 8 + 4) { // decode data uint16_t mask = (1 << p_card->addrsize) - 1; uint16_t addr = (cmd >> 1) & mask; @@ -425,7 +424,7 @@ static int32_t connected_phase(legic_card_select_t *p_card) { // check received against calculated crc uint8_t calc_crc = calc_crc4(addr << 1, p_card->cmdsize, byte); - if(calc_crc != crc) { + if (calc_crc != crc) { Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc); return -1; } @@ -453,7 +452,7 @@ void LegicRfSimulate(uint8_t cardtype) { init_tag(); // verify command line input - if(init_card(cardtype, &card) != 0) { + if (init_card(cardtype, &card) != 0) { DbpString("Unknown tagtype."); goto OUT; } @@ -464,17 +463,17 @@ void LegicRfSimulate(uint8_t cardtype) { WDT_HIT(); // wait for carrier, restart after timeout - if(!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) { + if (!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) { continue; } // wait for connection, restart on error - if(setup_phase(&card)) { + if (setup_phase(&card)) { continue; } // conection is established, process commands until one fails - while(!connected_phase(&card)) { + while (!connected_phase(&card)) { WDT_HIT(); } } From f760ac99e3ed3d0ed9b257a4ae3418ca357bee8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 26 Jan 2019 10:40:37 +0100 Subject: [PATCH 126/320] chg: 'script run ndef_dump' - local functions --- client/scripts/ndef_dump.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index 3b27cac37..a0eda5b7f 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -24,13 +24,13 @@ local example = "script run xxx" local author = "Martin Holst Swende & Asper" --- -- PrintAndLog -function prlog(...) +local function prlog(...) -- TODO; replace this with a call to the proper PrintAndLog print(...) end --- -- This is only meant to be used when errors occur -function oops(err) +local function oops(err) prlog("ERROR: ",err) return nil,err end @@ -70,13 +70,13 @@ local utils = { --- -- Usage help -function help() +local function help() prlog(desc) prlog("Example usage") prlog(example) end -function debug(...) +local function debug(...) if DEBUG then prlog("debug:", ...) end @@ -158,7 +158,7 @@ end --- This function is a lua-implementation of -- cmdhf14a.c:waitCmd(uint8_t iSelect) -function waitCmd(iSelect) +local function waitCmd(iSelect) local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) if response then local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) From f0b70d6a4bafa265db137f2e2bb477f40041178b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 26 Jan 2019 11:09:17 +0100 Subject: [PATCH 127/320] CHG: added manufacturers --- client/lualibs/taglib.lua | 185 +++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 72 deletions(-) diff --git a/client/lualibs/taglib.lua b/client/lualibs/taglib.lua index f421ab22f..97194714c 100644 --- a/client/lualibs/taglib.lua +++ b/client/lualibs/taglib.lua @@ -1,72 +1,115 @@ -local manufacturer = {} -manufacturer[0x01]='Motorola [UK]' -manufacturer[0x02]='STMicroelectronics SA [France]' -manufacturer[0x03]='Hitachi, Ltd [Japan]' -manufacturer[0x04]='NXP Semiconductors [Germany]' -manufacturer[0x05]='Infineon Technologies AG [Germany]' -manufacturer[0x06]='Cylink [USA]' -manufacturer[0x07]='Texas Instrument [France]' -manufacturer[0x08]='Fujitsu Limited [Japan]' -manufacturer[0x09]='Matsushita Electronics Corporation, Semiconductor Company [Japan]' -manufacturer[0x0A]='NEC [Japan]' -manufacturer[0x0B]='Oki Electric Industry Co. Ltd [Japan]' -manufacturer[0x0C]='Toshiba Corp. [Japan]' -manufacturer[0x0D]='Mitsubishi Electric Corp. [Japan]' -manufacturer[0x0E]='Samsung Electronics Co. Ltd [Korea]' -manufacturer[0x0F]='Hynix [Korea]' -manufacturer[0x10]='LG-Semiconductors Co. Ltd [Korea]' -manufacturer[0x11]='Emosyn-EM Microelectronics [USA]' -manufacturer[0x12]='INSIDE Technology [France]' -manufacturer[0x13]='ORGA Kartensysteme GmbH [Germany]' -manufacturer[0x14]='SHARP Corporation [Japan]' -manufacturer[0x15]='ATMEL [France]' -manufacturer[0x16]='EM Microelectronic-Marin SA [Switzerland]' -manufacturer[0x17]='KSW Microtec GmbH [Germany]' -manufacturer[0x18]='ZMD AG [Germany]' -manufacturer[0x19]='XICOR, Inc. [USA]' -manufacturer[0x1A]='Sony Corporation [Japan]' -manufacturer[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd [Malaysia]' -manufacturer[0x1C]='Emosyn [USA]' -manufacturer[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. [China]' -manufacturer[0x1E]='Magellan Technology Pty Limited [Australia]' -manufacturer[0x1F]='Melexis NV BO [Switzerland]' -manufacturer[0x20]='Renesas Technology Corp. [Japan]' -manufacturer[0x21]='TAGSYS [France]' -manufacturer[0x22]='Transcore [USA]' -manufacturer[0x23]='Shanghai belling corp., ltd. [China]' -manufacturer[0x24]='Masktech Germany Gmbh [Germany]' -manufacturer[0x25]='Innovision Research and Technology Plc [UK]' -manufacturer[0x26]='Hitachi ULSI Systems Co., Ltd. [Japan]' -manufacturer[0x27]='Cypak AB [Sweden]' -manufacturer[0x28]='Ricoh [Japan]' -manufacturer[0x29]='ASK [France]' -manufacturer[0x2A]='Unicore Microsystems, LLC [RussianFederation]' -manufacturer[0x2B]='Dallas Semiconductor/Maxim [USA]' -manufacturer[0x2C]='Impinj, Inc. [USA]' -manufacturer[0x2D]='RightPlug Alliance [USA]' -manufacturer[0x2E]='Broadcom Corporation [USA]' -manufacturer[0x2F]='MStar Semiconductor, Inc Taiwan, [ROC]' -manufacturer[0x30]='BeeDar Technology Inc. [USA]' -manufacturer[0x31]='RFIDsec [Denmark]' -manufacturer[0x32]='Schweizer Electronic AG [Germany]' -manufacturer[0x33]='AMIC Technology Corp [Taiwan]' -manufacturer[0x34]='Mikron JSC [Russia]' -manufacturer[0x35]='Fraunhofer Institute for Photonic Microsystems [Germany]' -manufacturer[0x36]='IDS Microchip AG [Switzerland]' -manufacturer[0x37]='Kovio [USA]' -manufacturer[0x38]='HMT Microelectronic Ltd [Switzerland]' -manufacturer[0x39]='Silicon Craft Technology [Thailand]' -manufacturer[0x3A]='Advanced Film Device Inc. [Japan]' -manufacturer[0x3B]='Nitecrest Ltd [UK]' -manufacturer[0x3C]='Verayo Inc. [USA]' -manufacturer[0x3D]='HID Global [USA]' -manufacturer[0x3E]='Productivity Engineering Gmbh [Germany]' -manufacturer[0x3F]='Austriamicrosystems AG (reserved) [Austria]' -manufacturer[0x40]='Gemalto SA [France]' -manufacturer[0x41]='Renesas Electronics Corporation [Japan]' -manufacturer[0x42]='3Alogics Inc [Korea]' -manufacturer[0x43]='Top TroniQ Asia Limited Hong [Kong]' -manufacturer[0x44]='Gentag Inc (USA) [USA]' +local m = {} +m[0x01]='Motorola UK' +m[0x02]='ST Microelectronics SA France' +m[0x03]='Hitachi, Ltd Japan' +m[0x04]='NXP Semiconductors Germany' +m[0x05]='Infineon Technologies AG Germany' +m[0x06]='Cylink USA' +m[0x07]='Texas Instrument France' +m[0x08]='Fujitsu Limited Japan' +m[0x09]='Matsushita Electronics Corporation, Semiconductor Company Japan' +m[0x0A]='NEC Japan' +m[0x0B]='Oki Electric Industry Co. Ltd Japan' +m[0x0C]='Toshiba Corp. Japan' +m[0x0D]='Mitsubishi Electric Corp. Japan' +m[0x0E]='Samsung Electronics Co. Ltd Korea' +m[0x0F]='Hynix / Hyundai, Korea' +m[0x10]='LG-Semiconductors Co. Ltd Korea' +m[0x11]='Emosyn-EM Microelectronics USA' +m[0x12]='INSIDE Technology France' +m[0x13]='ORGA Kartensysteme GmbH Germany' +m[0x14]='SHARP Corporation Japan' +m[0x15]='ATMEL France' +m[0x16]='EM Microelectronic-Marin SA Switzerland' +m[0x17]='KSW Microtec GmbH Germany' +m[0x18]='ZMD AG Germany' +m[0x19]='XICOR, Inc. USA' +m[0x1A]='Sony Corporation Japan' +m[0x1B]='Malaysia Microelectronic Solutions Sdn. Bhd Malaysia' +m[0x1C]='Emosyn USA' +m[0x1D]='Shanghai Fudan Microelectronics Co. Ltd. P.R. China' +m[0x1E]='Magellan Technology Pty Limited Australia' +m[0x1F]='Melexis NV BO Switzerland' +m[0x20]='Renesas Technology Corp. Japan' +m[0x21]='TAGSYS France' +m[0x22]='Transcore USA' +m[0x23]='Shanghai belling corp., ltd. China' +m[0x24]='Masktech Germany Gmbh Germany' +m[0x25]='Innovision Research and Technology Plc UK' +m[0x26]='Hitachi ULSI Systems Co., Ltd. Japan' +m[0x27]='Cypak AB Sweden' +m[0x28]='Ricoh Japan' +m[0x29]='ASK France' +m[0x2A]='Unicore Microsystems, LLC RussianFederation' +m[0x2B]='Dallas Semiconductor/Maxim USA' +m[0x2C]='Impinj, Inc. USA' +m[0x2D]='RightPlug Alliance USA' +m[0x2E]='Broadcom Corporation USA' +m[0x2F]='MStar Semiconductor, Inc Taiwan, ROC' +m[0x30]='BeeDar Technology Inc. USA' +m[0x31]='RFIDsec Denmark' +m[0x32]='Schweizer Electronic AG Germany' +m[0x33]='AMIC Technology Corp Taiwan' +m[0x34]='Mikron JSC Russia' +m[0x35]='Fraunhofer Institute for Photonic Microsystems Germany' +m[0x36]='IDS Microchip AG Switzerland' +m[0x37]='Kovio USA' +m[0x38]='HMT Microelectronic Ltd Switzerland' +m[0x39]='Silicon Craft Technology Thailand' +m[0x3A]='Advanced Film Device Inc. Japan' +m[0x3B]='Nitecrest Ltd UK' +m[0x3C]='Verayo Inc. USA' +m[0x3D]='HID Global USA' +m[0x3E]='Productivity Engineering Gmbh Germany' +m[0x3F]='Austriamicrosystems AG (reserved) Austria' +m[0x40]='Gemalto SA France' +m[0x41]='Renesas Electronics Corporation Japan' +m[0x42]='3Alogics Inc Korea' +m[0x43]='Top TroniQ Asia Limited Hong Kong' +m[0x44]='Gentag Inc USA' +m[0x45]='Invengo Information Technology Co.Ltd China' +m[0x46]='Guangzhou Sysur Microelectronics, Inc China' +m[0x47]='CEITEC S.A. Brazil' +m[0x48]='Shanghai Quanray Electronics Co. Ltd. China' +m[0x49]='MediaTek Inc Taiwan' +m[0x4A]='Angstrem PJSC Russia' +m[0x4B]='Celisic Semiconductor (Hong Kong) Limited China' +m[0x4C]='LEGIC Identsystems AG Switzerland' +m[0x4D]='Balluff GmbH Germany' +m[0x4E]='Oberthur Technologies France' +m[0x4F]='Silterra Malaysia Sdn. Bhd. Malaysia' +m[0x50]='DELTA Danish Electronics, Light & Acoustics Denmark' +m[0x51]='Giesecke & Devrient GmbH Germany' +m[0x52]='Shenzhen China Vision Microelectronics Co., Ltd. China' +m[0x53]='Shanghai Feiju Microelectronics Co. Ltd. China' +m[0x54]='Intel Corporation USA' +m[0x55]='Microsensys GmbH Germany' +m[0x56]='Sonix Technology Co., Ltd. Taiwan' +m[0x57]='Qualcomm Technologies Inc USA' +m[0x58]='Realtek Semiconductor Corp Taiwan' +m[0x59]='Freevision Technologies Co. Ltd China' +m[0x5A]='Giantec Semiconductor Inc. China' +m[0x5B]='JSC Angstrem-T Russia' +m[0x5C]='STARCHIP France' +m[0x5D]='SPIRTECH France' +m[0x5E]='GANTNER Electronic GmbH Austria' +m[0x5F]='Nordic Semiconductor Norway' +m[0x60]='Verisiti Inc USA' +m[0x61]='Wearlinks Technology Inc. China' +m[0x62]='Userstar Information Systems Co., Ltd Taiwan' +m[0x63]='Pragmatic Printing Ltd. UK' +m[0x64]='Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil' +m[0x65]='Tendyron Corporation China' +m[0x66]='MUTO Smart Co., Ltd. Korea' +m[0x67]='ON Semiconductor USA' +m[0x68]='TUBITAK BILGEM Turkey' +m[0x69]='Huada Semiconductor Co., Ltd China' +m[0x6A]='SEVENEY France' +m[0x6B]='ISSM France' +m[0x6C]='Wisesec Ltd Israel' +m[0x7C]='DB HiTek Co Ltd Korea' +m[0x7D]='SATO Vicinity Australia' +m[0x7E]='Holtek Taiwan' return { lookupManufacturer = function (value) @@ -76,8 +119,6 @@ return { value = v end - return manufacturer[value] or "no tag-info available" + return m[value] or "no tag-info available" end, - - } \ No newline at end of file From 8059f533af019955d9ffc9c2d700cc5ba2f6818b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 26 Jan 2019 11:09:47 +0100 Subject: [PATCH 128/320] syntax --- client/loclass/cipherutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/loclass/cipherutils.h b/client/loclass/cipherutils.h index 568671791..21d11aac0 100644 --- a/client/loclass/cipherutils.h +++ b/client/loclass/cipherutils.h @@ -52,7 +52,7 @@ typedef struct { uint8_t * buffer; uint8_t numbits; uint8_t position; -}BitstreamOut; +} BitstreamOut; bool headBit( BitstreamIn *stream); bool tailBit( BitstreamIn *stream); From fa3dfa59b97eee7aa1ad2107934162417690bbce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 26 Jan 2019 19:10:29 +0100 Subject: [PATCH 129/320] chg: 'script run legic' - minor adjustments. --- client/scripts/legic.lua | 295 ++++++++++++++++++++------------------- 1 file changed, 155 insertions(+), 140 deletions(-) diff --git a/client/scripts/legic.lua b/client/scripts/legic.lua index 546e5cc1a..264d4dfef 100644 --- a/client/scripts/legic.lua +++ b/client/scripts/legic.lua @@ -513,8 +513,8 @@ function readFromPM3() return tag end -function padString(str) - if (str:len() == 1) then +local function padString(str) + if (#str == 1) then return '0'..str end @@ -524,73 +524,84 @@ end --- -- write virtual Tag to real Tag function writeToTag(tag) - local bytes - local filename='MylegicClone.hex' - local taglen=22 + local bytes + local filename = 'MylegicClone.hex' + local taglen = 22 if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then - return - end - -- get used bytes / tag-len - if(istable(tag.SEG)) then - if (istable(tag.Bck)) then - for i=0, #tag.SEG do - taglen=taglen+tag.SEG[i].len+5 - end - end - local uid_old=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 - -- read new tag into memory so we can xor the new data with the new MCC - outTAG=readFromPM3() - outbytes=tagToBytes(outTAG) - -- copy 'inputbuffer' to 'outputbuffer' - tag.MCD = outbytes[1] - tag.MSN0 = outbytes[2] - tag.MSN1 = outbytes[3] - tag.MSN2 = outbytes[4] - tag.MCC = outbytes[5] - -- recheck all segments-crc/kghcrc (only on a credential) - if(istable(tag.Bck)) then - checkAllSegCrc(tag) - checkAllKghCrc(tag) - local uid_new=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 - for i=0, #tag.SEG do - if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then - io.write(accyan.."\nfixing known checksums"..acoff.." ... ") - if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then - io.write(acgreen.." done\n"..acoff) - else oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") end - end - end - end - bytes=tagToBytes(tag) - -- master-token-crc - if (tag.Type ~= "SAM") then bytes[22] = calcMtCrc(bytes) end - if (bytes) then - print("write temp-file '"..filename.."'") - print(accyan) - writeFile(bytes, filename..".bin") - print(acoff) - end - end + return + end + + -- get used bytes / tag-len + if (istable(tag.SEG)) then + if (istable(tag.Bck)) then + for i=0, #tag.SEG do + taglen = taglen + tag.SEG[i] . len + 5 + end + end + local uid_old = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 + + -- read new tag into memory so we can xor the new data with the new MCC + outTAG = readFromPM3() + outbytes = tagToBytes(outTAG) + -- copy 'inputbuffer' to 'outputbuffer' + tag.MCD = outbytes[1] + tag.MSN0 = outbytes[2] + tag.MSN1 = outbytes[3] + tag.MSN2 = outbytes[4] + tag.MCC = outbytes[5] + -- recheck all segments-crc/kghcrc (only on a credential) + if (istable(tag.Bck)) then + checkAllSegCrc(tag) + checkAllKghCrc(tag) + local uid_new = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2 + for i=0, #tag.SEG do + if (check43rdPartyCash1(uid_old, tag.SEG[i].data)) then + io.write(accyan.."\nfixing known checksums"..acoff.." ... ") + if (fix3rdPartyCash1(uid_new, tag.SEG[i].data)) then + io.write(acgreen.." done\n"..acoff) + else + oops("\nsomething went wrong at the repair of the 3rd-party-cash-segment") + end + end + end + end + bytes = tagToBytes(tag) + -- master-token-crc + if (tag.Type ~= "SAM") then + bytes[22] = calcMtCrc(bytes) + end + if (bytes) then + print("write temp-file '"..filename.."'") + print(accyan) + writeFile(bytes, filename..".bin") + print(acoff) + end + end - -- write data to file + -- write data to file if (taglen > 0) then WriteBytes = utils.input(acyellow.."enter number of bytes to write?"..acoff, taglen) -- load file into pm3-buffer - if (type(filename) ~= "string") then filename=input(acyellow.."filename to load to pm3-buffer?"..acoff,"legic.temp") end + if (type(filename) ~= "string") then + filename = input(acyellow.."filename to load to pm3-buffer?"..acoff, "legic.temp") + end + cmd = 'hf legic eload 2 '..filename core.console(cmd) -- write pm3-buffer to Tag for i=0, WriteBytes do if (i > 6) then - cmd = 'hf legic write o '..string.format("%x", i)..' d '..padString(bytes[i]) - print(acgreen..cmd..acoff) + cmd = ("hf legic write o %x d %s "):format(i, padString(bytes[i])) + print(acgreen..cmd..acoff) core.console(cmd) + core.clearCommandBuffer() elseif (i == 6) then - -- write DCF in reverse order (requires 'mosci-patch') - cmd = 'hf legic write o 05 d '..padString(bytes[i-1])..padString(bytes[i]) - print(acgreen..cmd..acoff) + -- write DCF in reverse order (requires 'mosci-patch') + cmd = ('hf legic write o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i])) + print(acgreen..cmd..acoff) core.console(cmd) - elseif (i == 5) then + core.clearCommandBuffer() + elseif (i == 5) then print(acgreen.."skip byte 0x05 - will be written next step"..acoff) else print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff) @@ -603,26 +614,28 @@ end --- File I/O --- --- -- read file into virtual-tag -function readFile(filename) - print(accyan) - local bytes = {} - local tag = {} - if file_check(filename) == false then return oops("input file: "..filename.." not found") end +local function readFile(filename) + print(accyan) + local bytes = {} + local tag = {} + if file_check(filename) == false then + return oops("input file: "..filename.." not found") + end - bytes = getInputBytes(filename) + bytes = getInputBytes(filename) - if bytes == false then return oops('couldnt get input bytes') end + if bytes == false then return oops('couldnt get input bytes') end - -- make plain bytes - bytes = xorBytes(bytes,bytes[5]) - print("create virtual tag from ".. #bytes .. " bytes") - -- create Tag for plain bytes - tag=createTagTable() - -- load plain bytes to tag-table - print(acoff) - tag=bytesToTag(bytes, tag) + -- make plain bytes + bytes = xorBytes(bytes,bytes[5]) + print("create virtual tag from ".. #bytes .. " bytes") + -- create Tag for plain bytes + tag = createTagTable() + -- load plain bytes to tag-table + print(acoff) + tag = bytesToTag(bytes, tag) - return tag + return tag end --- @@ -631,14 +644,16 @@ function writeFile(bytes, filename) if (filename ~= 'MylegicClone.hex') then if (file_check(filename)) then local answer = confirm("\nthe output-file "..filename.." already exists!\nthis will delete the previous content!\ncontinue?") - if (answer==false) then return print("user abort") end + if not answer then return print("user abort") end end end local line - local bcnt=0 - local fho,err = io.open(filename, "w") - if err then oops("OOps ... failed to open output-file ".. filename) end - bytes=xorBytes(bytes, bytes[5]) + local bcnt = 0 + local fho, err = io.open(filename, "w") + if err then + return oops("OOps ... failed to open output-file ".. filename) + end + bytes = xorBytes(bytes, bytes[5]) for i = 1, #bytes do if (bcnt == 0) then line = bytes[i] @@ -662,96 +677,96 @@ end --- Map related --- --- -- make tagMap -function makeTagMap() - local tagMap={} - if (#tagMap == 0) then - tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap") - tagMap['mappings']={} - tagMap['crc8']={} - -- insert fixed Tag-CRC - table.insert(tagMap.crc8, {name='TAG-CRC', pos=5, seq={1, 4}}) - tagMap['crc16']={} - end - print(accyan.."new tagMap created"..acoff) - return tagMap +local function makeTagMap() + local tagMap = {} + if (#tagMap == 0) then + tagMap['name'] = input(accyan.."enter Name for this Map: "..acoff , "newTagMap") + tagMap['mappings'] = {} + tagMap['crc8'] = {} + -- insert fixed Tag-CRC + table.insert(tagMap.crc8, {name = 'TAG-CRC', pos = 5, seq = {1, 4}}) + tagMap['crc16'] = {} + end + print(accyan.."new tagMap created"..acoff) + return tagMap end --- -- save mapping to file -function saveTagMap(map, filename) - if (string.len(filename)>0) then - if (file_check(filename)) then - local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?") - if (answer==false) then return print("user abort") end - end - end +local function saveTagMap(map, filename) + if (string.len(filename)>0) then + if (file_check(filename)) then + local answer = confirm("\nthe output-file "..filename.." alredy exists!\nthis will delete the previous content!\ncontinue?") + if not answer then return print("user abort") end + end + end - local line + local line local fho,err = io.open(filename, "w") if err then oops("OOps ... faild to open output-file ".. filename) end - -- write line to new file - for k, v in pairs(map) do - if (istable(v)) then - for k2, v2 in pairs(v) do - if (k=='mappings') then - fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n") - elseif (k=="crc8") then - local tmp="" - tmp=k..","..k2..","..v2['name']..","..v2['pos'].."," - tmp=tmp..tbl2seqstr(v2['seq']) - fho:write(tmp.."\n") - end - end - else - fho:write(k..","..v.."\n") - end - end + -- write line to new file + for k, v in pairs(map) do + if (istable(v)) then + for k2, v2 in pairs(v) do + if (k == 'mappings') then + fho:write(k..","..k2..","..v2['name']..","..v2['start']..","..v2['end']..","..((v2['highlight']) and "1" or "0").."\n") + elseif (k == "crc8") then + local tmp = "" + tmp = k..","..k2..","..v2['name']..","..v2['pos'].."," + tmp=tmp..tbl2seqstr(v2['seq']) + fho:write(tmp.."\n") + end + end + else + fho:write(k..","..v.."\n") + end + end fho:close() return true end --- -- toggle higligh -function toggleHighlight(tbl) +local function toggleHighlight(tbl) if (tbl['highlight']) then tbl['highlight'] = false else tbl['highlight'] = true end - return tbl + return tbl end --- -- return table od seqence-string -function seqstr2tbl(seqstr) - local s=split(seqstr) - local res={} - if (#s>=1) then - for sk, sv in pairs(s) do - s2=split(sv, '-') - if(#s2==2) then - table.insert(res, s2[1]) - table.insert(res, s2[2]) - end - end - end - return res +local function seqstr2tbl(seqstr) + local s = split(seqstr) + local res = {} + if (#s >= 1) then + for sk, sv in pairs(s) do + s2 = split(sv, '-') + if(#s2 == 2) then + table.insert(res, s2[1]) + table.insert(res, s2[2]) + end + end + end + return res end --- -- return sequence-string from table -function tbl2seqstr(seqtbl) - local res="" - if (istable(seqtbl)) then - for sk, sv in pairs(seqtbl) do - res=res..sv..((sk%2==0) and "," or "-") - end - if (string.sub(res, string.len(res))==",") then - res=string.sub(res, 1, string.len(res)-1) - end - end - return res +local function tbl2seqstr(seqtbl) + local res = "" + if (istable(seqtbl)) then + for sk, sv in pairs(seqtbl) do + res = res..sv..((sk%2==0) and "," or "-") + end + if (string.sub(res, string.len(res))== ",") then + res = string.sub(res, 1, string.len(res)-1) + end + end + return res end --- From 0beb730e043b632972318bc3d1e0a5e8e9934d37 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 27 Jan 2019 20:42:50 +0100 Subject: [PATCH 130/320] Update README.md --- README.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f21a2efdc..effdc0f6e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,33 @@ Proxmark3 RDV40 dedicated repo, based on iceman fork ## Notice This repo is based on iceman fork for proxmark3. It is dedicated to bring the most out of the new features for proxmark3 RDV40 device. +# Donations +Nothing says thank you as much as a donation, https://www.patreon.com/iceman1001 + +## ToC + +- Coverity Scan Config & Run +- Whats changed? +- Why didn't you based it on offical PM3 Master? +- Why don't you add this or that functionality? +- PM3 GUI +- Development +- KALI and ARCHLINUX users +- Setup and build for UBUNTU +- Setup and build for ArchLinux +- Homebrew (Mac OS X) +- Upgrading HomeBrew tap formula +- Building on Windows +- Gator96100 distro +- Build and run +- Validating proxmark client functionality +- Run the following commands +- Quit client +- First things on your RDV40 +- Verify sim module firmware version + +- The end + ## Coverity Scan Config & Run Download the Coverity Scan Self-buld and install it. You will need to configure ARM-NON-EABI- Compiler for it to use: @@ -37,14 +64,16 @@ The separation from offical pm3 repo gives us very much freedom to create a firm Give us a hint, and we'll see if we can't merge in the stuff you have. ## PM3 GUI -The official PM3-GUI from Gaucho will not work. -The new universial GUI will work. +The official PM3-GUI from Gaucho will not work. +The new universial GUI will work. [Proxmark3 Univerisal GUI](https://github.com/burma69/PM3UniversalGUI) ## Development This fork now compiles just fine on - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804 - Mac OS X / Homebrew + - ParrotOS + - WSL (Windows subsystem linux) on Windows 10 - Docker container ## KALI and ARCHLINUX users @@ -224,7 +253,7 @@ If all went well you should get some information about the firmware and memory u > > pm3 --> -### run the following commands +### Run the following commands pm3 --> hw status pm3 --> hw version pm3 --> hw tune From 34be8b4d37e5a9cb222370f77efbb113f00d18a6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 29 Jan 2019 15:23:07 +0100 Subject: [PATCH 131/320] CHG: wrong iso7816 (@piwi) --- client/cmdhflist.c | 2 +- client/cmdsmartcard.c | 4 ++-- common/protocols.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 7791c5e53..b2e0eeecc 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -357,7 +357,7 @@ void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ case ISO7816_EXTERNAL_AUTHENTICATION :snprintf(exp, size, "EXTERNAL AUTH");break; case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break; case ISO7816_MANAGE_CHANNEL :snprintf(exp, size, "MANAGE CHANNEL");break; - case ISO7816_GETSTATUS :snprintf(exp, size, "GET RESPONSE");break; + case ISO7816_GET_RESPONSE :snprintf(exp, size, "GET RESPONSE");break; default :snprintf(exp,size,"?"); break; } } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index fdc825d38..45957d407 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -356,7 +356,7 @@ static int smart_responseEx(uint8_t *data, bool silent) { if (needGetData) { int len = data[datalen - 1]; if (!silent) PrintAndLogEx(INFO, "Requesting 0x%02X bytes response", len); - uint8_t getstatus[] = {0x00, ISO7816_GETSTATUS, 0x00, 0x00, len}; + uint8_t getstatus[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len}; UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}}; memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) ); clearCommandBuffer(); @@ -372,7 +372,7 @@ static int smart_responseEx(uint8_t *data, bool silent) { if (datalen != len + 2) { // data with ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK - if (data[0] != ISO7816_GETSTATUS) { + if (data[0] != ISO7816_GET_RESPONSE) { if (!silent) { PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, data[0]); } diff --git a/common/protocols.h b/common/protocols.h index 9696c73e0..3c2e79a8d 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -302,10 +302,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_VERIFY 0x20 #define ISO7816_INTERNAL_AUTHENTICATION 0x88 #define ISO7816_EXTERNAL_AUTHENTICATION 0x82 -#define ISO7816_GET_CHALLENGE 0xB4 +#define ISO7816_GET_CHALLENGE 0x84 #define ISO7816_MANAGE_CHANNEL 0x70 -#define ISO7816_GETSTATUS 0xC0 +#define ISO7816_GET_RESPONSE 0xC0 // ISO7816-4 For response APDU's #define ISO7816_OK 0x9000 // 6x xx = ERROR From c419f7bf37fcaf637136edb830dea0e33fcb5010 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 29 Jan 2019 15:42:31 +0100 Subject: [PATCH 132/320] CHG: dropfield when CL is used. --- client/emv/cmdemv.c | 38 +++++++++++++++++--------------------- client/emv/emvcore.c | 4 ++-- client/util.h | 8 ++++++++ 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 453d08a20..f033ad7ba 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -623,7 +623,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) { return 0; } -#define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;} +#define dreturn(n) {free(pdol_data_tlv); tlvdb_free(tlvSelect); tlvdb_free(tlvRoot); DropFieldEx( channel ); return n;} void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, enum TransactionType TrType, bool GenACGPO) { @@ -1212,7 +1212,7 @@ int CmdEMVExec(const char *cmd) { } - DropField(); + DropFieldEx( channel ); // Destroy TLV's free(pdol_data_tlv); @@ -1314,7 +1314,7 @@ int CmdEMVScan(const char *cmd) { } // drop field at start - DropField(); + DropFieldEx( channel ); // iso 14443 select PrintAndLogEx(NORMAL, "--> GET UID, ATS."); @@ -1367,7 +1367,7 @@ int CmdEMVScan(const char *cmd) { if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) { PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); tlvdb_free(tlvSelect); - DropField(); + DropFieldEx( channel ); return 3; } @@ -1383,7 +1383,7 @@ int CmdEMVScan(const char *cmd) { if (!AIDlen) { PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); - DropField(); + DropFieldEx( channel ); return 4; } @@ -1402,7 +1402,7 @@ int CmdEMVScan(const char *cmd) { if (res) { PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 5; } @@ -1430,7 +1430,7 @@ int CmdEMVScan(const char *cmd) { if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } @@ -1439,7 +1439,7 @@ int CmdEMVScan(const char *cmd) { if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -1453,7 +1453,7 @@ int CmdEMVScan(const char *cmd) { if (res) { PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 7; } ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV); @@ -1545,8 +1545,7 @@ int CmdEMVScan(const char *cmd) { // free tlv object tlvdb_free(tlvRoot); - // DropField - DropField(); + DropFieldEx( channel ); res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { @@ -1630,7 +1629,7 @@ int CmdEMVRoca(const char *cmd) { if (EMVSearch(channel, false, true, false, tlvSelect)) { PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); tlvdb_free(tlvSelect); - DropField(); + DropFieldEx( channel ); return 3; } @@ -1646,7 +1645,7 @@ int CmdEMVRoca(const char *cmd) { if (!AIDlen) { PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); - DropField(); + DropFieldEx( channel ); return 4; } @@ -1661,7 +1660,7 @@ int CmdEMVRoca(const char *cmd) { if (res) { PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 5; } @@ -1673,7 +1672,7 @@ int CmdEMVRoca(const char *cmd) { if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } @@ -1682,7 +1681,7 @@ int CmdEMVRoca(const char *cmd) { if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 6; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -1696,7 +1695,7 @@ int CmdEMVRoca(const char *cmd) { if (res) { PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); tlvdb_free(tlvRoot); - DropField(); + DropFieldEx( channel ); return 7; } ProcessGPOResponseFormat1(tlvRoot, buf, len, false); @@ -1794,10 +1793,7 @@ out: // free tlv object tlvdb_free(tlvRoot); - if ( channel == ECC_CONTACTLESS) - DropField(); - - + DropFieldEx( channel ); return 0; } diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 77d288eaa..ae3b0574a 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -241,7 +241,7 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField int res = 0; if (ActivateField) { - DropField(); + DropFieldEx( channel ); msleep(50); } @@ -484,7 +484,7 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO } if(!LeaveFieldON) - DropField(); + DropFieldEx( channel ); return res; } diff --git a/client/util.h b/client/util.h index c9f13870d..e10f06497 100644 --- a/client/util.h +++ b/client/util.h @@ -178,6 +178,14 @@ } #endif +#ifndef DropFieldEx +#define DropFieldEx(x) { \ + if ( (x) == ECC_CONTACTLESS) { \ + DropField(); \ + } \ +} +#endif + extern uint8_t g_debugMode; extern int ukbhit(void); From 8991fa172dcb974adb538589dd6b663ca42dcdc4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 29 Jan 2019 15:47:44 +0100 Subject: [PATCH 133/320] FIX: wrong define --- armsrc/lfops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index d750fccbe..96abd9b99 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -80,7 +80,7 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) { printT55xxConfig(); -#if WITH_FLASH +#ifdef WITH_FLASH // shall persist to flashmem if (arg0 == 0) { return; @@ -119,7 +119,7 @@ t55xx_config* getT55xxConfig(void) { } void loadT55xxConfig(void) { -#if WITH_FLASH +#ifdef WITH_FLASH if (!FlashInit()) { return; } From 1b3d96ab2dfa32dcd43525b2bf4808414fc26dba Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 29 Jan 2019 19:30:15 +0200 Subject: [PATCH 134/320] add apdu chaining to arm side --- armsrc/iso14443a.c | 3 +++ include/mifare.h | 1 + 2 files changed, 4 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 257c39b1f..daeb6b749 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2226,6 +2226,9 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) { if (cmd_len) { // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) + if (param & ISO14A_SEND_CHAINING) { + real_cmd[0] |= 0x10; + } // put block number into the PCB real_cmd[0] |= iso14_pcb_blocknum; memcpy(real_cmd + 1, cmd, cmd_len); diff --git a/include/mifare.h b/include/mifare.h index cda7cfe9d..1373317e7 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -36,6 +36,7 @@ typedef enum ISO14A_COMMAND { ISO14A_NO_SELECT = (1 << 7), ISO14A_TOPAZMODE = (1 << 8), ISO14A_NO_RATS = (1 << 9) + ISO14A_SEND_CHAINING = (1 << 9) } iso14a_command_t; typedef struct { From cf21f046d82d0d85431cec779a668a1b642ca784 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 30 Jan 2019 18:15:47 +0200 Subject: [PATCH 135/320] arm side --- armsrc/epa.c | 2 +- armsrc/iso14443a.c | 6 +++--- armsrc/iso14443a.h | 2 +- include/mifare.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/armsrc/epa.c b/armsrc/epa.c index 68b2711da..e97fda7a0 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -108,7 +108,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) switch(iso_type) { case 'a': - return iso14_apdu(apdu, (uint16_t) length, response, NULL); + return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); break; case 'b': return iso14443b_apdu(apdu, length, response); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index daeb6b749..082d378ac 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2219,14 +2219,14 @@ b8 b7 b6 b5 b4 b3 b2 b1 b5,b6 = 00 - DESELECT 11 - WTX */ -int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) { +int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) { uint8_t parity[MAX_PARITY_SIZE] = {0x00}; uint8_t real_cmd[cmd_len + 4]; if (cmd_len) { // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) - if (param & ISO14A_SEND_CHAINING) { + if (send_chaining) { real_cmd[0] |= 0x10; } // put block number into the PCB @@ -2341,7 +2341,7 @@ void ReaderIso14443a(UsbCommand *c) { if ((param & ISO14A_APDU)) { uint8_t res; - arg0 = iso14_apdu(cmd, len, buf, &res); + arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf)); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 7f979e531..a23b5d7c2 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -114,7 +114,7 @@ extern void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32 extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par); extern void iso14443a_setup(uint8_t fpga_minor_mode); -extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res); +extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res); extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats); extern int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); extern void iso14a_set_trigger(bool enable); diff --git a/include/mifare.h b/include/mifare.h index 1373317e7..14c0e7e27 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -35,8 +35,8 @@ typedef enum ISO14A_COMMAND { ISO14A_SET_TIMEOUT = (1 << 6), ISO14A_NO_SELECT = (1 << 7), ISO14A_TOPAZMODE = (1 << 8), - ISO14A_NO_RATS = (1 << 9) - ISO14A_SEND_CHAINING = (1 << 9) + ISO14A_NO_RATS = (1 << 9), + ISO14A_SEND_CHAINING = (1 << 10) } iso14a_command_t; typedef struct { From 30a6ef19b904492dc3cccc4f1f877a75cd4661e9 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 30 Jan 2019 18:16:50 +0200 Subject: [PATCH 136/320] added FSC correct calculation in `hf 14a info` --- client/cmdhf14a.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 43832e2cf..4a6b7518d 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -147,6 +147,10 @@ char* getTagInfo(uint8_t uid) { return manufactureMapping[len-1].desc; } +// iso14a apdu input frame length +static uint16_t frameLength = 0; +uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256}; + int usage_hf_14a_sim(void) { // PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n"); PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n"); @@ -486,10 +490,7 @@ int CmdHF14AInfo(const char *Cmd) { (tb1 ? "" : " NOT"), (tc1 ? "" : " NOT"), fsci, - fsci < 5 ? (fsci - 2) * 8 : - fsci < 8 ? (fsci - 3) * 32 : - fsci == 8 ? 256 : - -1 + fsci < sizeof(atsFSC) ? atsFSC[fsci] : -1 ); } pos = 2; From 18db34ffb048af75c71c69d8408c661fe220fa51 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 20:18:50 +0100 Subject: [PATCH 137/320] chg: use calloc --- client/cmddata.c | 2 +- client/cmdhfepa.c | 2 +- client/cmdhficlass.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index a9f58b962..65fd0d829 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1786,7 +1786,7 @@ int Cmdbin2hex(const char *Cmd) { //Number of digits supplied as argument size_t length = en - bg + 1; size_t bytelen = (length+7) / 8; - uint8_t* arr = (uint8_t *) malloc(bytelen); + uint8_t* arr = (uint8_t *) calloc(bytelen, sizeof(uint8_t)); memset(arr, 0, bytelen); BitstreamOut bout = { arr, 0, 0 }; diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index b681810ed..dd110c9c0 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -43,7 +43,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd) PrintAndLogEx(FAILED, "Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]); } else { size_t nonce_length = resp.arg[1]; - char *nonce = (char *) malloc(2 * nonce_length + 1); + char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t)); for(int j = 0; j < nonce_length; j++) { sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]); } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f0bfa18a0..9427acf50 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -404,7 +404,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void* dump = malloc(datalen); + void* dump = calloc(datalen, sizeof(uint8_t)); if ( !dump ) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; @@ -456,7 +456,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void* dump = malloc(datalen); + void* dump = calloc(datalen, sizeof(uint8_t)); if ( !dump ) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; From ed7122e409907810f65cc0d458a536607fb04590 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 20:21:41 +0100 Subject: [PATCH 138/320] chg: use calloc --- client/cmdhfmf.c | 6 +++--- client/cmdhftopaz.c | 6 +++--- client/cmdsmartcard.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a02302b15..a26381930 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -415,7 +415,7 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) { char * GenerateFilename(const char *prefix, const char *suffix){ uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; int uidlen=0; - char * fptr = malloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1); + char * fptr = calloc (sizeof (char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid)*2 + 1, sizeof(uint8_t)); GetHFMF14AUID(uid, &uidlen); if (!uidlen) { @@ -2195,7 +2195,7 @@ int CmdHF14AMfSniff(const char *Cmd){ if (traceLen > bufsize || buf == NULL) { uint8_t *p; if (buf == NULL) // not yet allocated - p = malloc(traceLen); + p = calloc(traceLen, sizeof(uint8_t)); else // need more memory p = realloc(buf, traceLen); @@ -2912,7 +2912,7 @@ int CmdHF14AMfCSave(const char *Cmd) { if (errors || cmdp == 0) return usage_hf14_csave(); - dump = malloc(bytes); + dump = calloc(bytes, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return 1; diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index ea4699f1b..a6046cee0 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -194,7 +194,7 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(NORMAL, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); uint16_t memsize = (data[2] + 1) * 8; topaz_tag.size = memsize; - topaz_tag.dynamic_memory = malloc(memsize - TOPAZ_STATIC_MEMORY); + topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t)); PrintAndLogEx(NORMAL, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); PrintAndLogEx(NORMAL, " %02x: %s / %s", data[3], (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", @@ -278,12 +278,12 @@ static void topaz_print_control_TLVs(uint8_t *memory) { dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas; if (old == NULL) { - new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t)); + new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t, sizeof(uint8_t))); } else { while(old->next != NULL) { old = old->next; } - new = old->next = (dynamic_lock_area_t *)malloc(sizeof(dynamic_lock_area_t)); + new = old->next = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t), sizeof(uint8_t)); } new->next = NULL; if (area_start <= next_lockable_byte) { diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 45957d407..23b2b8b3c 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -1012,7 +1012,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { json_t *root = NULL; smart_loadjson("aidlist", "json", &root); - uint8_t* buf = malloc(USB_CMD_DATA_SIZE); + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); if ( !buf ) return 1; From e81b0fa355df3d227a39c717b577a27ad13e40ad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 20:43:30 +0100 Subject: [PATCH 139/320] chg: use calloc --- client/cmdhftopaz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index a6046cee0..2f80b054c 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -278,7 +278,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *new = topaz_tag.dynamic_lock_areas; if (old == NULL) { - new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t, sizeof(uint8_t))); + new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t) , sizeof(uint8_t)); } else { while(old->next != NULL) { old = old->next; From 99b6087b01506320de9a8db5ad70b2cc0f2a520f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 21:16:20 +0100 Subject: [PATCH 140/320] chg: use calloc --- client/tinycbor/open_memstream.c | 2 +- client/ui.c | 2 +- client/util.c | 4 ++-- common/crapto1/crapto1.c | 4 ++-- common/radixsort.c | 2 +- uart/uart_posix.c | 2 +- uart/uart_win32.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/tinycbor/open_memstream.c b/client/tinycbor/open_memstream.c index 18f3de8b1..f618db8ae 100644 --- a/client/tinycbor/open_memstream.c +++ b/client/tinycbor/open_memstream.c @@ -90,7 +90,7 @@ static int close_buffer(void *cookie) FILE *open_memstream(char **bufptr, size_t *lenptr) { - struct Buffer *b = (struct Buffer *)malloc(sizeof(struct Buffer)); + struct Buffer *b = (struct Buffer *)calloc(sizeof(struct Buffer), sizeof(uint8_t)); if (b == NULL) return NULL; b->alloc = 0; diff --git a/client/ui.c b/client/ui.c index a0151a8db..71603fed6 100644 --- a/client/ui.c +++ b/client/ui.c @@ -196,7 +196,7 @@ void SetFlushAfterWrite(bool value) { int i,j; - int * output = (int* ) malloc(sizeof(int) * len); + int * output = (int* ) calloc(sizeof(int) * len, sizeof(uint8_t)); if ( !output ) return; // clear mem diff --git a/client/util.c b/client/util.c index b22258d44..c4d6ae5a4 100644 --- a/client/util.c +++ b/client/util.c @@ -884,8 +884,8 @@ extern void strcreplace(char *buf, size_t len, char from, char to) { } extern char *strmcopy(char *buf) { - char* str = NULL; - if ((str = (char*) malloc(strlen(buf) + 1)) != NULL) { + char* str = (char*) calloc(strlen(buf) + 1, sizeof(uint8_t)); + if (str != NULL) { memset(str, 0, strlen(buf) + 1); strcpy(str, buf); } diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index 8dc8f26c8..af1ed8167 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -405,7 +405,7 @@ int nonce_distance(uint32_t from, uint32_t to) { uint16_t x, i; if(!dist) { - dist = malloc(2 << 16); + dist = calloc(2 << 16, sizeof(uint8_t)); if(!dist) return -1; for (x = i = 1; i; ++i) { @@ -443,7 +443,7 @@ static uint32_t fastfwd[2][8] = { */ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) { - uint32_t *candidates = malloc(4 << 10); + uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); if (!candidates) return 0; uint32_t c, entry; diff --git a/common/radixsort.c b/common/radixsort.c index 91495316c..981c19191 100644 --- a/common/radixsort.c +++ b/common/radixsort.c @@ -3,7 +3,7 @@ uint64_t * radixSort(uint64_t * array, uint32_t size) { rscounts_t counts; memset(&counts, 0, 256 * 8 * sizeof(uint32_t)); - uint64_t * cpy = (uint64_t *)malloc(size * sizeof(uint64_t)); + uint64_t * cpy = (uint64_t *)calloc(size * sizeof(uint64_t), sizeof(uint8_t)); uint32_t o8=0, o7=0, o6=0, o5=0, o4=0, o3=0, o2=0, o1=0; uint32_t t8, t7, t6, t5, t4, t3, t2, t1; uint32_t x; diff --git a/uart/uart_posix.c b/uart/uart_posix.c index d857729d6..cb878a4f0 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -75,7 +75,7 @@ const struct timeval timeout = { serial_port uart_open(const char* pcPortName) { - serial_port_unix* sp = malloc(sizeof(serial_port_unix)); + serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); if (sp == 0) return INVALID_SERIAL_PORT; if (memcmp(pcPortName, "tcp:", 4) == 0) { diff --git a/uart/uart_win32.c b/uart/uart_win32.c index 11c90f15f..438f586c8 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -50,7 +50,7 @@ typedef struct { serial_port uart_open(const char* pcPortName) { char acPortName[255]; - serial_port_windows* sp = malloc(sizeof(serial_port_windows)); + serial_port_windows* sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t)); if (sp == 0) { printf("[!] UART failed to allocate memory\n"); From ad72a424ef12b392490fad34f49d1a2d76adab5e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 21:40:50 +0100 Subject: [PATCH 141/320] chg: use calloc --- client/cmdhfmfhard.c | 2 +- client/fpga_compress.c | 6 +++--- client/hid-flasher/flash.c | 6 +++--- client/loclass/cipher.c | 4 ++-- client/loclass/elite_crack.c | 2 +- client/proxmark3.c | 8 ++++---- client/reveng/cli.c | 4 +++- client/reveng/model.c | 2 +- client/reveng/poly.c | 2 +- client/reveng/preset.c | 8 ++++++-- client/reveng/reveng.c | 8 +++++--- client/scandir.c | 3 ++- client/tinycbor/cborparser_dup_string.c | 2 +- client/tinycbor/cbortojson.c | 4 ++-- client/util.c | 2 +- 15 files changed, 36 insertions(+), 27 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 07e05a81e..3547761a5 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -209,7 +209,7 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2) static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) { - return malloc(items*size); + return calloc(items*size, sizeof(uint8_t)); } diff --git a/client/fpga_compress.c b/client/fpga_compress.c index ceba6ac64..6e6e67be4 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -59,7 +59,7 @@ static void usage(void) static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) { - return malloc(items*size); + return calloc(items*size, sizeof(uint8_t)); } @@ -89,9 +89,9 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardn z_stream compressed_fpga_stream; if (hardnested_mode) { - fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE); + fpga_config = calloc(num_infiles * HARDNESTED_TABLE_SIZE, sizeof(uint8_t)); } else { - fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE); + fpga_config = calloc(num_infiles * FPGA_CONFIG_SIZE, sizeof(uint8_t)); } // read the input files. Interleave them into fpga_config[] i = 0; diff --git a/client/hid-flasher/flash.c b/client/hid-flasher/flash.c index e74f4ed49..c53e560d5 100644 --- a/client/hid-flasher/flash.c +++ b/client/hid-flasher/flash.c @@ -40,7 +40,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, flash_seg_t *seg; uint32_t last_end = 0; - ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs); + ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { fprintf(stderr, "Out of memory\n"); return -1; @@ -90,7 +90,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint8_t *data; // make extra space if we need to move the data forward - data = malloc(filesz + BLOCK_SIZE); + data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { fprintf(stderr, "Out of memory\n"); return -1; @@ -226,7 +226,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) } num_phdrs = le16(ehdr.e_phnum); - phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr)); + phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { fprintf(stderr, "Out of memory\n"); goto fail; diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index af11ce4cc..e8553ba6c 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -224,7 +224,7 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t cc_nr[13] = { 0 }; uint8_t div_key[8]; - //cc_nr=(uint8_t*)malloc(length+1); + //cc_nr=(uint8_t*) calloc(length+1, sizeof(uint8_t)); memcpy(cc_nr, cc_nr_p, 12); memcpy(div_key, div_key_p, 8); @@ -244,7 +244,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke { uint8_t *address_data; uint8_t div_key[8]; - address_data = (uint8_t*) malloc(address_data_size); + address_data = (uint8_t*) calloc(address_data_size, sizeof(uint8_t)); memcpy(address_data, address_data_p, address_data_size); memcpy(div_key, div_key_p, 8); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 2002e348f..6619e7aaa 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -493,7 +493,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { uint64_t t1 = msclock(); - dumpdata* attack = (dumpdata* ) malloc(itemsize); + dumpdata* attack = (dumpdata* ) calloc(itemsize, sizeof(uint8_t)); for (i = 0 ; i * itemsize < dumpsize ; i++ ) { memcpy(attack, dump + i * itemsize, itemsize); diff --git a/client/proxmark3.c b/client/proxmark3.c index ed7fd245d..246da350b 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -215,11 +215,11 @@ const char *get_my_executable_directory(void) { static void set_my_executable_path(void) { int path_length = wai_getExecutablePath(NULL, 0, NULL); if (path_length != -1) { - my_executable_path = (char*)malloc(path_length + 1); + my_executable_path = (char*)calloc(path_length + 1, sizeof(uint8_t)); int dirname_length = 0; if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) { my_executable_path[path_length] = '\0'; - my_executable_directory = (char *)malloc(dirname_length + 2); + my_executable_directory = (char *)calloc(dirname_length + 2, sizeof(uint8_t)); strncpy(my_executable_directory, my_executable_path, dirname_length+1); my_executable_directory[dirname_length+1] = '\0'; } @@ -321,9 +321,9 @@ int main(int argc, char* argv[]) { } else { if (addLuaExec){ // add "script run " to command - char *ctmp = NULL; int len = strlen(script_cmd) + 11 + 1; - if ((ctmp = (char*) malloc(len)) != NULL) { + char *ctmp = (char*) calloc(len, sizeof(uint8_t)); + if (ctmp != NULL) { memset(ctmp, 0, len); strcpy(ctmp, "script run "); strcpy(&ctmp[11], script_cmd); diff --git a/client/reveng/cli.c b/client/reveng/cli.c index f4b40856a..6e147ba20 100644 --- a/client/reveng/cli.c +++ b/client/reveng/cli.c @@ -377,7 +377,9 @@ ipqx: /* allocate argument array */ args = argc - optind; - if(!(apolys = malloc(args * sizeof(poly_t)))){ + + apolys = calloc(args * sizeof(poly_t), sizeof(char)); + if ( !apolys ){ uerror("cannot allocate memory for argument list"); return 0; } diff --git a/client/reveng/model.c b/client/reveng/model.c index f99b1ee02..2c58d695a 100644 --- a/client/reveng/model.c +++ b/client/reveng/model.c @@ -118,7 +118,7 @@ char * mtostr(const model_t *model) { + (checkstr && *checkstr ? strlen(checkstr) : 6) + (magicstr && *magicstr ? strlen(magicstr) : 6) + (model->name && *model->name ? 2 + strlen(model->name) : 6); - if ((string = malloc(size))) { + if ((string = calloc(size, sizeof(uint8_t)))) { sprintf(strbuf, "\"%s\"", model->name); sprintf(string, "width=%lu " diff --git a/client/reveng/poly.c b/client/reveng/poly.c index 011a09978..7056c118a 100644 --- a/client/reveng/poly.c +++ b/client/reveng/poly.c @@ -349,7 +349,7 @@ pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned l size *= cperhx; if(!size || ~flags & P_SPACE) ++size; /* for trailing null */ - if(!(sptr = string = (char *) malloc(size))) + if(!(sptr = string = (char *) calloc(size, sizeof(char)))) uerror("cannot allocate memory for string"); size = end - start; diff --git a/client/reveng/preset.c b/client/reveng/preset.c index 6dbedaed9..82a18b977 100644 --- a/client/reveng/preset.c +++ b/client/reveng/preset.c @@ -811,7 +811,9 @@ int mbynam(model_t *dest, const char *key) { if (!aliases->name) return(-1); - if (!(ukey = malloc((size_t) 1 + strlen(key) + 1))) { + + ukey = calloc((size_t) 1 + strlen(key) + 1, sizeof(char)); + if (!ukey) { uerror("[!] cannot allocate memory for comparison string"); return(0); } @@ -861,7 +863,9 @@ char * mnames(void) { ++aptr; } if (!size) return(NULL); - if ((string = malloc(size))) { + + string = calloc(size, sizeof(char)); + if (string) { aptr = aliases; sptr = string; while (aptr->name) { diff --git a/client/reveng/reveng.c b/client/reveng/reveng.c index 004a6fc3c..550dc2da5 100644 --- a/client/reveng/reveng.c +++ b/client/reveng/reveng.c @@ -173,8 +173,9 @@ modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) { unsigned long alen, blen; if(args < 2) return(NULL); - - if(!(result = malloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t)))) + + result = calloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t), sizeof(char)); + if(!result) uerror("cannot allocate memory for codeword table"); rptr = result; @@ -240,7 +241,8 @@ engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, c dlen = plen(divisor); /* Allocate the CRC matrix */ - if(!(mat = (poly_t *) malloc((dlen << 1) * sizeof(poly_t)))) + mat = (poly_t *) calloc((dlen << 1) * sizeof(poly_t), sizeof(char)); + if(!mat) uerror("cannot allocate memory for CRC matrix"); /* Find arguments of the two shortest lengths */ diff --git a/client/scandir.c b/client/scandir.c index 12bbef110..619bd72c6 100644 --- a/client/scandir.c +++ b/client/scandir.c @@ -51,7 +51,8 @@ int scandir (const char *dir, nl = ntmp; } - if (!(etmp = (struct dirent *) malloc (sizeof *ent))) { + etmp = (struct dirent *) calloc (sizeof *ent, sizeof(char)); + if (!etmp) { err_no = 1; break; } diff --git a/client/tinycbor/cborparser_dup_string.c b/client/tinycbor/cborparser_dup_string.c index 061c5ac77..202cd2022 100644 --- a/client/tinycbor/cborparser_dup_string.c +++ b/client/tinycbor/cborparser_dup_string.c @@ -105,7 +105,7 @@ CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t * return err; ++*buflen; - *buffer = malloc(*buflen); + *buffer = calloc(*buflen, sizeof(uint8_t)); if (!*buffer) { /* out of memory */ return CborErrorOutOfMemory; diff --git a/client/tinycbor/cbortojson.c b/client/tinycbor/cbortojson.c index 5a1a2e5dc..34b900bab 100644 --- a/client/tinycbor/cbortojson.c +++ b/client/tinycbor/cbortojson.c @@ -178,7 +178,7 @@ static CborError dump_bytestring_base16(char **result, CborValue *it) return err; /* a Base16 (hex) output is twice as big as our buffer */ - buffer = (uint8_t *)malloc(n * 2 + 1); + buffer = (uint8_t *)calloc(n * 2 + 1, sizeof(uint8_t)); *result = (char *)buffer; /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */ @@ -204,7 +204,7 @@ static CborError generic_dump_base64(char **result, CborValue *it, const char al /* a Base64 output (untruncated) has 4 bytes for every 3 in the input */ size_t len = (n + 5) / 3 * 4; - out = buffer = (uint8_t *)malloc(len + 1); + out = buffer = (uint8_t *)calloc(len + 1, sizeof(uint8_t)); *result = (char *)buffer; /* we read our byte string at the tail end of the buffer diff --git a/client/util.c b/client/util.c index c4d6ae5a4..cea42f338 100644 --- a/client/util.c +++ b/client/util.c @@ -280,7 +280,7 @@ void sprint_bin_break_ex(uint8_t *src, size_t srclen, char *dest , uint8_t break printf("(sprint_bin_break) rowlen %d\n", rowlen); // 3072 + end of line characters if broken at 8 bits - dest = (char *)malloc(MAX_BIN_BREAK_LENGTH); + dest = (char *)calloc(MAX_BIN_BREAK_LENGTH, sizeof(uint8_t)); if (dest == NULL) return; //clear memory From 5c231e772ccb7434c58601d1c1f6968621e7a980 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Jan 2019 21:53:10 +0100 Subject: [PATCH 142/320] chg: use calloc --- client/flash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/flash.c b/client/flash.c index de6fdf7e6..2c06311c3 100644 --- a/client/flash.c +++ b/client/flash.c @@ -38,7 +38,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, flash_seg_t *seg; uint32_t last_end = 0; - ctx->segments = malloc(sizeof(flash_seg_t) * num_phdrs); + ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { fprintf(stderr, "Out of memory\n"); return -1; @@ -88,7 +88,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint8_t *data; // make extra space if we need to move the data forward - data = malloc(filesz + BLOCK_SIZE); + data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { fprintf(stderr, "Error: Out of memory\n"); return -1; @@ -111,7 +111,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint32_t new_length = this_end - prev_seg->start; uint32_t this_offset = paddr - prev_seg->start; uint32_t hole = this_offset - prev_seg->length; - uint8_t *new_data = malloc(new_length); + uint8_t *new_data = calloc(new_length, sizeof(uint8_t)); if (!new_data) { fprintf(stderr, "Error: Out of memory\n"); free(data); @@ -223,7 +223,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) { } num_phdrs = le16(ehdr.e_phnum); - phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr)); + phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { fprintf(stderr, "Out of memory\n"); goto fail; From a01aead732c5a11a8f77bf944610ea2a32b2197e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 31 Jan 2019 16:57:02 +0100 Subject: [PATCH 143/320] add: 'make get_xorsearch' - easy download of xorsearch by Didier Stevens, see https://blog.didierstevens.com/programs/xorsearch/ --- tools/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index 0a6e4430e..c750cce26 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,4 +8,7 @@ get_crapto1: get_nonce_bf: # git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute - git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute \ No newline at end of file + git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute + +get_xorsearch: + wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip \ No newline at end of file From 673c080ea53ae037495b5b9ec6e17d4a293d6ac1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Feb 2019 18:00:08 +0200 Subject: [PATCH 144/320] client part --- client/cmdhf14a.c | 164 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 23 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 4a6b7518d..d9b829e68 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh , Hagen Fritsch -// 2011, 2017 Merlok +// 2011, 2017 - 2019 Merlok // 2014, Peter Fillmore // 2015, 2016, 2017 Iceman // @@ -12,6 +12,8 @@ //----------------------------------------------------------------------------- #include "cmdhf14a.h" +bool APDUInFramingEnable = true; + static int CmdHelp(const char *Cmd); static int waitCmd(uint8_t iLen); @@ -837,15 +839,90 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav return 0; } -int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chaining) { - uint16_t cmdc = 0; +int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { + UsbCommand resp; - *chaining = false; + frameLength = 0; + + if (card) + memset(card, 0, sizeof(iso14a_card_select_t)); - if (activateField) { - cmdc |= ISO14A_CONNECT; + DropField(); + + // Anticollision + SELECT card + UsbCommand ca = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; + SendCommand(&ca); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(ERR, "Proxmark connection timeout."); + return 1; } + // check result + if (resp.arg[0] == 0) { + PrintAndLogEx(ERR, "No card in field."); + return 1; + } + + if (resp.arg[0] != 1 && resp.arg[0] != 2) { + PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.arg[0]); + return 1; + } + + if (resp.arg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision + // get ATS + UsbCommand cr = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0}}; + uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 + memcpy(cr.d.asBytes, rats, 2); + SendCommand(&cr); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(ERR, "Proxmark connection timeout."); + return 1; + } + + if (resp.arg[0] <= 0) { // ats_len + PrintAndLogEx(ERR, "Can't get ATS."); + return 1; + } + + // get frame length from ATS in data field + if (resp.arg[0] > 1) { + uint8_t fsci = resp.d.asBytes[1] & 0x0f; + if (fsci < sizeof(atsFSC)) + frameLength = atsFSC[fsci]; + } + } else { + // get frame length from ATS in card data structure + iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.d.asBytes; + if (vcard->ats_len > 1) { + uint8_t fsci = vcard->ats[1] & 0x0f; + if (fsci < sizeof(atsFSC)) + frameLength = atsFSC[fsci]; + } + + if (card) + memcpy(card, vcard, sizeof(iso14a_card_select_t)); + } + + if (disconnect) + DropField(); + + return 0; +} + +int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) { + *chainingout = false; + + if (activateField) { + // select with no disconnect and set frameLength + int selres = SelectCard14443_4(false, NULL); + if (selres) + return selres; + } + + uint16_t cmdc = 0; + if (chainingin) + cmdc = ISO14A_SEND_CHAINING; + // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes // https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size // here length USB_CMD_DATA_SIZE=512 @@ -857,18 +934,6 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t uint8_t *recv; UsbCommand resp; - if (activateField) { - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "APDU: Proxmark connection timeout."); - return 1; - } - if (resp.arg[0] != 1) { - PrintAndLogEx(ERR, "APDU: Proxmark error %d.", resp.arg[0]); - DropField(); - return 1; - } - } - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { recv = resp.d.asBytes; int iLen = resp.arg[0]; @@ -884,13 +949,20 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t return 2; } + // I-block ACK + if ((res & 0xf2) == 0xa2) { + *dataoutlen = 0; + *chainingout = true; + return 0; + } + if(!iLen) { PrintAndLogEx(ERR, "APDU: No APDU response."); return 1; } // check apdu length - if (iLen < 4 && iLen >= 0) { + if (iLen < 2 && iLen >= 0) { PrintAndLogEx(ERR, "APDU: Small APDU response. Len=%d", iLen); return 2; } @@ -905,7 +977,7 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t // chaining if ((res & 0x10) != 0) { - *chaining = true; + *chainingout = true; } // CRC Check @@ -924,12 +996,58 @@ int CmdExchangeAPDU(uint8_t *datain, int datainlen, bool activateField, uint8_t int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { *dataoutlen = 0; bool chaining = false; - - int res = CmdExchangeAPDU(datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining); + int res; +printf("framelen=%d datainlen=%d\n", frameLength, datainlen); + // 3 byte here - 1b framing header, 2b crc16 + if (APDUInFramingEnable && + ( (frameLength && (datainlen > frameLength - 3)) || (datainlen > USB_CMD_DATA_SIZE - 3)) ) { + int clen = 0; + + bool vActivateField = activateField; + + do { + int vlen = MIN(frameLength - 3, datainlen - clen); + bool chainBlockNotLast = ((clen + vlen) < datainlen); + + *dataoutlen = 0; + res = CmdExchangeAPDU(chainBlockNotLast, &datain[clen], vlen, vActivateField, dataout, maxdataoutlen, dataoutlen, &chaining); + if (res) { + if (!leaveSignalON) + DropField(); + + return 200; + } + + // check R-block ACK + if ((*dataoutlen == 0) && (*dataoutlen != 0 || chaining != chainBlockNotLast)) { + if (!leaveSignalON) + DropField(); + + return 201; + } + + clen += vlen; + vActivateField = false; + if (*dataoutlen) { + if (clen != datainlen) + PrintAndLogEx(WARNING, "APDU: I-block/R-block sequence error. Data len=%d, Sent=%d, Last packet len=%d", datainlen, clen, *dataoutlen); + break; + } + } while (clen < datainlen); + } else { + res = CmdExchangeAPDU(false, datain, datainlen, activateField, dataout, maxdataoutlen, dataoutlen, &chaining); + if (res) { + if (!leaveSignalON) + DropField(); + + return res; + } + } + while (chaining) { // I-block with chaining - res = CmdExchangeAPDU(NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining); + res = CmdExchangeAPDU(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining); if (res) { if (!leaveSignalON) From 09c5f0ef7638d5d536e72d1276dbb18e7ceb208d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Feb 2019 18:12:01 +0200 Subject: [PATCH 145/320] remove debug and small output addon. errors was not visible --- client/cmdhf14a.c | 1 - client/fido/fidocore.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index d9b829e68..cff3eb61e 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -998,7 +998,6 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea bool chaining = false; int res; -printf("framelen=%d datainlen=%d\n", frameLength, datainlen); // 3 byte here - 1b framing header, 2b crc16 if (APDUInFramingEnable && ( (frameLength && (datainlen > frameLength - 3)) || (datainlen > USB_CMD_DATA_SIZE - 3)) ) { diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index ee39fbbe9..f83e64944 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -250,9 +250,9 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu uint32_t verifyflags = 0; res = mbedtls_x509_crt_verify(&cert, &cacert, NULL, NULL, &verifyflags, NULL, NULL); if (res) { - PrintAndLog("ERROR: DER verify returned 0x%x - %s", (res<0)?-res:res, ecdsa_get_error(res)); + PrintAndLog("ERROR: DER verify returned 0x%x - %s\n", (res<0)?-res:res, ecdsa_get_error(res)); } else { - PrintAndLog("Certificate OK."); + PrintAndLog("Certificate OK.\n"); } if (verbose) { From 34bae8adcf18d503d36c84c29ad7f27bdb95e877 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Feb 2019 18:51:53 +0200 Subject: [PATCH 146/320] add `hf 14a chaining` --- client/cmdhf14a.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index cff3eb61e..c38a876e8 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1323,6 +1323,37 @@ int CmdHF14AAntiFuzz(const char *cmd) { return 0; } +int CmdHF14AChaining(const char *cmd) { + + CLIParserInit("hf 14a chaining", + "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", + "Usage:\n" + "\thf 14a chaining disable -> disable chaining\n" + "\thf 14a chaining -> show chaining enable/disable state\n"); + + void* argtable[] = { + arg_param_begin, + arg_str0(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + struct arg_str *str = arg_get_str(1); + int len = arg_get_str_len(1); + + if (len && (!strcmp(str->sval[0], "enable") || !strcmp(str->sval[0], "1"))) + APDUInFramingEnable = true; + + if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0"))) + APDUInFramingEnable = false; + + CLIParserFree(); + + PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); + + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"}, @@ -1332,6 +1363,7 @@ static command_t CommandTable[] = { {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443-a tag"}, {"sniff", CmdHF14ASniff, 0, "sniff ISO 14443-a traffic"}, {"apdu", CmdHF14AAPDU, 0, "Send ISO 14443-4 APDU to tag"}, + {"chaining", CmdHF14AChaining, 0, "Control ISO 14443-4 input chaining"}, {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, {"antifuzz", CmdHF14AAntiFuzz, 0, "Fuzzing the anticollision phase. Warning! Readers may react strange"}, {NULL, NULL, 0, NULL} From 029e75e866b9bb9abd97e4ab170e3ade7f8ecbc8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Feb 2019 18:54:57 +0200 Subject: [PATCH 147/320] formatting --- client/cmdhf14a.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index c38a876e8..9140a3502 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1358,13 +1358,13 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443-a history"}, {"info", CmdHF14AInfo, 0, "Tag information"}, - {"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"}, + {"reader", CmdHF14AReader, 0, "Act like an ISO14443-a reader"}, {"cuids", CmdHF14ACUIDs, 0, " Collect n>0 ISO14443-a UIDs in one go"}, - {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443-a tag"}, + {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443-a tag"}, {"sniff", CmdHF14ASniff, 0, "sniff ISO 14443-a traffic"}, {"apdu", CmdHF14AAPDU, 0, "Send ISO 14443-4 APDU to tag"}, {"chaining", CmdHF14AChaining, 0, "Control ISO 14443-4 input chaining"}, - {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, + {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, {"antifuzz", CmdHF14AAntiFuzz, 0, "Fuzzing the anticollision phase. Warning! Readers may react strange"}, {NULL, NULL, 0, NULL} }; From 77f4492433f170db1f1bd06eba0d3bb09be4531b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 2 Feb 2019 19:30:32 +0100 Subject: [PATCH 148/320] fix: 'hf 15 write' - faulty string formatter token --- client/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index d8a212130..a1b55d7c6 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -1241,7 +1241,7 @@ int CmdHF15Write(const char *Cmd) { AddCrc(req, reqlen); c.arg[0] = reqlen+2; - PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x&02X) | data ", pagenum, pagenum); + PrintAndLogEx(NORMAL, "iso15693 writing to page %02d (0x%02X) | data ", pagenum, pagenum); clearCommandBuffer(); SendCommand(&c); From 95db68fa30af72786f58cd08d1abdc9084c46669 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 3 Feb 2019 10:18:22 +0100 Subject: [PATCH 149/320] FIX: scripts path needed for scripts to call other scripts. --- client/scripting.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/scripting.c b/client/scripting.c index 3d3518ced..b6bb80f33 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -758,6 +758,15 @@ int set_pm3_libraries(lua_State *L) { //-- remove the global environment table from the stack lua_pop(L, 1); + + //--add to the LUA_PATH (package.path in lua) + // so we can load scripts from the ./scripts/ - directory + char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, get_my_executable_directory()); + strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + //-- Last but not least, add to the LUA_PATH (package.path in lua) // so we can load libraries from the ./lualib/ - directory char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; @@ -765,6 +774,5 @@ int set_pm3_libraries(lua_State *L) { strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); strcat(libraries_path, LUA_LIBRARIES_WILDCARD); setLuaPath(L, libraries_path); - return 1; } \ No newline at end of file From 7678ab13e0b2bae4d8a58ae1194ffa6379700d73 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Feb 2019 22:36:15 +0200 Subject: [PATCH 150/320] add slolkey CA root --- client/fido/additional_ca.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index f529e99b5..564eda2ae 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -58,6 +58,23 @@ "U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==\r\n" \ "-----END CERTIFICATE-----\r\n" +// Name: SoloKey U2F Root CA Serial 14143382635911888524 (0xc44763928ff4be8c) +// Issued: 2018-11-11 +#define SOLOKEY_CA \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIB9DCCAZoCCQDER2OSj/S+jDAKBggqhkjOPQQDAjCBgDELMAkGA1UEBhMCVVMx\r\n" \ +"ETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsM\r\n" \ +"B1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYS\r\n" \ +"aGVsbG9Ac29sb2tleXMuY29tMCAXDTE4MTExMTEyNTE0MloYDzIwNjgxMDI5MTI1\r\n" \ +"MTQyWjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQK\r\n" \ +"DAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlz\r\n" \ +"LmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMFkwEwYHKoZI\r\n" \ +"zj0CAQYIKoZIzj0DAQcDQgAEWHAN0CCJVZdMs0oktZ5m93uxmB1iyq8ELRLtqVFL\r\n" \ +"SOiHQEab56qRTB/QzrpGAY++Y2mw+vRuQMNhBiU0KzwjBjAKBggqhkjOPQQDAgNI\r\n" \ +"ADBFAiEAz9SlrAXIlEu87vra54rICPs+4b0qhp3PdzcTg7rvnP0CIGjxzlteQQx+\r\n" \ +"jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs\r\n" \ +"-----END CERTIFICATE-----\r\n" + /* Concatenation of all additional CA certificates in PEM format if available */ -const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA; +const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); From 75aeec65072b47694d51796aa7581ced2f0b9fda Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Mon, 4 Feb 2019 17:44:29 +0000 Subject: [PATCH 151/320] Add led blink on successful flash write --- armsrc/Standalone/hf_bog.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 9079d5df3..65254bd5c 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -271,6 +271,11 @@ void RAMFUNC SniffAndStore(uint8_t param) { uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts); if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen); + // If pwd saved successfully, blink led A three times + if (writelen > 0) { + SpinErr(0, 200, 5); // blink led A + } + SpinDelay(100); // Reset the SPI Baudrate to the default value (24MHz) From cd44ea27b785d693a03689cb709d5cefd13c0537 Mon Sep 17 00:00:00 2001 From: "osboxes.org" Date: Mon, 4 Feb 2019 22:16:12 +0100 Subject: [PATCH 152/320] FIX: 'script run mifare_autopwn' - now doesn't crash --- client/scripts/mifare_autopwn.lua | 46 ++++++++++++++++++++++--------- client/scripts/remagic.lua | 1 + 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index 9bd149a55..738ca6950 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -12,8 +12,10 @@ This is a script which automates cracking and dumping mifare classic cards. It s place by the device. Arguments: - -d debug logging on - -h this help + -h this help + -d debug logging on + -k known key for Sector 0 , keytype A + Output files from this operation: .eml - emulator file @@ -73,12 +75,12 @@ local function nested(key,sak) if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k typ = 4 elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K - typ= 1 + typ = 1 elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k typ = 0 - elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" + elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" typ = 2 - elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" + elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" typ = 1 else print("I don't know how many sectors there are on this type of card, defaulting to 16") @@ -87,22 +89,40 @@ local function nested(key,sak) core.console(cmd) end -local function dump(uid) +local function dump(uid, numsectors) dbg('dumping tag memory') + local typ = 1 + if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k | Ev1 4k + typ = 4 + elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k | Ev1 1K + typ = 1 + elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k + typ = 0 + elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" + typ = 2 + elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" + typ = 1 + end + if utils.confirm('Do you wish to create a memory dump of tag?') then - core.console("hf mf dump") + local dumpfile = 'hf-mf-'..uid..'-data.bin' + + local dmp = ('hf mf dump %s f %s'):format(typ, dumpfile) + core.console(dmp) + -- Save the global args, those are *our* arguments local myargs = args -- Set the arguments for htmldump script - args =("-o %s.html"):format(uid) + args =('-i %s -o %s.html'):format(dumpfile, uid) -- call it - require('../scripts/htmldump') + require('htmldump') - args ="" -- dump to emulator - require('../scripts/dumptoemul') + args =('-i %s -o %s.eml'):format(dumpfile, uid) + require('dumptoemul') + -- Set back args. Not that it's used, just for the karma... args = myargs end @@ -177,9 +197,9 @@ local function main(args) print("Found valid key: "..key); end -- Use nested attack - nested(key,sak) + nested(key, sak) -- Dump info - dump(uid) + dump(uid, sak) if #key == 12 then exit = true end else diff --git a/client/scripts/remagic.lua b/client/scripts/remagic.lua index 5062d8cf4..10e25583a 100644 --- a/client/scripts/remagic.lua +++ b/client/scripts/remagic.lua @@ -72,6 +72,7 @@ local function sendCmds( cmds ) if cmds[i] then print ( cmds[i] ) core.console( cmds[i] ) + core.clearCommandBuffer() end end end From 0e5d8968938199b91c760921ebf1b0428747530a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 5 Feb 2019 18:27:48 +0200 Subject: [PATCH 153/320] fix endless loop --- armsrc/iso14443a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 082d378ac..e63cd5e74 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2248,7 +2248,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u return 0; //DATA LINK ERROR } else{ // S-Block WTX - while((data_bytes[0] & 0xF2) == 0xF2) { + while(len && ((data_bytes[0] & 0xF2) == 0xF2)) { uint32_t save_iso14a_timeout = iso14a_get_timeout(); // temporarily increase timeout iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT) ); From 69f3e65dd0c8a1f1f95c4bbb0b975205f57c40c1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 5 Feb 2019 18:39:03 +0200 Subject: [PATCH 154/320] fix memmove if len=0 --- armsrc/iso14443a.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index e63cd5e74..4267d28af 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2266,32 +2266,34 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u iso14a_set_timeout(save_iso14a_timeout); } - // if we received an I- or R(ACK)-Block with a block number equal to the - // current block number, toggle the current block number + // if we received an I- or R(ACK)-Block with a block number equal to the + // current block number, toggle the current block number if (len >= 3 // PCB+CRC = 3 bytes && ((data_bytes[0] & 0xC0) == 0 // I-Block || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers - { - iso14_pcb_blocknum ^= 1; - } + { + iso14_pcb_blocknum ^= 1; + } // if we received I-block with chaining we need to send ACK and receive another block of data if (res) *res = data_bytes[0]; // crc check - if (len >=3 && !check_crc(CRC_14443_A, data_bytes, len)) { + if (len >= 3 && !check_crc(CRC_14443_A, data_bytes, len)) { return -1; } } - // cut frame byte - len -= 1; - // memmove(data_bytes, data_bytes + 1, len); - for (int i = 0; i < len; i++) - data_bytes[i] = data_bytes[i + 1]; + if (len) { + // cut frame byte + len -= 1; + // memmove(data_bytes, data_bytes + 1, len); + for (int i = 0; i < len; i++) + data_bytes[i] = data_bytes[i + 1]; + } return len; } From 7934630d2bfa3768e23b0aed43f72ca830a520cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 14 Feb 2019 19:27:39 +0100 Subject: [PATCH 155/320] FIX: Makefile bad styled calls --- armsrc/Makefile | 4 ++-- client/Makefile | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 76f3a0173..efc443227 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -21,7 +21,7 @@ APP_CFLAGS = -DWITH_CRC \ -DWITH_ISO14443a \ -DWITH_ICLASS \ -DWITH_FELICA \ - -DWITH_FLASH \ + -DWITH_FLASH \ -DWITH_SMARTCARD \ -DWITH_FPC \ -DWITH_HFSNOOP \ @@ -191,7 +191,7 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ $(FPGA_COMPRESSOR): - make -C ../client $(notdir $(FPGA_COMPRESSOR)) + $(MAKE) -C ../client $(notdir $(FPGA_COMPRESSOR)) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) diff --git a/client/Makefile b/client/Makefile index 4f7168fa0..0b19d4599 100644 --- a/client/Makefile +++ b/client/Makefile @@ -299,29 +299,29 @@ lualibs/mf_default_keys.lua : default_keys.dic clean: $(RM) $(CLEAN) - cd ../liblua && make clean - cd $(JANSSONLIBPATH) && make clean - cd $(MBEDTLSLIBPATH) && make clean - cd $(CBORLIBPATH) && make clean + cd ../liblua && $(MAKE) clean + cd $(JANSSONLIBPATH) && $(MAKE) clean + cd $(MBEDTLSLIBPATH) && $(MAKE) clean + cd $(CBORLIBPATH) && $(MAKE) clean tarbin: $(BINS) $(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) lua_build: @echo Compiling liblua, using platform $(LUAPLATFORM) - cd ../liblua && make $(LUAPLATFORM) + cd ../liblua && $(MAKE) $(LUAPLATFORM) jansson_build: @echo Compiling jansson - cd $(JANSSONLIBPATH) && make all + cd $(JANSSONLIBPATH) && $(MAKE) all mbedtls_build: @echo Compiling mbedtls - cd $(MBEDTLSLIBPATH) && make all + cd $(MBEDTLSLIBPATH) && $(MAKE) all cbor_build: @echo Compiling tinycbor - cd $(CBORLIBPATH) && make all + cd $(CBORLIBPATH) && $(MAKE) all .PHONY: all clean From 35df317a2cae5610c9b94fdcd0718916eb9257ad Mon Sep 17 00:00:00 2001 From: vratiskol Date: Fri, 15 Feb 2019 01:08:30 +0100 Subject: [PATCH 156/320] Update MAXBLOCK - MF 4K - Modify MAXBLOCK size: 4k => 256 - Typo --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a26381930..32fd65872 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -11,7 +11,7 @@ #include "cmdhfmf.h" #include "mifare4.h" -#define MIFARE_4K_MAXBLOCK 255 +#define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 #define MIFARE_1K_MAXBLOCK 64 #define MIFARE_MINI_MAXBLOCK 20 @@ -2503,7 +2503,7 @@ int CmdHF14AMfESave(const char *Cmd) { } memset(dump, 0, bytes); - PrintAndLogEx(INFO, "dowingloading from emulator memory"); + PrintAndLogEx(INFO, "downloading from emulator memory"); if (!GetFromDevice( BIG_BUF_EML, dump, bytes, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); From f8985ed1be1179437b6cf669559585d0b5e0d7f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 15 Feb 2019 12:38:38 +0100 Subject: [PATCH 157/320] chg: remove warning for overflow --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a26381930..55f2b03df 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -645,7 +645,7 @@ int CmdHF14AMfRdSc(const char *Cmd) { return 0; } -uint8_t NumOfBlocks(char card){ +uint16_t NumOfBlocks(char card){ switch(card){ case '0' : return MIFARE_MINI_MAXBLOCK; case '1' : return MIFARE_1K_MAXBLOCK; From 8e6b41f513e4aac14845a507a6bf52c6df93c303 Mon Sep 17 00:00:00 2001 From: vratiskol Date: Fri, 15 Feb 2019 15:17:28 +0100 Subject: [PATCH 158/320] Use Variable for MIFARE_MINI_MAXSECTOR Modify type uint16_t => 256 --- client/cmdhfmf.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 32fd65872..8129aceb6 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -16,6 +16,11 @@ #define MIFARE_1K_MAXBLOCK 64 #define MIFARE_MINI_MAXBLOCK 20 +#define MIFARE_MINI_MAXSECTOR 5 +#define MIFARE_1K_MAXSECTOR 16 +#define MIFARE_2K_MAXSECTOR 32 +#define MIFARE_4K_MAXSECTOR 40 + static int CmdHelp(const char *Cmd); int usage_hf14_ice(void){ @@ -591,7 +596,7 @@ int CmdHF14AMfRdSc(const char *Cmd) { } sectorNo = param_get8(Cmd, 0); - if (sectorNo > 39) { + if (sectorNo > MIFARE_4K_MAXSECTOR ) { PrintAndLogEx(NORMAL, "Sector number must be less than 40"); return 1; } @@ -645,7 +650,7 @@ int CmdHF14AMfRdSc(const char *Cmd) { return 0; } -uint8_t NumOfBlocks(char card){ +uint16_t NumOfBlocks(char card){ switch(card){ case '0' : return MIFARE_MINI_MAXBLOCK; case '1' : return MIFARE_1K_MAXBLOCK; @@ -656,11 +661,11 @@ uint8_t NumOfBlocks(char card){ } uint8_t NumOfSectors(char card){ switch(card){ - case '0' : return 5; - case '1' : return 16; - case '2' : return 32; - case '4' : return 40; - default : return 16; + case '0' : return MIFARE_MINI_MAXSECTOR; + case '1' : return MIFARE_1K_MAXSECTOR; + case '2' : return MIFARE_2K_MAXSECTOR; + case '4' : return MIFARE_4K_MAXSECTOR; + default : return MIFARE_1K_MAXSECTOR; } } @@ -1497,11 +1502,11 @@ int CmdHF14AMfChk_fast(const char *Cmd) { // sectors switch(ctmp) { - case '0': sectorsCnt = 5; break; - case '1': sectorsCnt = 16; break; - case '2': sectorsCnt = 32; break; - case '4': sectorsCnt = 40; break; - default: sectorsCnt = 16; + case '0': sectorsCnt = MIFARE_MINI_MAXSECTOR; break; + case '1': sectorsCnt = MIFARE_1K_MAXSECTOR; break; + case '2': sectorsCnt = MIFARE_2K_MAXSECTOR; break; + case '4': sectorsCnt = MIFARE_4K_MAXSECTOR; break; + default: sectorsCnt = MIFARE_1K_MAXSECTOR; } for (i = 1; param_getchar(Cmd, i); i++) { @@ -2412,14 +2417,14 @@ int CmdHF14AMfELoad(const char *Cmd) { return usage_hf14_eload(); switch (c) { - case '0' : numBlocks = 5*4; break; + case '0' : numBlocks = MIFARE_MINI_MAXBLOCK; break; case '1' : - case '\0': numBlocks = 16*4; break; - case '2' : numBlocks = 32*4; break; - case '4' : numBlocks = 256; break; + case '\0': numBlocks = MIFARE_1K_MAXBLOCK; break; + case '2' : numBlocks = MIFARE_2K_MAXBLOCK; break; + case '4' : numBlocks = MIFARE_4K_MAXBLOCK; break; case 'u' : numBlocks = 255; blockWidth = 4; break; default: { - numBlocks = 16*4; + numBlocks = MIFARE_1K_MAXBLOCK; nameParamNo = 0; } } @@ -2761,7 +2766,7 @@ int CmdHF14AMfCLoad(const char *Cmd) { blockNum++; // magic card type - mifare 1K - if (blockNum >= 16 * 4) break; + if (blockNum >= MIFARE_1K_MAXBLOCK ) break; } PrintAndLogEx(NORMAL, "\n"); From 77eaa360930ca3d9efb7db8adaaf5df2b9444894 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 17 Feb 2019 11:07:48 +0100 Subject: [PATCH 159/320] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index effdc0f6e..c8c04f852 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,14 @@ This fork now compiles just fine on ## KALI and ARCHLINUX users Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly. -`sudo apt remove modemmanager` +```sh +sudo apt remove modemmanager +``` +or +```sh +systemctl stop ModemManager +systemctl disable ModemManager +``` ## Setup and build for UBUNTU GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04 From 535d4e6ee9e2ab49b130acafe1440aaaab4d1048 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Feb 2019 15:37:20 +0100 Subject: [PATCH 160/320] FIX: usb slow for posix systems - https://github.com/Proxmark/proxmark3/pull/787 (@fl0-0) --- uart/uart_posix.c | 543 +++++++++++++++++++++++----------------------- 1 file changed, 273 insertions(+), 270 deletions(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index cb878a4f0..88397fa5f 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -70,338 +70,341 @@ typedef struct { // Set time-out on 30 miliseconds const struct timeval timeout = { .tv_sec = 0, // 0 second - .tv_usec = 300000 // 300 000 micro seconds + .tv_usec = 30000 // 30 000 micro seconds }; -serial_port uart_open(const char* pcPortName) -{ - serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); - if (sp == 0) return INVALID_SERIAL_PORT; +serial_port uart_open(const char* pcPortName) { + serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); + if (sp == 0) return INVALID_SERIAL_PORT; - if (memcmp(pcPortName, "tcp:", 4) == 0) { - struct addrinfo *addr, *rp; - char *addrstr = strdup(pcPortName + 4); + if (memcmp(pcPortName, "tcp:", 4) == 0) { + struct addrinfo *addr, *rp; + char *addrstr = strdup(pcPortName + 4); - if (addrstr == NULL) { - printf("Error: strdup\n"); - return INVALID_SERIAL_PORT; - } + if (addrstr == NULL) { + printf("Error: strdup\n"); + return INVALID_SERIAL_PORT; + } - char *colon = strrchr(addrstr, ':'); - char *portstr; - if (colon) { - portstr = colon + 1; - *colon = '\0'; - } else { - portstr = "7901"; + timeout.tv_usec = 300000 // 300 000 micro seconds + + char *colon = strrchr(addrstr, ':'); + char *portstr; + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else { + portstr = "7901"; + } + + int s = getaddrinfo(addrstr, portstr, NULL, &addr); + if (s != 0) { + printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + return INVALID_SERIAL_PORT; + } + + int sfd; + for (rp = addr; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + printf("Error: Could not connect\n"); + return INVALID_SERIAL_PORT; + } + + freeaddrinfo(addr); + free(addrstr); + + sp->fd = sfd; + + int one = 1; + setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + return sp; } - - int s = getaddrinfo(addrstr, portstr, NULL, &addr); - if (s != 0) { - printf("Error: getaddrinfo: %s\n", gai_strerror(s)); - return INVALID_SERIAL_PORT; - } - - int sfd; - for (rp = addr; rp != NULL; rp = rp->ai_next) { - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (sfd == -1) - continue; - - if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) - break; - - close(sfd); - } - - if (rp == NULL) { /* No address succeeded */ - printf("Error: Could not connect\n"); - return INVALID_SERIAL_PORT; - } - - freeaddrinfo(addr); - free(addrstr); - - sp->fd = sfd; - - int one = 1; - setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); - return sp; - } - sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - if(sp->fd == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if(sp->fd == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } - // Finally figured out a way to claim a serial port interface under unix - // We just try to set a (advisory) lock on the file descriptor - struct flock fl; - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - - // Does the system allows us to place a lock on this file descriptor - if (fcntl(sp->fd, F_SETLK, &fl) == -1) { - // A conflicting lock is held by another process - free(sp); - return CLAIMED_SERIAL_PORT; - } + // Finally figured out a way to claim a serial port interface under unix + // We just try to set a (advisory) lock on the file descriptor + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); + + // Does the system allows us to place a lock on this file descriptor + if (fcntl(sp->fd, F_SETLK, &fl) == -1) { + // A conflicting lock is held by another process + free(sp); + return CLAIMED_SERIAL_PORT; + } + + // Try to retrieve the old (current) terminal info struct + if(tcgetattr(sp->fd,&sp->tiOld) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + // Duplicate the (old) terminal info struct + sp->tiNew = sp->tiOld; + + // Configure the serial port + sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; + sp->tiNew.c_iflag = IGNPAR; + sp->tiNew.c_oflag = 0; + sp->tiNew.c_lflag = 0; + + // Block until n bytes are received + sp->tiNew.c_cc[VMIN] = 0; + // Block until a timer expires (n * 100 mSec.) + sp->tiNew.c_cc[VTIME] = 0; + + // Try to set the new terminal info struct + if(tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } - // Try to retrieve the old (current) terminal info struct - if(tcgetattr(sp->fd,&sp->tiOld) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Duplicate the (old) terminal info struct - sp->tiNew = sp->tiOld; - - // Configure the serial port - sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; - sp->tiNew.c_iflag = IGNPAR; - sp->tiNew.c_oflag = 0; - sp->tiNew.c_lflag = 0; - - // Block until n bytes are received - sp->tiNew.c_cc[VMIN] = 0; - // Block until a timer expires (n * 100 mSec.) - sp->tiNew.c_cc[VTIME] = 0; - - // Try to set the new terminal info struct - if(tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - // Flush all lingering data that may exist tcflush(sp->fd, TCIOFLUSH); #ifdef WITH_FPC if ( uart_set_speed(sp, 115200) ) { - printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); + printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); } else { uart_set_speed(sp, 9600); printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n"); } #else - // set speed, works for UBUNTU 14.04 - bool success = uart_set_speed(sp, 460800); - if (success) { - printf("[=] UART Setting serial baudrate 460800\n"); - } else { - uart_set_speed(sp, 115200); - printf("[=] UART Setting serial baudrate 115200\n"); - } + // set speed, works for UBUNTU 14.04 + bool success = uart_set_speed(sp, 460800); + if (success) { + printf("[=] UART Setting serial baudrate 460800\n"); + } else { + uart_set_speed(sp, 115200); + printf("[=] UART Setting serial baudrate 115200\n"); + } #endif - return sp; + return sp; } void uart_close(const serial_port sp) { - serial_port_unix* spu = (serial_port_unix*)sp; - tcflush(spu->fd, TCIOFLUSH); - tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); - struct flock fl; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); + serial_port_unix* spu = (serial_port_unix*)sp; + tcflush(spu->fd, TCIOFLUSH); + tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); + struct flock fl; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); - // Does the system allows us to place a lock on this file descriptor - int err = fcntl(spu->fd, F_SETLK, &fl); - if ( err == -1) { - //perror("fcntl"); - } - close(spu->fd); - free(sp); + // Does the system allows us to place a lock on this file descriptor + int err = fcntl(spu->fd, F_SETLK, &fl); + if ( err == -1) { + //perror("fcntl"); + } + close(spu->fd); + free(sp); } bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) { - int res; - int byteCount; - fd_set rfds; - struct timeval tv; + int res; + int byteCount; + fd_set rfds; + struct timeval tv; + + // Reset the output count + *pszRxLen = 0; - // Reset the output count - *pszRxLen = 0; - - do { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix*)sp)->fd, &rfds); - tv = timeout; - res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv); - - // Read error - if (res < 0) { - return false; - } - - // Read time-out - if (res == 0) { - if (*pszRxLen == 0) { - // Error, we received no data - return false; - } else { - // We received some data, but nothing more is available - return true; - } - } - - // Retrieve the count of the incoming bytes - res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); - if (res < 0) return false; - - // Cap the number of bytes, so we don't overrun the buffer - if (pszMaxRxLen - (*pszRxLen) < byteCount) { - byteCount = pszMaxRxLen - (*pszRxLen); - } + do { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd, &rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv); - // There is something available, read the data - res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount); + // Read error + if (res < 0) { + return false; + } - // Stop if the OS has some troubles reading the data - if (res <= 0) return false; - - *pszRxLen += res; + // Read time-out + if (res == 0) { + if (*pszRxLen == 0) { + // Error, we received no data + return false; + } else { + // We received some data, but nothing more is available + return true; + } + } - if (*pszRxLen == pszMaxRxLen) { - // We have all the data we wanted. - return true; - } - - } while (byteCount); + // Retrieve the count of the incoming bytes + res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); + if (res < 0) return false; - return true; + // Cap the number of bytes, so we don't overrun the buffer + if (pszMaxRxLen - (*pszRxLen) < byteCount) { + byteCount = pszMaxRxLen - (*pszRxLen); + } + + // There is something available, read the data + res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount); + + // Stop if the OS has some troubles reading the data + if (res <= 0) return false; + + *pszRxLen += res; + + if (*pszRxLen == pszMaxRxLen) { + // We have all the data we wanted. + return true; + } + + } while (byteCount); + + return true; } bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t len) { - int32_t res; - size_t pos = 0; - fd_set rfds; - struct timeval tv; + int32_t res; + size_t pos = 0; + fd_set rfds; + struct timeval tv; - while (pos < len) { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix*)sp)->fd, &rfds); - tv = timeout; - res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv); - - // Write error - if (res < 0) { - printf("UART:: write error (%d)\n", res); - return false; - } - - // Write time-out - if (res == 0) { - printf("UART:: write time-out\n"); - return false; - } - - // Send away the bytes - res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos); - - // Stop if the OS has some troubles sending the data - if (res <= 0) return false; - - pos += res; - } - return true; + while (pos < len) { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd, &rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv); + + // Write error + if (res < 0) { + printf("UART:: write error (%d)\n", res); + return false; + } + + // Write time-out + if (res == 0) { + printf("UART:: write time-out\n"); + return false; + } + + // Send away the bytes + res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos); + + // Stop if the OS has some troubles sending the data + if (res <= 0) return false; + + pos += res; + } + return true; } bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { - const serial_port_unix* spu = (serial_port_unix*)sp; - speed_t stPortSpeed; - switch (uiPortSpeed) { - case 0: stPortSpeed = B0; break; - case 50: stPortSpeed = B50; break; - case 75: stPortSpeed = B75; break; - case 110: stPortSpeed = B110; break; - case 134: stPortSpeed = B134; break; - case 150: stPortSpeed = B150; break; - case 300: stPortSpeed = B300; break; - case 600: stPortSpeed = B600; break; - case 1200: stPortSpeed = B1200; break; - case 1800: stPortSpeed = B1800; break; - case 2400: stPortSpeed = B2400; break; - case 4800: stPortSpeed = B4800; break; - case 9600: stPortSpeed = B9600; break; - case 19200: stPortSpeed = B19200; break; - case 38400: stPortSpeed = B38400; break; + const serial_port_unix* spu = (serial_port_unix*)sp; + speed_t stPortSpeed; + switch (uiPortSpeed) { + case 0: stPortSpeed = B0; break; + case 50: stPortSpeed = B50; break; + case 75: stPortSpeed = B75; break; + case 110: stPortSpeed = B110; break; + case 134: stPortSpeed = B134; break; + case 150: stPortSpeed = B150; break; + case 300: stPortSpeed = B300; break; + case 600: stPortSpeed = B600; break; + case 1200: stPortSpeed = B1200; break; + case 1800: stPortSpeed = B1800; break; + case 2400: stPortSpeed = B2400; break; + case 4800: stPortSpeed = B4800; break; + case 9600: stPortSpeed = B9600; break; + case 19200: stPortSpeed = B19200; break; + case 38400: stPortSpeed = B38400; break; # ifdef B57600 - case 57600: stPortSpeed = B57600; break; + case 57600: stPortSpeed = B57600; break; # endif # ifdef B115200 - case 115200: stPortSpeed = B115200; break; + case 115200: stPortSpeed = B115200; break; # endif # ifdef B230400 - case 230400: stPortSpeed = B230400; break; + case 230400: stPortSpeed = B230400; break; # endif # ifdef B460800 - case 460800: stPortSpeed = B460800; break; + case 460800: stPortSpeed = B460800; break; # endif # ifdef B921600 - case 921600: stPortSpeed = B921600; break; + case 921600: stPortSpeed = B921600; break; # endif - default: return false; - }; - struct termios ti; - if (tcgetattr(spu->fd,&ti) == -1) return false; - // Set port speed (Input and Output) - cfsetispeed(&ti, stPortSpeed); - cfsetospeed(&ti, stPortSpeed); - return (tcsetattr(spu->fd, TCSANOW, &ti) != -1); + default: return false; + }; + struct termios ti; + if (tcgetattr(spu->fd,&ti) == -1) return false; + // Set port speed (Input and Output) + cfsetispeed(&ti, stPortSpeed); + cfsetospeed(&ti, stPortSpeed); + return (tcsetattr(spu->fd, TCSANOW, &ti) != -1); } uint32_t uart_get_speed(const serial_port sp) { - struct termios ti; - uint32_t uiPortSpeed; - const serial_port_unix* spu = (serial_port_unix*)sp; - if (tcgetattr(spu->fd, &ti) == -1) return 0; - // Set port speed (Input) - speed_t stPortSpeed = cfgetispeed(&ti); - switch (stPortSpeed) { - case B0: uiPortSpeed = 0; break; - case B50: uiPortSpeed = 50; break; - case B75: uiPortSpeed = 75; break; - case B110: uiPortSpeed = 110; break; - case B134: uiPortSpeed = 134; break; - case B150: uiPortSpeed = 150; break; - case B300: uiPortSpeed = 300; break; - case B600: uiPortSpeed = 600; break; - case B1200: uiPortSpeed = 1200; break; - case B1800: uiPortSpeed = 1800; break; - case B2400: uiPortSpeed = 2400; break; - case B4800: uiPortSpeed = 4800; break; - case B9600: uiPortSpeed = 9600; break; - case B19200: uiPortSpeed = 19200; break; - case B38400: uiPortSpeed = 38400; break; + struct termios ti; + uint32_t uiPortSpeed; + const serial_port_unix* spu = (serial_port_unix*)sp; + + if (tcgetattr(spu->fd, &ti) == -1) + return 0; + + // Set port speed (Input) + speed_t stPortSpeed = cfgetispeed(&ti); + switch (stPortSpeed) { + case B0: uiPortSpeed = 0; break; + case B50: uiPortSpeed = 50; break; + case B75: uiPortSpeed = 75; break; + case B110: uiPortSpeed = 110; break; + case B134: uiPortSpeed = 134; break; + case B150: uiPortSpeed = 150; break; + case B300: uiPortSpeed = 300; break; + case B600: uiPortSpeed = 600; break; + case B1200: uiPortSpeed = 1200; break; + case B1800: uiPortSpeed = 1800; break; + case B2400: uiPortSpeed = 2400; break; + case B4800: uiPortSpeed = 4800; break; + case B9600: uiPortSpeed = 9600; break; + case B19200: uiPortSpeed = 19200; break; + case B38400: uiPortSpeed = 38400; break; # ifdef B57600 - case B57600: uiPortSpeed = 57600; break; + case B57600: uiPortSpeed = 57600; break; # endif # ifdef B115200 - case B115200: uiPortSpeed = 115200; break; + case B115200: uiPortSpeed = 115200; break; # endif # ifdef B230400 - case B230400: uiPortSpeed = 230400; break; + case B230400: uiPortSpeed = 230400; break; # endif # ifdef B460800 - case B460800: uiPortSpeed = 460800; break; + case B460800: uiPortSpeed = 460800; break; # endif # ifdef B921600 - case B921600: uiPortSpeed = 921600; break; + case B921600: uiPortSpeed = 921600; break; # endif - default: return 0; - }; - return uiPortSpeed; + default: return 0; + }; + return uiPortSpeed; } - #endif From f05ab29c04e8f6f9d4f4be36d0784f9f6dd7c0d4 Mon Sep 17 00:00:00 2001 From: Fl0-0 Date: Sun, 17 Feb 2019 15:51:37 +0100 Subject: [PATCH 161/320] Fix for USB uart slowness See Proxmark#787 --- uart/uart_posix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index cb878a4f0..093aaf363 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -68,9 +68,9 @@ typedef struct { } serial_port_unix; // Set time-out on 30 miliseconds -const struct timeval timeout = { +struct timeval timeout = { .tv_sec = 0, // 0 second - .tv_usec = 300000 // 300 000 micro seconds + .tv_usec = 30000 // 30000 micro seconds }; serial_port uart_open(const char* pcPortName) @@ -89,6 +89,10 @@ serial_port uart_open(const char* pcPortName) char *colon = strrchr(addrstr, ':'); char *portstr; + + // Set time-out to 300 miliseconds only for TCP port + timeout.tv_usec = 300000; + if (colon) { portstr = colon + 1; *colon = '\0'; From 4ea05fc026a5bc92f6f92c057b21da24f9323320 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Feb 2019 15:56:45 +0100 Subject: [PATCH 162/320] Fix: 'hf mf fchk' - now reports back correct found keys. --- CHANGELOG.md | 2 ++ armsrc/mifarecmd.c | 20 ++++++++++++-------- client/mifarehost.c | 21 +++++++++++---------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c7adf3a6..69078a1f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] + - Fix 'hf mf fchk' (@iceman) + - Fix 'usb slow on posix based systems' (@fl0-0) - Change 'lf pcf7931' - improved read code (@sguerrini97) - Change 'hf felica list' - started with some FeliCa annotations (@iceman) - Fix 'hf tune' - now works as expected (@iceman) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3e1967b4e..6b10ddd0d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1259,7 +1259,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da LED_A_ON(); if ( firstchunk ) { - clear_trace(); set_tracing(false); @@ -1458,26 +1457,31 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da } // end loop sectors } // end loop keys } // end loop strategy 2 -OUT: +OUT: LEDsoff(); crypto1_destroy(pcs); // All keys found, send to client, or last keychunk from client if (foundkeys == allkeys || lastchunk ) { - + uint64_t foo = 0; + for (uint8_t m = 0; m < 64; m++) { + foo |= ((uint64_t)(found[m] & 1) << m); + } + uint16_t bar = 0; - for (uint8_t m = 0; m < 64; ++m) - foo |= (found[m] << m); - for (uint8_t m=64; m < sizeof(found); ++m) - bar |= (found[m] << (m-64)); - + uint8_t j = 0; + for (uint8_t m=64; m < sizeof(found); m++) { + bar |= ((uint16_t)(found[m] & 1) << j++); + } + uint8_t *tmp = BigBuf_malloc(480+10); memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) ); num_to_bytes(foo, 8, tmp+480); tmp[488] = bar & 0xFF; tmp[489] = bar >> 8 & 0xFF; + cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10); set_tracing(false); diff --git a/client/mifarehost.c b/client/mifarehost.c index 0f37f8a8b..31ed8e39d 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -173,18 +173,19 @@ int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // success array. each byte is status of key uint8_t arr[80]; - uint64_t foo = bytes_to_num(resp.d.asBytes+480, 8); - for (uint8_t i = 0; i < 64; ++i) { - arr[i] = (foo >> i) & 0x1; - } - foo = bytes_to_num(resp.d.asBytes+488, 2); - for (uint8_t i = 0; i < 16; ++i) { - arr[i+64] = (foo >> i) & 0x1; - } + uint64_t foo = 0; + uint16_t bar = 0; + foo = bytes_to_num(resp.d.asBytes+480, 8); + bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]); + for (uint8_t i = 0; i < 64; i++) + arr[i] = (foo >> i) & 0x1; + + for (uint8_t i = 0; i < 16; i++) + arr[i+64] = (bar >> i) & 0x1; + // initialize storage for found keys - icesector_t *tmp = NULL; - tmp = calloc(sectorsCnt, sizeof(icesector_t)); + icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); if (tmp == NULL) return 1; memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) ); From d6063d677685725490454b0be39400fec3ae73f6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Feb 2019 16:07:31 +0100 Subject: [PATCH 163/320] textual --- README.md | 9 ++++++++- tools/Makefile | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index effdc0f6e..c8c04f852 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,14 @@ This fork now compiles just fine on ## KALI and ARCHLINUX users Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly. -`sudo apt remove modemmanager` +```sh +sudo apt remove modemmanager +``` +or +```sh +systemctl stop ModemManager +systemctl disable ModemManager +``` ## Setup and build for UBUNTU GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04 diff --git a/tools/Makefile b/tools/Makefile index c750cce26..b72503158 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -11,4 +11,9 @@ get_nonce_bf: git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute get_xorsearch: - wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip \ No newline at end of file + mkdir xorsearch + wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip +# Mingw +# unzzip-big XORSearch_V1_11_2.zip +# linux +# gunzip XORSearch_V1_11_2.zip \ No newline at end of file From f80aaa13abc45f081459ee43e167989097bba039 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Feb 2019 16:09:02 +0100 Subject: [PATCH 164/320] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69078a1f7..44a6fc2d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - Fix 'hf mf fchk' (@iceman) - Fix 'usb slow on posix based systems' (@fl0-0) - Change 'lf pcf7931' - improved read code (@sguerrini97) From e23d53adc13b1626fcbab13e0b8ac6b7dfd1b46f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Feb 2019 16:48:14 +0100 Subject: [PATCH 165/320] chg: 'hf mf hardnested' - speedup for those with good cpus, triggering the bruteforce faster. --- client/cmdhfmfhard.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 3547761a5..4818f480f 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1038,8 +1038,11 @@ static bool shrink_key_space(float *brute_forces) } *brute_forces = MIN(brute_forces1, brute_forces2); float reduction_rate = update_reduction_rate(*brute_forces, false); - return ((hardnested_stage & CHECK_2ND_BYTES) - && reduction_rate >= 0.0 && reduction_rate < brute_force_per_second * sample_period / 1000.0); + +//iceman 2018 + return ((hardnested_stage & CHECK_2ND_BYTES) && + reduction_rate >= 0.0 && + ( reduction_rate < brute_force_per_second * (float)sample_period / 1000.0 || *brute_forces < 0x1F000000000)); } From f943348a7b5d5a6c1ab05a09bc8e2106a6d9789e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 10:18:55 +0100 Subject: [PATCH 166/320] FIX: detection of presence of git on system. ie downloaded a zip file with everything or precompiled distro may not have git installed. On ubuntu/mingw 'env -S' doesn't exist. --- tools/mkversion.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkversion.pl b/tools/mkversion.pl index 1acca6efa..674c44177 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -28,7 +28,7 @@ my $clean = 2; # fatal: No names found, cannot describe anything. ## # anyway forcing any kind of shell is at least useless, at worst fatal. -my $commandGIT = "env -S which git"; +my $commandGIT = "env which git"; if ( defined($commandGIT) ) { From 7e601e5285ac7a45bfb94804dbfa7a719d06bcab Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 10:27:14 +0100 Subject: [PATCH 167/320] chg: textual --- client/cmdhfmf.c | 2 +- client/cmdhw.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 8129aceb6..c5c4ab1d5 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1834,7 +1834,7 @@ int CmdHF14AMfChk(const char *Cmd) { } if (keycnt == 0) { - PrintAndLogEx(NORMAL, "No key specified, trying default keys"); + PrintAndLogEx(INFO, "No key specified, trying default keys"); for (;keycnt < MIFARE_DEFAULTKEYS_SIZE; keycnt++) PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], diff --git a/client/cmdhw.c b/client/cmdhw.c index a93a940cc..ec7b42a1a 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -257,9 +257,9 @@ int CmdVersion(const char *Cmd) { SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { #ifdef __WIN32 - PrintAndLogEx(NORMAL, "\nProxmark3 RFID instrument\n"); + PrintAndLogEx(NORMAL, "\n [ Proxmark3 RFID instrument ]\n"); #else - PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n"); + PrintAndLogEx(NORMAL, "\n\e[34m [ Proxmark3 RFID instrument ]\e[0m\n"); #endif char s[50] = {0}; #if defined(WITH_FLASH) || defined(WITH_SMARTCARD) || defined(WITH_FPC) @@ -275,7 +275,7 @@ int CmdVersion(const char *Cmd) { strncat(s, "fpc; ", sizeof(s) - strlen(s) - 1); #endif PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); - PrintAndLogEx(NORMAL, " client: iceman %s \n", s); + PrintAndLogEx(NORMAL, " client: iceman %s \n", s); PrintAndLogEx(NORMAL, (char*)resp.d.asBytes); lookupChipID(resp.arg[0], resp.arg[1]); From cacba04959347743d842f531977c448ffd97646f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 10:38:49 +0100 Subject: [PATCH 168/320] chg: 'hf mf fchk' - better handling when no keys was found. --- client/cmdhfmf.c | 86 ++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c5c4ab1d5..58a190f8c 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1649,47 +1649,63 @@ out: t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0)); - printKeyTable( sectorsCnt, e_sector ); - - if (transferToEml) { - uint8_t block[16] = {0x00}; - for (uint8_t i = 0; i < sectorsCnt; ++i ) { - mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); - if (e_sector[i].foundKey[0]) - num_to_bytes(e_sector[i].Key[0], 6, block); - if (e_sector[i].foundKey[1]) - num_to_bytes(e_sector[i].Key[1], 6, block+10); - mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); - } - PrintAndLogEx(NORMAL, "Found keys have been transferred to the emulator memory"); + // check.. + uint8_t found_keys = 0; + for (uint8_t i = 0; i < sectorsCnt; ++i) { + + if ( e_sector[i].foundKey[0] ) + found_keys++; + + if ( e_sector[i].foundKey[1] ) + found_keys++; } - if (createDumpFile) { - fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) - return 1; - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s", fptr); - free(keyBlock); - free(e_sector); - return 1; - } - PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr); + if ( found_keys == 0 ) { + PrintAndLogEx(WARNING, "No keys found"); + } else { - for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + FILE *fkeys = fopen(fptr, "wb"); + if (fkeys == NULL) { + PrintAndLogEx(WARNING, "Could not create file %s", fptr); + free(keyBlock); + free(e_sector); + return 1; + } + PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr); + + for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + } } free(keyBlock); From 06fc95b62d74b89a0df6abf555d714f079dcd167 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 10:41:54 +0100 Subject: [PATCH 169/320] chg: 'hf mf fchk' - textual --- client/cmdhfmf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 58a190f8c..03ac49c3d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1676,7 +1676,7 @@ out: num_to_bytes(e_sector[i].Key[1], 6, block+10); mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); } - PrintAndLogEx(NORMAL, "Found keys have been transferred to the emulator memory"); + PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } if (createDumpFile) { @@ -1691,7 +1691,7 @@ out: free(e_sector); return 1; } - PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr); + PrintAndLogEx(SUCCESS, "Printing keys to binary file %s...", fptr); for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + PrintAndLogEx(SUCCESS, "Found keys have been dumped to %s --> 0xffffffffffff has been inserted for unknown keys.", fptr); } } From 20ccfb036c2a6bc3b5ba40cdf9c394e52b0e4f47 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 13:12:25 +0100 Subject: [PATCH 170/320] chg: more colors --- client/loclass/fileutils.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 5bac3d2cd..0751f838b 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -71,14 +71,14 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si /*Opening file for writing in binary mode*/ FILE *f = fopen(fileName, "wb"); if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); free(fileName); return 1; } fwrite(data, 1, datalen, f); fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file %s", datalen, fileName); + PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file " _YELLOW_(%s), datalen, fileName); free(fileName); return 0; } @@ -106,8 +106,8 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si /*Opening file for writing in text mode*/ FILE *f = fopen(fileName, "w+"); - if (!f) { - PrintAndLogDevice(WARNING, "file not found or locked. '%s'", fileName); + if (!f) { + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -130,7 +130,7 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, si } fflush(f); fclose(f); - PrintAndLogDevice(SUCCESS, "saved %d blocks to text file %s", blocks, fileName); + PrintAndLogDevice(SUCCESS, "saved %d blocks to text file " _YELLOW_(%s), blocks, fileName); out: free(fileName); @@ -240,13 +240,12 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty int res = json_dump_file(root, fileName, JSON_INDENT(2)); if (res) { - PrintAndLogDevice(FAILED, "error: can't save the file: %s", fileName); + PrintAndLogDevice(FAILED, "error: can't save the file: " _YELLOW_(%s), fileName); json_decref(root); retval = 200; goto out; } - PrintAndLogDevice(SUCCESS, "File `%s` saved.", fileName); - + PrintAndLogDevice(SUCCESS, "File `" _YELLOW_(%s)"` saved.", fileName); json_decref(root); out: @@ -266,7 +265,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* FILE *f = fopen(fileName, "rb"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -305,7 +304,7 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* memcpy( (data), dump, bytes_read); free(dump); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file %s", bytes_read, fileName); + PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file " _YELLOW_(%s), bytes_read, fileName); *datalen = bytes_read; @@ -328,7 +327,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ FILE *f = fopen(fileName, "r"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -359,7 +358,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ } } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file %s", counter, fileName); + PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_(%s), counter, fileName); *datalen = counter; out: @@ -382,13 +381,13 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size root = json_load_file(fileName, 0, &error); if (!root) { - PrintAndLog("ERROR: json (%s) error on line %d: %s", fileName, error.line, error.text); + PrintAndLog("ERROR: json " _YELLOW_(%s) " error on line %d: %s", fileName, error.line, error.text); retval = 2; goto out; } if (!json_is_object(root)) { - PrintAndLog("ERROR: Invalid json (%s) format. root must be an object.", fileName); + PrintAndLog("ERROR: Invalid json " _YELLOW_(%s) " format. root must be an object.", fileName); retval = 3; goto out; } @@ -446,7 +445,7 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size } - PrintAndLog("Loaded JSON: (%s) OK.", fileName); + PrintAndLog("Loaded JSON: " _YELLOW_(%s) " OK.", fileName); out: json_decref(root); free(fileName); @@ -479,7 +478,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data FILE *f = fopen(fileName, "r"); if ( !f ) { - PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName); + PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); retval = 1; goto out; } @@ -512,7 +511,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data counter += (keylen >> 1); } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file %s", *keycnt, fileName); + PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file " _YELLOW_(%s), *keycnt, fileName); *datalen = counter; out: free(fileName); From e6c68645e378a1dc73a7faa3afcaa5a62624ab19 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 13:28:22 +0100 Subject: [PATCH 171/320] chg: colors --- client/cmdhf15.c | 30 ++++++++++++------------ client/cmdhflegic.c | 2 +- client/cmdhfmfu.c | 56 ++++++++++++++++++++++----------------------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index a1b55d7c6..41d6ee8cd 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -519,21 +519,21 @@ int CmdHF15Info(const char *Cmd) { SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { - PrintAndLogEx(NORMAL, "iso15693 card select failed"); + PrintAndLogEx(WARNING, "iso15693 card select failed"); return 1; } uint32_t status = resp.arg[0]; if ( status < 2 ) { - PrintAndLogEx(NORMAL, "iso15693 card doesn't answer to systeminfo command"); + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command"); return 1; } recv = resp.d.asBytes; if ( recv[0] & ISO15_RES_ERROR ) { - PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + PrintAndLogEx(WARNING, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); return 3; } @@ -575,8 +575,8 @@ int CmdHF15Info(const char *Cmd) { // Record Activity without enabeling carrier //helptext int CmdHF15Record(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_record(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_record(); UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693, {0,0,0}}; clearCommandBuffer(); @@ -598,8 +598,8 @@ int HF15Reader(const char *Cmd, bool verbose) { } int CmdHF15Reader(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_reader(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_reader(); HF15Reader(Cmd, true); return 0; @@ -608,16 +608,16 @@ int CmdHF15Reader(const char *Cmd) { // Simulation is still not working very good // helptext int CmdHF15Sim(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_sim(); + char cmdp =tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim(); uint8_t uid[8] = {0,0,0,0,0,0,0,0}; if (param_gethex(Cmd, 0, uid, 16)) { - PrintAndLogEx(NORMAL, "UID must include 16 HEX symbols"); + PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); return 0; } - PrintAndLogEx(NORMAL, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) ); + PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid)) ); UsbCommand c = {CMD_SIMTAG_ISO_15693, {0, 0, 0}}; memcpy(c.d.asBytes, uid, 8); @@ -630,10 +630,10 @@ int CmdHF15Sim(const char *Cmd) { // (There is no standard way of reading the AFI, allthough some tags support this) // helptext int CmdHF15Afi(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_15_findafi(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_15_findafi(); - PrintAndLogEx(NORMAL, "press pm3-button to cancel"); + PrintAndLogEx(SUCCESS, "press pm3-button to cancel"); UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}}; clearCommandBuffer(); @@ -689,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) { } // detect blocksize from card :) - PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(NORMAL, "Reading memory from tag UID " _YELLOW_(%s), sprintUID(NULL, uid)); int blocknum = 0; uint8_t *recv = NULL; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 1403060e5..8c4ef411c 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -180,7 +180,7 @@ int CmdLegicInfo(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "Reading tag memory %d b...", card.cardsize); + PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", card.cardsize); // allocate receiver buffer uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index b5be04593..0a7e77b1c 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -518,57 +518,57 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces){ char *spacer = spc + (10-spaces); if ( tagtype & UL ) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else if ( tagtype & UL_C) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else if ( tagtype & UL_NANO_40) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight Nano 40bytes (MF0UNH00)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight Nano 40bytes (MF0UNH00)", spacer); else if ( tagtype & UL_EV1_48) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); else if ( tagtype & UL_EV1_128) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); else if ( tagtype & UL_EV1 ) - PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 UNKNOWN", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 UNKNOWN", spacer); else if ( tagtype & NTAG ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG UNKNOWN", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG UNKNOWN", spacer); else if ( tagtype & NTAG_203 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); else if ( tagtype & NTAG_210 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); else if ( tagtype & NTAG_212 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); else if ( tagtype & NTAG_213 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); else if ( tagtype & NTAG_213_F ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213F 144bytes (NT2H1311F0DTL)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 213F 144bytes (NT2H1311F0DTL)", spacer); else if ( tagtype & NTAG_215 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); else if ( tagtype & NTAG_216 ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); else if ( tagtype & NTAG_216_F ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); else if ( tagtype & NTAG_I2C_1K ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD"); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_2K ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_1K_PLUS ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 888bytes (NT3H2111FHK)", spacer, "\xFD"); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC plus 888bytes (NT3H2111FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_2K_PLUS ) - PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 1912bytes (NT3H2211FHK)", spacer, "\xFD"); + PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC plus 1912bytes (NT3H2211FHK)", spacer, "\xFD"); else if ( tagtype & MY_D ) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); else if ( tagtype & MY_D_NFC ) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); else if ( tagtype & MY_D_MOVE ) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); else if ( tagtype & MY_D_MOVE_NFC ) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); else if ( tagtype & MY_D_MOVE_LEAN ) - PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); + PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); else if ( tagtype & FUDAN_UL ) - PrintAndLogEx(NORMAL, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(SUCCESS, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else - PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); + PrintAndLogEx(SUCCESS, "%sTYPE : Unknown %06x", spacer, tagtype); return 0; } @@ -606,7 +606,7 @@ static int ulc_print_configuration( uint8_t *data){ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage){ - PrintAndLogEx(NORMAL, "\n--- Tag Configuration"); + PrintAndLogEx(SUCCESS, "\n--- Tag Configuration"); bool strg_mod_en = (data[0] & 2); uint8_t authlim = (data[4] & 0x07); @@ -1743,7 +1743,7 @@ int CmdHF14AMfUDump(const char *Cmd){ } } ul_print_type(tagtype, 0); - PrintAndLogEx(NORMAL, "Reading tag memory..."); + PrintAndLogEx(SUCCESS, "Reading tag memory..."); UsbCommand c = {CMD_MIFAREU_READCARD, {startPage, pages}}; if ( hasAuthKey ) { if (tagtype & UL_C) From 23d0b6b1c64c00e9ae4854aa4d619cbf47f8b04b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 14:59:19 +0100 Subject: [PATCH 172/320] chg: colors --- client/cmdhfmf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 03ac49c3d..db2f2b495 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1691,7 +1691,7 @@ out: free(e_sector); return 1; } - PrintAndLogEx(SUCCESS, "Printing keys to binary file %s...", fptr); + PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_(%s)"...", fptr); for (i=0; i 0xffffffffffff has been inserted for unknown keys.", fptr); + PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_(%s)" --> 0xffffffffffff has been inserted for unknown keys.", fptr); } } @@ -1964,7 +1964,7 @@ out: num_to_bytes(e_sector[i].Key[1], 6, block+10); mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); } - PrintAndLogEx(NORMAL, "Found keys have been transferred to the emulator memory"); + PrintAndLogEx(INFO, "Found keys have been transferred to the emulator memory"); } if (createDumpFile) { @@ -1979,7 +1979,7 @@ out: free(e_sector); return 1; } - PrintAndLogEx(NORMAL, "Printing keys to binary file %s...", fptr); + PrintAndLogEx(INFO, "Printing keys to binary file " _YELLOW_(%s)"...", fptr); for( i=0; i Date: Mon, 18 Feb 2019 15:37:26 +0100 Subject: [PATCH 173/320] chg: more colors --- client/cmdhfmf.c | 62 ++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index db2f2b495..691c8678e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -734,7 +734,7 @@ int CmdHF14AMfDump(const char *Cmd) { } if ((fin = fopen(keyFilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", keyFilename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename); return 1; } @@ -743,7 +743,7 @@ int CmdHF14AMfDump(const char *Cmd) { for (sectorNo=0; sectorNo Date: Mon, 18 Feb 2019 15:47:48 +0100 Subject: [PATCH 174/320] chg: colors --- client/cmdhfmf.c | 74 +++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 691c8678e..e9b1bed10 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -945,7 +945,7 @@ int CmdHF14AMfRestore(const char *Cmd) { } if ((fkeys = fopen(keyFilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", keyFilename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename); return 1; } @@ -979,10 +979,10 @@ int CmdHF14AMfRestore(const char *Cmd) { } if ((fdump = fopen(dataFilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", dataFilename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), dataFilename); return 1; } - PrintAndLogEx(INFO, "Restoring %s to card", dataFilename); + PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", dataFilename); for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { @@ -1561,7 +1561,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) { if( buf[0]=='#' ) continue; //The line start with # is comment, skip if (!isxdigit(buf[0])){ - PrintAndLogEx(FAILED, "File content error. '%s' must include 12 HEX symbols", buf); + PrintAndLogEx(FAILED, "File content error. '" _YELLOW_(%s)"' must include 12 HEX symbols", buf); continue; } @@ -1622,7 +1622,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) { if (ukbhit()) { int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); goto out; } @@ -1686,7 +1686,7 @@ out: FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s", fptr); + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr); free(keyBlock); free(e_sector); return 1; @@ -1750,23 +1750,21 @@ int CmdHF14AMfChk(const char *Cmd) { blockNo = param_get8(Cmd, 0); } - ctmp = param_getchar(Cmd, 1); + ctmp = tolower(param_getchar(Cmd, 1)); clen = param_getlength(Cmd, 1); if (clen == 1) { switch (ctmp) { case 'a': - case 'A': keyType = 0; break; case 'b': - case 'B': keyType = 1; break; case '?': keyType = 2; break; default: - PrintAndLogEx(NORMAL, "Key type must be A , B or ?"); + PrintAndLogEx(FAILED, "Key type must be A , B or ?"); free(keyBlock); return 1; }; @@ -1774,7 +1772,7 @@ int CmdHF14AMfChk(const char *Cmd) { for (i = 2; param_getchar(Cmd, i); i++) { - ctmp = param_getchar(Cmd, i); + ctmp = tolower(param_getchar(Cmd, i)); clen = param_getlength(Cmd, i); if (clen == 12) { @@ -1796,8 +1794,8 @@ int CmdHF14AMfChk(const char *Cmd) { PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex( (keyBlock + 6*keycnt), 6 ) );; keycnt++; } else if ( clen == 1 ) { - if (ctmp == 't' || ctmp == 'T') { transferToEml = 1; continue; } - if (ctmp == 'd' || ctmp == 'D') { createDumpFile = 1; continue; } + if (ctmp == 't' ) { transferToEml = 1; continue; } + if (ctmp == 'd' ) { createDumpFile = 1; continue; } } else { // May be a dic file if ( param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE ) { @@ -1822,7 +1820,7 @@ int CmdHF14AMfChk(const char *Cmd) { // codesmell, only checks first char? if (!isxdigit(buf[0])){ - PrintAndLogEx(FAILED, "File content error. '%s' must include 12 HEX symbols",buf); + PrintAndLogEx(FAILED, "File content error. '" _YELLOW_(%s)"' must include 12 HEX symbols",buf); continue; } @@ -1964,7 +1962,7 @@ out: num_to_bytes(e_sector[i].Key[1], 6, block+10); mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); } - PrintAndLogEx(INFO, "Found keys have been transferred to the emulator memory"); + PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); } if (createDumpFile) { @@ -1974,7 +1972,7 @@ out: FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s", fptr); + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s), fptr); free(keyBlock); free(e_sector); return 1; @@ -2039,7 +2037,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { uint8_t sector = data.sector; uint8_t keytype = data.keytype; - PrintAndLogEx(NORMAL, "Reader is trying authenticate with: Key %s, sector %02d: [%012" PRIx64 "]" + PrintAndLogEx(INFO, "Reader is trying authenticate with: Key %s, sector %02d: [%012" PRIx64 "]" , keytype ? "B" : "A" , sector , key @@ -2054,7 +2052,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { num_to_bytes( k_sector[sector].Key[0], 6, memBlock); num_to_bytes( k_sector[sector].Key[1], 6, memBlock+10); //iceman, guessing this will not work so well for 4K tags. - PrintAndLogEx(NORMAL, "Setting Emulator Memory Block %02d: [%s]" + PrintAndLogEx(INFO, "Setting Emulator Memory Block %02d: [%s]" , (sector*4) + 3 , sprint_hex( memBlock, sizeof(memBlock)) ); @@ -2129,7 +2127,7 @@ int CmdHF14AMf1kSim(const char *Cmd) { UsbCommand resp; if(flags & FLAG_INTERACTIVE) { - PrintAndLogEx(NORMAL, "Press pm3-button or send another cmd to abort simulation"); + PrintAndLogEx(INFO, "Press pm3-button or send another cmd to abort simulation"); while( !ukbhit() ){ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue; @@ -2165,8 +2163,8 @@ int CmdHF14AMfSniff(const char *Cmd){ memset(uid, 0x00, sizeof(uid)); - char ctmp = param_getchar(Cmd, 0); - if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if ( ctmp == 'h') return usage_hf14_sniff(); for (int i = 0; i < 4; i++) { ctmp = tolower(param_getchar(Cmd, i)); @@ -2193,7 +2191,7 @@ int CmdHF14AMfSniff(const char *Cmd){ printf("."); fflush(stdout); if (ukbhit()) { int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\n[!] aborted via keyboard!\n"); + PrintAndLogEx(INFO, "\naborted via keyboard!\n"); break; } @@ -2496,7 +2494,7 @@ int CmdHF14AMfELoad(const char *Cmd) { return 4; } } - PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: %s", blockNum, filename); + PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: " _YELLOW_(%s), blockNum, filename); return 0; } @@ -2804,8 +2802,8 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { int res; memset(data, 0x00, sizeof(data)); - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetblk(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetblk(); blockNo = param_get8(Cmd, 0); @@ -2840,8 +2838,8 @@ int CmdHF14AMfCGetSc(const char *Cmd) { uint8_t sector = 0; int i, res, flags; - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetsc(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_cgetsc(); sector = param_get8(Cmd, 0); if (sector > 39) { @@ -2979,8 +2977,8 @@ int CmdHF14AMfCSave(const char *Cmd) { //needs nt, ar, at, Data to decrypt int CmdHf14AMfDecryptBytes(const char *Cmd){ - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_decryptbytes(); + char ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_decryptbytes(); uint32_t nt = param_get32ex(Cmd,0,0,16); uint32_t ar_enc = param_get32ex(Cmd,1,0,16); @@ -3031,7 +3029,7 @@ int CmdHf14AMfSetMod(const char *Cmd) { UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t ok = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", ok); + PrintAndLogEx(SUCCESS, "isOk:%02x", ok); if (!ok) PrintAndLogEx(FAILED, "Failed."); } else { @@ -3044,12 +3042,12 @@ int CmdHf14AMfSetMod(const char *Cmd) { int CmdHf14AMfNack(const char *Cmd) { bool verbose = false; - char ctmp = param_getchar(Cmd, 0); - if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_nack(); - if ( ctmp == 'v' || ctmp == 'V' ) verbose = true; + char ctmp = tolower(param_getchar(Cmd, 0)); + if ( ctmp == 'h' ) return usage_hf14_nack(); + if ( ctmp == 'v' ) verbose = true; if ( verbose ) - PrintAndLogEx(NORMAL, "Started testing card for NACK bug. Press key to abort"); + PrintAndLogEx(INFO, "Started testing card for NACK bug. Press key to abort"); detect_classic_nackbug(verbose); return 0; @@ -3107,7 +3105,7 @@ int CmdHF14AMfice(const char *Cmd) { PrintAndLogEx(NORMAL, "Collecting %u nonces \n", limit); if ((fnonces = fopen(filename,"wb")) == NULL) { - PrintAndLogEx(WARNING, "Could not create file %s",filename); + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_(%s),filename); return 3; } @@ -3118,7 +3116,7 @@ int CmdHF14AMfice(const char *Cmd) { do { if (ukbhit()) { int gc = getchar(); (void)gc; - PrintAndLogEx(NORMAL, "\naborted via keyboard!\n"); + PrintAndLogEx(INFO, "\naborted via keyboard!\n"); break; } @@ -3140,7 +3138,7 @@ int CmdHF14AMfice(const char *Cmd) { total_num_nonces += items; if ( total_num_nonces > part_limit ) { - PrintAndLogEx(NORMAL, "Total nonces %u\n", total_num_nonces); + PrintAndLogEx(INFO, "Total nonces %u\n", total_num_nonces); part_limit += 3000; } @@ -3151,7 +3149,7 @@ int CmdHF14AMfice(const char *Cmd) { } while (!acquisition_completed); out: - PrintAndLogEx(NORMAL, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000); + PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock()-t1)/1000); if ( fnonces ) { fflush(fnonces); From 0997c558004593b255bf0e91393a4cfe7ef8d471 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:07:39 +0100 Subject: [PATCH 175/320] chg: colors --- client/cmdhfmfu.c | 61 +++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 0a7e77b1c..6f189fabb 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -980,11 +980,11 @@ int CmdHF14AMfUInfo(const char *Cmd){ if ( hasAuthKey ) return 1; // also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys - PrintAndLogEx(NORMAL, "Trying some default 3des keys"); + PrintAndLogEx(INFO, "Trying some default 3des keys"); for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) { key = default_3des_keys[i]; if (ulc_authentication(key, true)) { - PrintAndLogEx(NORMAL, "Found default 3des key: "); + PrintAndLogEx(SUCCESS, "Found default 3des key: "); uint8_t keySwap[16]; memcpy(keySwap, SwapEndian64(key,16,8), 16); ulc_print_3deskey(keySwap); @@ -1079,7 +1079,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1089,7 +1089,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1099,7 +1099,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1109,7 +1109,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ num_to_bytes( ul_ev1_pwdgenD(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); goto out; } @@ -1119,13 +1119,13 @@ int CmdHF14AMfUInfo(const char *Cmd){ key = default_pwd_pack[i]; len = ulev1_requestAuthentication(key, pack, sizeof(pack)); if (len > -1) { - PrintAndLogEx(NORMAL, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); + PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); break; } else { if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } } - if (len < 1) PrintAndLogEx(NORMAL, "password not known"); + if (len < 1) PrintAndLogEx(WARNING, "password not known"); } } out: @@ -1250,7 +1250,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){ UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); + PrintAndLogEx(SUCCESS, "isOk:%02x", isOK); } else { PrintAndLogEx(WARNING, "Command execute timeout"); } @@ -1365,7 +1365,7 @@ int CmdHF14AMfURdBl(const char *Cmd){ PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK); } } else { - PrintAndLogEx(NORMAL, "Command execute time-out"); + PrintAndLogEx(WARNING, "Command execute time-out"); } return 0; } @@ -1912,12 +1912,10 @@ int CmdHF14AMfURestore(const char *Cmd){ memset(authkey, 0x00, sizeof(authkey)); while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_hf_mfu_restore(); case 'k': - case 'K': keylen = param_getstr(Cmd, cmdp+1, tempStr, sizeof(tempStr)); if (keylen == 32 || keylen == 8) { //ul-c or ev1/ntag key length errors = param_gethex(tempStr, 0, authkey, keylen); @@ -1930,12 +1928,10 @@ int CmdHF14AMfURestore(const char *Cmd){ hasKey = true; break; case 'l': - case 'L': swapEndian = true; cmdp++; break; case 'f': - case 'F': filelen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); if (filelen > FILE_PATH_SIZE-5) @@ -1947,17 +1943,14 @@ int CmdHF14AMfURestore(const char *Cmd){ cmdp += 2; break; case 's': - case 'S': cmdp++; write_special = true; break; case 'e': - case 'E': cmdp++; write_extra = true; break; case 'r': - case 'R': cmdp++; read_key = true; break; @@ -1972,7 +1965,7 @@ int CmdHF14AMfURestore(const char *Cmd){ if (errors || cmdp == 0) return usage_hf_mfu_restore(); if ((f = fopen(filename,"rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file %s", filename); + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), filename); return 1; } @@ -2000,7 +1993,7 @@ int CmdHF14AMfURestore(const char *Cmd){ return 1; } - PrintAndLogEx(NORMAL, "Restoring %s to card", filename); + PrintAndLogEx(INFO, "Restoring " _YELLOW_(%s)" to card", filename); mfu_dump_t *mem = (mfu_dump_t*)dump; uint8_t pages = (bytes_read-48)/4; @@ -2084,7 +2077,7 @@ int CmdHF14AMfURestore(const char *Cmd){ } } - PrintAndLogEx(NORMAL, "Restoring data blocks."); + PrintAndLogEx(INFO, "Restoring data blocks."); // write all other data // Skip block 0,1,2,3 (only magic tags can write to them) // Skip last 5 blocks usually is configuration @@ -2103,7 +2096,7 @@ int CmdHF14AMfURestore(const char *Cmd){ // write special data last if (write_special) { - PrintAndLogEx(NORMAL, "Restoring configuration blocks.\n"); + PrintAndLogEx(INFO, "Restoring configuration blocks.\n"); PrintAndLogEx(NORMAL, "authentication with keytype[%x] %s\n", (uint8_t)(c.arg[1] & 0xff), sprint_hex(p_authkey,4)); @@ -2128,16 +2121,16 @@ int CmdHF14AMfURestore(const char *Cmd){ // Load emulator with dump file // int CmdHF14AMfUeLoad(const char *Cmd){ - char c = param_getchar(Cmd, 0); - if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_eload(); + char c = tolower(param_getchar(Cmd, 0)); + if ( c == 'h' || c == 0x00) return usage_hf_mfu_eload(); return CmdHF14AMfELoad(Cmd); } // // Simulate tag // int CmdHF14AMfUSim(const char *Cmd){ - char c = param_getchar(Cmd, 0); - if ( c == 'h' || c == 'H' || c == 0x00) return usage_hf_mfu_sim(); + char c = tolower(param_getchar(Cmd, 0)); + if ( c == 'h' || c == 0x00) return usage_hf_mfu_sim(); return CmdHF14ASim(Cmd); } @@ -2153,16 +2146,16 @@ int CmdHF14AMfucAuth(const char *Cmd){ uint8_t keyNo = 3; bool errors = false; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); //Change key to user defined one - if (cmdp == 'k' || cmdp == 'K'){ + if (cmdp == 'k'){ keyNo = param_get8(Cmd, 1); if(keyNo >= KEYS_3DES_COUNT) errors = true; } - if (cmdp == 'h' || cmdp == 'H') errors = true; + if (cmdp == 'h') errors = true; if (errors) return usage_hf_mfu_ucauth(); @@ -2278,9 +2271,9 @@ int CmdTestDES(const char * cmd) int CmdHF14AMfucSetPwd(const char *Cmd){ uint8_t pwd[16] = {0x00}; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd(); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetpwd(); if (param_gethex(Cmd, 0, pwd, 32)) { PrintAndLogEx(WARNING, "Password must include 32 HEX symbols"); @@ -2295,7 +2288,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){ UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { if ( (resp.arg[0] & 0xff) == 1) { - PrintAndLogEx(NORMAL, "Ultralight-C new password: %s", sprint_hex(pwd,16)); + PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd,16)); } else { PrintAndLogEx(WARNING, "Failed writing at block %d", resp.arg[1] & 0xff); return 1; @@ -2315,9 +2308,9 @@ int CmdHF14AMfucSetUid(const char *Cmd){ UsbCommand c = {CMD_MIFAREU_READBL}; UsbCommand resp; uint8_t uid[7] = {0x00}; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid(); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_ucsetuid(); if (param_gethex(Cmd, 0, uid, 14)) { PrintAndLogEx(WARNING, "UID must include 14 HEX symbols"); From a4f6701c85a4e5f3e0438759c5854246938ff9b8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:16:24 +0100 Subject: [PATCH 176/320] chg: cleaning --- client/cmdhf15.c | 56 ++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 41d6ee8cd..2800b0c9c 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -764,7 +764,7 @@ int CmdHF15Dump(const char*Cmd) { } int CmdHF15Restore(const char*Cmd) { - FILE *file; + FILE *f; uint8_t uid[8]={0x00}; char filename[FILE_PATH_SIZE] = {0x00}; @@ -774,10 +774,10 @@ int CmdHF15Restore(const char*Cmd) { char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00}; char param[FILE_PATH_SIZE]=""; char hex[255]=""; - uint8_t retries = 3, tried = 0; + uint8_t retries = 3, tried = 0, i = 0; int retval=0; size_t bytes_read; - uint8_t i=0; + while(param_getchar(Cmd, cmdp) != 0x00) { switch(tolower(param_getchar(Cmd, cmdp))) { case '-': @@ -785,7 +785,8 @@ int CmdHF15Restore(const char*Cmd) { switch(param[1]) { case '2': - case 'o': strncpy(newCmdPrefix, " ",sizeof(newCmdPrefix)-1); + case 'o': + strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix)-1); strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1); break; default: @@ -815,18 +816,18 @@ int CmdHF15Restore(const char*Cmd) { default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); return usage_15_restore(); - break; } cmdp++; } + PrintAndLogEx(INFO,"Blocksize: %u",blocksize); - if(filename[0]=='\0') - { + + if ( !strlen(filename)) { PrintAndLogEx(WARNING,"Please provide a filename"); - return 1; + return usage_15_restore(); } - if ((file = fopen(filename,"rb")) == NULL) { + if ((f = fopen(filename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file %s", filename); return 2; } @@ -835,40 +836,43 @@ int CmdHF15Restore(const char*Cmd) { PrintAndLogEx(WARNING, "No tag found"); return 3; } + while (1) { - tried=0; - hex[0]=0x00; - tmpCmd[0]=0x00; + tried = 0; + hex[0] = 0x00; + tmpCmd[0] = 0x00; - bytes_read = fread( buff, 1, blocksize, file ); + bytes_read = fread( buff, 1, blocksize, f ); if ( bytes_read == 0) { - PrintAndLogEx(SUCCESS, "File reading done (%s).", filename); - fclose(file); + PrintAndLogEx(SUCCESS, "File reading done `%s`", filename); + fclose(f); return 0; - } - else if ( bytes_read != blocksize) { + } else if ( bytes_read != blocksize) { PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); - fclose(file); + fclose(f); return 2; } - for(int j=0;j= retries) return retval; + i++; } - fclose(file); + fclose(f); } int CmdHF15List(const char *Cmd) { From 5ec82a0dc4499cc7daf4f975a10757ca0c640015 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:27:56 +0100 Subject: [PATCH 177/320] chg: adjustments --- client/cmdhfmfu.c | 54 +++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 6f189fabb..e583f7f02 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -518,57 +518,57 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces){ char *spacer = spc + (10-spaces); if ( tagtype & UL ) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else if ( tagtype & UL_C) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else if ( tagtype & UL_NANO_40) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight Nano 40bytes (MF0UNH00)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight Nano 40bytes (MF0UNH00)", spacer); else if ( tagtype & UL_EV1_48) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); else if ( tagtype & UL_EV1_128) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); else if ( tagtype & UL_EV1 ) - PrintAndLogEx(SUCCESS, "%sTYPE : MIFARE Ultralight EV1 UNKNOWN", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : MIFARE Ultralight EV1 UNKNOWN", spacer); else if ( tagtype & NTAG ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG UNKNOWN", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG UNKNOWN", spacer); else if ( tagtype & NTAG_203 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); else if ( tagtype & NTAG_210 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); else if ( tagtype & NTAG_212 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); else if ( tagtype & NTAG_213 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); else if ( tagtype & NTAG_213_F ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 213F 144bytes (NT2H1311F0DTL)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 213F 144bytes (NT2H1311F0DTL)", spacer); else if ( tagtype & NTAG_215 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); else if ( tagtype & NTAG_216 ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); else if ( tagtype & NTAG_216_F ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG 216F 888bytes (NT2H1611F0DTL)", spacer); else if ( tagtype & NTAG_I2C_1K ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_2K ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_1K_PLUS ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC plus 888bytes (NT3H2111FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 888bytes (NT3H2111FHK)", spacer, "\xFD"); else if ( tagtype & NTAG_I2C_2K_PLUS ) - PrintAndLogEx(SUCCESS, "%sTYPE : NTAG I%sC plus 1912bytes (NT3H2211FHK)", spacer, "\xFD"); + PrintAndLogEx(NORMAL, "%sTYPE : NTAG I%sC plus 1912bytes (NT3H2211FHK)", spacer, "\xFD"); else if ( tagtype & MY_D ) - PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); else if ( tagtype & MY_D_NFC ) - PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); else if ( tagtype & MY_D_MOVE ) - PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); else if ( tagtype & MY_D_MOVE_NFC ) - PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); else if ( tagtype & MY_D_MOVE_LEAN ) - PrintAndLogEx(SUCCESS, "%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); + PrintAndLogEx(NORMAL, "%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); else if ( tagtype & FUDAN_UL ) - PrintAndLogEx(SUCCESS, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : "" ); + PrintAndLogEx(NORMAL, "%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "" : "" ); else - PrintAndLogEx(SUCCESS, "%sTYPE : Unknown %06x", spacer, tagtype); + PrintAndLogEx(NORMAL, "%sTYPE : Unknown %06x", spacer, tagtype); return 0; } @@ -606,7 +606,7 @@ static int ulc_print_configuration( uint8_t *data){ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage){ - PrintAndLogEx(SUCCESS, "\n--- Tag Configuration"); + PrintAndLogEx(NORMAL, "\n--- Tag Configuration"); bool strg_mod_en = (data[0] & 2); uint8_t authlim = (data[4] & 0x07); From 1e98c4621d5ea2ee97dcb2247b6c62fbdb2bdc91 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:30:57 +0100 Subject: [PATCH 178/320] chg: colors --- client/loclass/fileutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 0751f838b..6078ec4f9 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -245,7 +245,7 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty retval = 200; goto out; } - PrintAndLogDevice(SUCCESS, "File `" _YELLOW_(%s)"` saved.", fileName); + PrintAndLogDevice(SUCCESS, "Save to json file " _YELLOW_(%s), fileName); json_decref(root); out: @@ -445,7 +445,7 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size } - PrintAndLog("Loaded JSON: " _YELLOW_(%s) " OK.", fileName); + PrintAndLog("loaded from JSON file " _YELLOW_(%s), fileName); out: json_decref(root); free(fileName); From 58f35d50a628cf34977db08b659429db3e4bc10a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:32:13 +0100 Subject: [PATCH 179/320] chg: textual --- client/loclass/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 6078ec4f9..da91b21ec 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -245,7 +245,7 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty retval = 200; goto out; } - PrintAndLogDevice(SUCCESS, "Save to json file " _YELLOW_(%s), fileName); + PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_(%s), fileName); json_decref(root); out: From b320ebca7c03d8add91c3d65860fdcaf824103f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:39:39 +0100 Subject: [PATCH 180/320] chg: textual --- client/cmdhfmf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e9b1bed10..e2dc16efd 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------------- +1//----------------------------------------------------------------------------- // Copyright (C) 2011,2012 Merlok // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -1235,8 +1235,8 @@ int CmdHF14AMfNested(const char *Cmd) { if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]); mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); - PrintAndLogEx(SUCCESS, "key transferred to emulator memory."); - } + } + PrintAndLogEx(SUCCESS, "key transferred to emulator memory."); } // Create dump file From 72cf200df7b0d17f1f38117f71788fefea40edfe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Feb 2019 16:43:27 +0100 Subject: [PATCH 181/320] chg.... --- client/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e2dc16efd..47646852e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1,4 +1,4 @@ -1//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // Copyright (C) 2011,2012 Merlok // // This code is licensed to you under the terms of the GNU GPL, version 2 or, From 26bca369292dc7cb6ae39762555c4bbf6e250ff1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 19 Feb 2019 18:39:05 +0200 Subject: [PATCH 182/320] delete comment --- client/emv/emvcore.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/emv/emvcore.c b/client/emv/emvcore.c index 6ccee471c..7af08690c 100644 --- a/client/emv/emvcore.c +++ b/client/emv/emvcore.c @@ -263,7 +263,6 @@ int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool LeaveField break; case ECC_CONTACT: #ifdef WITH_SMARTCARD - //int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); res = ExchangeAPDUSC(data, (IncludeLe?6:5) + apdu.Lc, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); #else res = 1; From 56c9bcc03a6d4c42e3aea902eb5d7d3c7bfb8651 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 19 Feb 2019 21:15:54 +0200 Subject: [PATCH 183/320] added IAD decoding and some improvements --- client/emv/cmdemv.c | 75 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index d0015ac38..477062d38 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1212,16 +1212,79 @@ int CmdEMVExec(const char *cmd) { if ((CID & EMVAC_AC_MASK) == EMVAC_ARQC) PrintAndLogEx(INFO, "AC1 result: ARQC (Online authorisation requested)"); if ((CID & EMVAC_AC_MASK) == EMVAC_AC_MASK) PrintAndLogEx(INFO, "AC1 result: RFU"); - PrintAndLogEx(NORMAL, "\n* * Processing online request\n"); + // decode Issuer Application Data (IAD) + uint8_t CryptoVersion = 0; + const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9f10, NULL); + if (IAD && (IAD->len > 1)) { + PrintAndLogEx(NORMAL, "\n* * Issuer Application Data (IAD):"); + uint8_t VDDlen = IAD->value[0]; // Visa discretionary data length + uint8_t IDDlen = 0; // Issuer discretionary data length + PrintAndLogEx(NORMAL, "IAD length: %d", IAD->len); + PrintAndLogEx(NORMAL, "VDDlen: %d", VDDlen); + if (VDDlen < IAD->len - 1) + IDDlen = IAD->value[VDDlen + 1]; + PrintAndLogEx(NORMAL, "IDDlen: %d", IDDlen); + + uint8_t DerivKeyIndex = IAD->value[1]; + CryptoVersion = IAD->value[2]; + + PrintAndLogEx(NORMAL, "CryptoVersion: %d", CryptoVersion); + PrintAndLogEx(NORMAL, "DerivKeyIndex: %d", DerivKeyIndex); + + // Card Verification Results (CVR) decode + if ((VDDlen - 2) > 0) { + uint8_t CVRlen = IAD->value[3]; + if (CVRlen == (VDDlen - 2 - 1)) { + PrintAndLogEx(NORMAL, "CVR length: %d", CVRlen); + PrintAndLogEx(NORMAL, "CVR: %s", sprint_hex(&IAD->value[4], CVRlen)); + } else { + PrintAndLogEx(NORMAL, "Wrong CVR length! CVR: %s", sprint_hex(&IAD->value[3], VDDlen - 2)); + } + } + if (IDDlen) + PrintAndLogEx(NORMAL, "IDD: %s", sprint_hex(&IAD->value[VDDlen + 1], IDDlen)); + } else { + PrintAndLogEx(NORMAL, "Issuer Application Data (IAD) not found."); + } + + PrintAndLogEx(NORMAL, "\n* * Processing online request"); // authorization response code from acquirer const char HostResponse[] = "00"; // 0x3030 - PrintAndLogEx(NORMAL, "* * Host Response: `%s`", HostResponse); - tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse); + size_t HostResponseLen = sizeof(HostResponse) - 1; + PrintAndLogEx(NORMAL, "Host Response: `%s`", HostResponse); + tlvdb_change_or_add_node(tlvRoot, 0x8a, HostResponseLen, (const unsigned char *)HostResponse); + if (CryptoVersion == 10) { + PrintAndLogEx(NORMAL, "\n* * Generate ARPC"); + + // Application Cryptogram (AC) + const struct tlv *AC = tlvdb_get(tlvRoot, 0x9f26, NULL); + if (AC && (AC->len > 0)) { + PrintAndLogEx(NORMAL, "AC: %s", sprint_hex(AC->value, AC->len)); + + size_t rawARPClen = AC->len; + uint8_t rawARPC[rawARPClen]; + memcpy(rawARPC, AC->value, AC->len); + for (int i = 0; (i < HostResponseLen) && (i < rawARPClen); i++) + rawARPC[i] ^= HostResponse[i]; + PrintAndLogEx(NORMAL, "raw ARPC: %s", sprint_hex(rawARPC, rawARPClen)); + + // here must be calculation of ARPC, but we dont know a bank keys. + PrintAndLogEx(NORMAL, "ARPC: n/a"); + + } else { + PrintAndLogEx(NORMAL, "Application Cryptogram (AC) not found."); + } + + // here must be external authenticate, but we dont know ARPC + + } + + // needs to send AC2 command (res == ARQC) if ((CID & 0xc0) == 0x80) { - PrintAndLogEx(NORMAL, "* * Calc CDOL2"); + PrintAndLogEx(NORMAL, "\n* * Calc CDOL2"); struct tlv *cdol2_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag if (!cdol2_data_tlv) { PrintAndLogEx(WARNING, "Error: can't create CDOL2 TLV."); @@ -1230,9 +1293,11 @@ int CmdEMVExec(const char *cmd) { PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol2_data_tlv->len, sprint_hex(cdol2_data_tlv->value, cdol2_data_tlv->len)); - PrintAndLogEx(NORMAL, "* * AC2"); + //PrintAndLogEx(NORMAL, "* * AC2"); + // here must be AC2, but we dont make external authenticate ( + /* // AC2 PRINT_INDENT(level); if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); From 25d6a1274f33d8cb9a34586ebecc8af29af0236c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 19 Feb 2019 21:19:45 +0200 Subject: [PATCH 184/320] small improvement --- client/emv/cmdemv.c | 2 +- client/emv/emvcore.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 477062d38..e2988e1e7 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1283,7 +1283,7 @@ int CmdEMVExec(const char *cmd) { // needs to send AC2 command (res == ARQC) - if ((CID & 0xc0) == 0x80) { + if ((CID & EMVAC_AC_MASK) == EMVAC_ARQC) { PrintAndLogEx(NORMAL, "\n* * Calc CDOL2"); struct tlv *cdol2_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag if (!cdol2_data_tlv) { diff --git a/client/emv/emvcore.h b/client/emv/emvcore.h index 7d53e83bb..9aaaf2e6f 100644 --- a/client/emv/emvcore.h +++ b/client/emv/emvcore.h @@ -39,7 +39,7 @@ typedef enum { enum TransactionType { TT_MSD, - TT_VSDC, // not standart for contactless!!!! + TT_VSDC, // contact only. not standart for contactless TT_QVSDCMCHIP, TT_CDA, }; From e793fa8d73d4cf4e9fe6c16e4447beb4c6e9df74 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 19 Feb 2019 21:28:19 +0200 Subject: [PATCH 185/320] fix tlvdb_get_uint8 --- client/emv/tlv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 8d1429640..0daedaf47 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -551,8 +551,7 @@ struct tlvdb *tlvdb_elm_get_parent(struct tlvdb *tlvdb) bool tlvdb_get_uint8(struct tlvdb *tlvRoot, tlv_tag_t tag, uint8_t *value) { - const struct tlvdb *tlvdb = tlvdb_get(tlvRoot, tag, NULL); - const struct tlv *tlvelm = tlvdb_get_tlv(tlvdb); + const struct tlv *tlvelm = tlvdb_get(tlvRoot, tag, NULL); return tlv_get_uint8(tlvelm, value); } From 3d7cf1e9b764dacbdcf39e9b582915eb1a0fe23e Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 20 Feb 2019 11:29:40 +0100 Subject: [PATCH 186/320] chg: text --- client/cmdmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 5b147e76a..9b71df21d 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -24,14 +24,14 @@ static command_t CommandTable[] = { {"lf", CmdLF, 1, "{ Low Frequency commands... }"}, {"emv", CmdEMV, 1, "{ EMV iso14443 and iso7816... }"}, {"rem", CmdRem, 1, "{ Add text to row in log file }"}, - {"reveng", CmdRev, 1, "{ Crc calculations from the software reveng 1.53... }"}, + {"reveng", CmdRev, 1, "{ Crc calculations from the RevEng software... }"}, {"script", CmdScript, 1, "{ Scripting commands }"}, {"trace", CmdTrace, 1, "{ Trace manipulation... }"}, #ifdef WITH_FLASH - {"mem", CmdFlashMem, 1, "{ RDV40, Flash Memory manipulation... }"}, + {"mem", CmdFlashMem, 1, "{ Flash Memory manipulation... }"}, #endif #ifdef WITH_SMARTCARD - {"sc", CmdSmartcard, 1, "{ RDV40, Smart card ISO7816 commands... }"}, + {"sc", CmdSmartcard, 1, "{ Smart card ISO7816 commands... }"}, #endif {"quit", CmdQuit, 1, ""}, {"exit", CmdQuit, 1, "Exit program"}, From 915c73bcfc9dcd74997d999529e450216d2633f8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 14:48:52 +0200 Subject: [PATCH 187/320] fix possible error --- client/emv/tlv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 0daedaf47..31b5ea360 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -353,6 +353,9 @@ struct tlvdb *tlvdb_find_path(struct tlvdb *tlvdb, tlv_tag_t tag[]) { void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) { while (tlvdb->next) { + if (tlvdb->next == other) + return; + tlvdb = tlvdb->next; } From d81478755e23832505af7aeb64dfbc659c432cd7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 14:50:17 +0200 Subject: [PATCH 188/320] 2nd fix --- client/emv/tlv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/emv/tlv.c b/client/emv/tlv.c index 31b5ea360..a309d0659 100644 --- a/client/emv/tlv.c +++ b/client/emv/tlv.c @@ -352,6 +352,9 @@ struct tlvdb *tlvdb_find_path(struct tlvdb *tlvdb, tlv_tag_t tag[]) { void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) { + if (tlvdb == other) + return; + while (tlvdb->next) { if (tlvdb->next == other) return; From 8e199d4c9e67197fb8576132e8f8c056287d6514 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 15:51:55 +0200 Subject: [PATCH 189/320] add get ATR to cmdsmartcard --- client/cmdsmartcard.c | 21 +++++++++++++-------- client/cmdsmartcard.h | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 23b2b8b3c..9496b5445 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -292,7 +292,10 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { return 0; } -static bool smart_select(bool silent) { +bool smart_select(bool silent, smart_card_atr_t *atr) { + if (atr) + memset(atr, 0, sizeof(smart_card_atr_t)); + UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; clearCommandBuffer(); SendCommand(&c); @@ -308,12 +311,14 @@ static bool smart_select(bool silent) { return false; } - if (!silent) { - smart_card_atr_t card; - memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); - + smart_card_atr_t card; + memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); + + if (atr) + memcpy(atr, &card, sizeof(smart_card_atr_t)); + + if (!silent) PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); - } return true; } @@ -518,7 +523,7 @@ int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leave *dataoutlen = 0; if (activateCard) - smart_select(false); + smart_select(false, NULL); PrintAndLogEx(DEBUG, "APDU SC"); @@ -1017,7 +1022,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { return 1; PrintAndLogEx(INFO, "Selecting card"); - if ( !smart_select(false) ) + if ( !smart_select(false, NULL) ) return 1; char* caid = NULL; diff --git a/client/cmdsmartcard.h b/client/cmdsmartcard.h index cffaeff98..00bc41ff4 100644 --- a/client/cmdsmartcard.h +++ b/client/cmdsmartcard.h @@ -33,6 +33,7 @@ extern int CmdSmartUpgrade(const char* cmd); extern int CmdSmartInfo(const char* cmd); extern int CmdSmartReader(const char *Cmd); +extern bool smart_select(bool silent, smart_card_atr_t *atr); extern int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); extern int usage_sm_raw(void); From fe66f0fac4f9b6e61b81ac979e43a953f3c6a46b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 15:52:26 +0200 Subject: [PATCH 190/320] added contact to `emv scan` --- client/emv/cmdemv.c | 49 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index e2988e1e7..de86d5343 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1382,12 +1382,6 @@ int CmdEMVScan(const char *cmd) { SetAPDULogging(showAPDU); - // TODO - if (channel == ECC_CONTACT) { - PrintAndLogEx(ERR, "Do not use contact interface. Exit."); - return 1; - } - // current path + file name if (!strstr(crelfname, ".json")) strcat(crelfname, ".json"); @@ -1411,23 +1405,35 @@ int CmdEMVScan(const char *cmd) { } // drop field at start - DropFieldEx( channel ); - - // iso 14443 select - PrintAndLogEx(NORMAL, "--> GET UID, ATS."); - - iso14a_card_select_t card; - if (Hf14443_4aGetCardData(&card)) { - return 2; - } + if (channel == ECC_CONTACTLESS) + DropFieldEx( channel ); JsonSaveStr(root, "$.File.Created", "proxmark3 `emv scan`"); - JsonSaveStr(root, "$.Card.Communication", "iso14443-4a"); - JsonSaveBufAsHex(root, "$.Card.UID", (uint8_t *)&card.uid, card.uidlen); - JsonSaveHex(root, "$.Card.ATQA", card.atqa[0] + (card.atqa[1] << 2), 2); - JsonSaveHex(root, "$.Card.SAK", card.sak, 0); - JsonSaveBufAsHex(root, "$.Card.ATS", (uint8_t *)card.ats, card.ats_len); + if (channel == ECC_CONTACTLESS) { + // iso 14443 select + PrintAndLogEx(NORMAL, "--> GET UID, ATS."); + + iso14a_card_select_t card; + if (Hf14443_4aGetCardData(&card)) { + return 2; + } + + + JsonSaveStr(root, "$.Card.Contactless.Communication", "iso14443-4a"); + JsonSaveBufAsHex(root, "$.Card.Contactless.UID", (uint8_t *)&card.uid, card.uidlen); + JsonSaveHex(root, "$.Card.Contactless.ATQA", card.atqa[0] + (card.atqa[1] << 2), 2); + JsonSaveHex(root, "$.Card.Contactless.SAK", card.sak, 0); + JsonSaveBufAsHex(root, "$.Card.Contactless.ATS", (uint8_t *)card.ats, card.ats_len); + } else { + PrintAndLogEx(NORMAL, "--> GET ATR."); + + smart_card_atr_t card; + smart_select(true, &card); + + JsonSaveStr(root, "$.Card.Contact.Communication", "iso7816"); + JsonSaveBufAsHex(root, "$.Card.Contact.ATR", (uint8_t *)card.atr, card.atr_len); + } // init applets list tree const char *al = "Applets list"; @@ -1642,7 +1648,8 @@ int CmdEMVScan(const char *cmd) { // free tlv object tlvdb_free(tlvRoot); - DropFieldEx( channel ); + if (channel == ECC_CONTACTLESS) + DropFieldEx( channel ); res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { From ed991e76b4dd638ced3f32485068f84a2a18f528 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 16:04:08 +0200 Subject: [PATCH 191/320] add print error if smart card functionality not defined --- client/emv/cmdemv.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index de86d5343..6f5917b8d 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -792,6 +792,14 @@ int CmdEMVExec(const char *cmd) { uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; CLIParserFree(); +#ifndef WITH_SMARTCARD + // not compiled with smartcard functionality, we need to exit + if ( channel == ECC_CONTACT ) { + PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting."); + return 0; + } +#endif + SetAPDULogging(showAPDU); // init applets list tree @@ -1380,6 +1388,14 @@ int CmdEMVScan(const char *cmd) { CLIGetStrWithReturn(12, relfname, &relfnamelen); CLIParserFree(); +#ifndef WITH_SMARTCARD + // not compiled with smartcard functionality, we need to exit + if ( channel == ECC_CONTACT ) { + PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting."); + return 0; + } +#endif + SetAPDULogging(showAPDU); // current path + file name @@ -1418,7 +1434,6 @@ int CmdEMVScan(const char *cmd) { if (Hf14443_4aGetCardData(&card)) { return 2; } - JsonSaveStr(root, "$.Card.Contactless.Communication", "iso14443-4a"); JsonSaveBufAsHex(root, "$.Card.Contactless.UID", (uint8_t *)&card.uid, card.uidlen); @@ -1702,6 +1717,7 @@ int CmdEMVRoca(const char *cmd) { if (arg_get_lit(2)) channel = ECC_CONTACT; PrintChannel(channel); + CLIParserFree(); #ifndef WITH_SMARTCARD // not compiled with smartcard functionality, we need to exit From 12582df97657f9fbf7ad8fae431ec5034cd93409 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 16:05:32 +0200 Subject: [PATCH 192/320] fix macro --- client/emv/cmdemv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 6f5917b8d..3e36a4ae6 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1421,8 +1421,7 @@ int CmdEMVScan(const char *cmd) { } // drop field at start - if (channel == ECC_CONTACTLESS) - DropFieldEx( channel ); + DropFieldEx( channel ); JsonSaveStr(root, "$.File.Created", "proxmark3 `emv scan`"); @@ -1663,8 +1662,7 @@ int CmdEMVScan(const char *cmd) { // free tlv object tlvdb_free(tlvRoot); - if (channel == ECC_CONTACTLESS) - DropFieldEx( channel ); + DropFieldEx( channel ); res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { From 8ddedcb140a73cb04c6106e91b1852d77ef36779 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 17:54:05 +0200 Subject: [PATCH 193/320] typo --- client/emv/cmdemv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index e2988e1e7..3200d84b0 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1199,7 +1199,7 @@ int CmdEMVExec(const char *cmd) { dreturn(7); } - // process Format1 (0x80) anf print Format2 (0x77) + // process Format1 (0x80) and print Format2 (0x77) ProcessACResponseFormat1(tlvRoot, buf, len, decodeTLV); uint8_t CID = 0; From 2c4db1ce7c37528fb343d57841a6c3cddcd4a357 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 19:37:30 +0200 Subject: [PATCH 194/320] check ATR length --- client/emv/cmdemv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 9bb71de76..9728a32b7 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1444,6 +1444,10 @@ int CmdEMVScan(const char *cmd) { smart_card_atr_t card; smart_select(true, &card); + if (!card.atr_len) { + PrintAndLogEx(ERR, "Can't get ATR from a smart card."); + return 1; + } JsonSaveStr(root, "$.Card.Contact.Communication", "iso7816"); JsonSaveBufAsHex(root, "$.Card.Contact.ATR", (uint8_t *)card.atr, card.atr_len); From 54ade5df94eb133486bcc688b45989da847fbab5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 21:12:06 +0200 Subject: [PATCH 195/320] add read sector code --- client/mifarehost.c | 31 +++++++++++++++++++++++++++++++ client/mifarehost.h | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/client/mifarehost.c b/client/mifarehost.c index 31ed8e39d..817f99c93 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -414,6 +414,37 @@ out: return -4; } +// MIFARE +int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { + + UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; + memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); + SendCommand(&c); + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + + if (isOK) { + memcpy(data, resp.d.asBytes, mfNumBlocksPerSector(sectorNo) * 16); + for (int i = 0; i < (sectorNo<32?3:15); i++) { + PrintAndLogEx(NORMAL, "data : %s", sprint_hex(data + i * 16, 16)); + } + PrintAndLogEx(NORMAL, "trailer: %s", sprint_hex(data + (sectorNo<32?3:15) * 16, 16)); + + return 0; + } else { + return 1; + } + } else { + PrintAndLogEx(ERR, "Command execute timeout"); + return 2; + } + + return 0; +} + // EMULATOR int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}}; diff --git a/client/mifarehost.h b/client/mifarehost.h index 8f0f3f3bf..69458fdfa 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -76,7 +76,7 @@ extern int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t las uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); extern int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey); - +extern int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); extern int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); extern int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); From f2b600e6e96f34fa5112ffadeb6816b89191b267 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 21:12:28 +0200 Subject: [PATCH 196/320] add keys for mad and ndef --- client/mifaredefault.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/mifaredefault.h b/client/mifaredefault.h index 400463eaf..db9c0329d 100644 --- a/client/mifaredefault.h +++ b/client/mifaredefault.h @@ -31,7 +31,7 @@ static const uint64_t g_mifare_default_keys[] = 0xabcdef123456, 0x4d3a99c351dd, 0x1a982c7e459a, - 0xd3f7d3f7d3f7, + 0xd3f7d3f7d3f7, // NDEF public key 0x714c5c886e97, 0x587ee5f9350f, 0xa0478cc39091, @@ -42,4 +42,7 @@ static const uint64_t g_mifare_default_keys[] = 0x96a301bce267 }; +static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; +static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; + #endif From 583b73226810d2f0aa8a72a5e01aeef352ebe8cd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 21:12:50 +0200 Subject: [PATCH 197/320] add `hf mf mad` command --- client/cmdhfmf.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 47646852e..811fa2430 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3198,6 +3198,39 @@ int CmdHF14AMfAuth4(const char *cmd) { return MifareAuth4(NULL, keyn, key, true, false, true); } +// https://www.nxp.com/docs/en/application-note/AN10787.pdf +int CmdHF14AMfMAD(const char *cmd) { + + CLIParserInit("hf mf mad", + "Checks and prints Mifare Application Directory (MAD)", + "Usage:\n\thf mf mad -> shows MAD if exists\n"); + + void* argtable[] = { + arg_param_begin, + arg_lit0("vV", "verbose", "show technical data"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + bool verbose = arg_get_lit(1); + + CLIParserFree(); + + uint8_t sector[16 * 4] = {0}; + if (mfReadSector(0, 0, (uint8_t *)g_mifare_mad_key, sector)) { + PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + return 2; + } + + if (verbose) { + for(int i = 0; i < 3; i ++) + PrintAndLogEx(NORMAL, "[i] %s", sprint_hex(§or[i * 16], 16)); + } + +// MADDecodeAndPrint(sector, verbose); + + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"darkside", CmdHF14ADarkside, 0, "Darkside attack. read parity error messages."}, @@ -3234,6 +3267,9 @@ 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"}, + {"-----------", CmdHelp, 1, ""}, + {"mad", CmdHF14AMfMAD, 0, "Checks and prints MAD"}, +// {"ndef", CmdHF14AMfHDEF, 0, "Checks and prints NDEF records from card"}, {"ice", CmdHF14AMfice, 0, "collect Mifare Classic nonces to file"}, {NULL, NULL, 0, NULL} From 1675b10c009646fddf4b8a384ca3a7bf5f18fb12 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 20 Feb 2019 21:15:44 +0200 Subject: [PATCH 198/320] small fix --- client/mifarehost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifarehost.c b/client/mifarehost.c index 817f99c93..ba5081441 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -435,7 +435,7 @@ int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) return 0; } else { - return 1; + return isOK; } } else { PrintAndLogEx(ERR, "Command execute timeout"); From 06ade9970a4345430e7349ef5b23f61241ba94e1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 20 Feb 2019 22:29:39 +0100 Subject: [PATCH 199/320] FIX: mem leaks FIX: 'hf mf nested' - params --- client/cmdhf15.c | 1 + client/cmdhfmf.c | 25 ++++++++++++++----------- client/cmdtrace.c | 6 +++--- client/emv/cmdemv.c | 1 + client/loclass/ikeys.c | 3 +++ client/scripting.c | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 2800b0c9c..097a52704 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -834,6 +834,7 @@ int CmdHF15Restore(const char*Cmd) { if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found"); + fclose(f); return 3; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 47646852e..9efb79700 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -425,6 +425,7 @@ char * GenerateFilename(const char *prefix, const char *suffix){ GetHFMF14AUID(uid, &uidlen); if (!uidlen) { PrintAndLogEx(WARNING, "No tag found."); + free(fptr); return NULL; } @@ -1082,19 +1083,21 @@ int CmdHF14AMfNested(const char *Cmd) { } else { SectorsCnt = NumOfSectors(cmdp); } - - ctmp = tolower(param_getchar(Cmd, 4)); - transferToEml |= (ctmp == 't'); - createDumpFile |= (ctmp == 'd'); - ctmp = tolower(param_getchar(Cmd, 6)); - transferToEml |= (ctmp == 't'); - createDumpFile |= (ctmp == 'd'); + uint8_t j = 4; + while ( ctmp != 0x00 ) { + + ctmp = tolower(param_getchar(Cmd, j)); + transferToEml |= (ctmp == 't'); + createDumpFile |= (ctmp == 'd'); + + j++; + } // check if we can authenticate to sector res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64); if (res) { - PrintAndLogEx(WARNING, "key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); return 3; } @@ -1112,9 +1115,9 @@ int CmdHF14AMfNested(const char *Cmd) { if (transferToEml) { uint8_t sectortrailer; if (trgBlockNo < 32*4) { // 4 block sector - sectortrailer = (trgBlockNo & ~0x03) + 3; + sectortrailer = trgBlockNo | 0x03; } else { // 16 block sector - sectortrailer = (trgBlockNo & ~0x0f) + 15; + sectortrailer = trgBlockNo | 0x0f; } mfEmlGetMem(keyBlock, sectortrailer, 1); @@ -1236,7 +1239,7 @@ int CmdHF14AMfNested(const char *Cmd) { num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]); mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); } - PrintAndLogEx(SUCCESS, "key transferred to emulator memory."); + PrintAndLogEx(SUCCESS, "keys transferred to emulator memory."); } // Create dump file diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 90c08459f..56f97ca1d 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -14,7 +14,6 @@ static int CmdHelp(const char *Cmd); // trace pointer static uint8_t *trace; long traceLen = 0; -bool preRDV40 = true; int usage_trace_list(){ PrintAndLogEx(NORMAL, "List protocol data in trace buffer."); @@ -297,8 +296,9 @@ void printFelica(uint16_t traceLen, uint8_t *trace) { if (tracepos + 3 >= traceLen) break; - uint16_t gap = (uint16_t)trace[tracepos+1] + ((uint16_t)trace[tracepos] >> 8); - uint16_t crc_ok = trace[tracepos+2]; + + uint16_t gap = *((uint16_t *)(trace + tracepos)); + uint8_t crc_ok = trace[tracepos+2]; tracepos += 3; if (tracepos + 3 >= traceLen) break; diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 9728a32b7..4228a03e3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1204,6 +1204,7 @@ int CmdEMVExec(const char *cmd) { if (res) { PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw); + free(cdol1_data_tlv); dreturn(7); } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index aefbbaf99..2d14959ca 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -685,6 +685,9 @@ static bool readKeyFile(uint8_t key[8]) { sprintf(filename, "%s.bin", "client/loclass/iclass_key"); } + if ( filename == NULL ) + return retval; + FILE *f = fopen(filename, "rb"); if (!f) return retval; diff --git a/client/scripting.c b/client/scripting.c index b6bb80f33..6f6a30f53 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -608,7 +608,7 @@ static int l_hardnested(lua_State *L){ char filename[FILE_PATH_SIZE]="nonces.bin"; const char *p_filename = luaL_checklstring(L, 11, &size); if(size != 0) - strcpy(filename, p_filename); + memcpy(filename, p_filename, FILE_PATH_SIZE-1); uint32_t blockNo = 0, keyType = 0; uint32_t trgBlockNo = 0, trgKeyType = 0; From 91d6836a47778741b3795080e9a6172425b7540f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 15:34:31 +0100 Subject: [PATCH 200/320] fix: mem leaks. --- client/cmdhffelica.c | 4 ++-- client/cmdhficlass.c | 4 ++-- client/cmdhflegic.c | 1 + client/cmdhfmfhard.c | 10 ++++++++-- client/emv/cmdemv.c | 2 ++ client/emv/emv_pk.c | 6 ------ client/hardnested/hardnested_bruteforce.c | 9 +++++++-- 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 700f7ae8b..07422f419 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -299,10 +299,10 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) { char idm[20]; char pmm[20]; for (int j = 0; j < 8; j++) - snprintf(idm+( j * 2),20, "%02x", trace[j+3]); + snprintf(idm + (j * 2), 20, "%02x", trace[j+3]); for (int j = 0; j < 8; j++) - snprintf(pmm+( j * 2),20, "%02x", trace[j+11]); + snprintf(pmm + (j * 2), 20, "%02x", trace[j+11]); PrintAndLogEx(NORMAL, "DeviceId: IDm: 0x%s PMm: 0x%s ", idm, pmm); } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 9427acf50..746146758 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2162,10 +2162,10 @@ static int cmp_uint32( const void *a, const void *b) { int CmdHFiClassLookUp(const char *Cmd) { uint8_t CSN[8]; - uint8_t EPURSE[8]; + uint8_t EPURSE[8] = { 0,0,0,0,0,0,0,0 }; uint8_t MACS[8]; uint8_t CCNR[12]; - uint8_t MAC_TAG[4] = {0x00,0x00,0x00,0x00}; + uint8_t MAC_TAG[4] = { 0,0,0,0 }; // elite key, raw key, standard key bool use_elite = false; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 8c4ef411c..41df287a9 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -1022,6 +1022,7 @@ int CmdLegicRestore(const char *Cmd){ f = fopen(filename,"rb"); if (!f) { PrintAndLogEx(WARNING, "File %s not found or locked", filename); + free(data); return 3; } diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 4818f480f..0c661d410 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -266,14 +266,20 @@ static void init_bitflip_bitarrays(void) continue; } else { fseek(statesfile, 0, SEEK_END); - uint32_t filesize = (uint32_t)ftell(statesfile); + int fsize = ftell(statesfile); + if ( fsize == -1 ){ + PrintAndLogEx(WARNING, "File read error with %s. Aborting...\n", state_file_name); + fclose(statesfile); + exit(5); + } + uint32_t filesize = (uint32_t)fsize; rewind(statesfile); uint8_t input_buffer[filesize]; size_t bytesread = fread(input_buffer, 1, filesize, statesfile); if (bytesread != filesize) { PrintAndLogEx(WARNING, "File read error with %s. Aborting...\n", state_file_name); fclose(statesfile); - inflateEnd(&compressed_stream); + //inflateEnd(&compressed_stream); exit(5); } fclose(statesfile); diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 4228a03e3..98bc389f4 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -284,6 +284,7 @@ int CmdEMVGPO(const char *cmd) { if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); + free(pdol_data_tlv); return 4; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -296,6 +297,7 @@ int CmdEMVGPO(const char *cmd) { if (pdol_data_tlv != &data_tlv) free(pdol_data_tlv); + tlvdb_free(tlvRoot); if (sw) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index b577855e0..091ab8062 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -429,9 +429,6 @@ char *emv_pk_get_ca_pk_file(const char *dirname, const unsigned char *rid, unsig if (!dirname) dirname = ".";//openemv_config_get_str("capk.dir", NULL); - if (!dirname) - return NULL; - char *filename; int ret = asprintf(&filename, "%s/%02hhx%02hhx%02hhx%02hhx%02hhx_%02hhx.0", dirname, @@ -453,9 +450,6 @@ char *emv_pk_get_ca_pk_rid_file(const char *dirname, const unsigned char *rid) if (!dirname) dirname = "."; //openemv_config_get_str("capk.dir", NULL); - if (!dirname) - return NULL; - char *filename; int ret = asprintf(&filename, "%s/%02hhx%02hhx%02hhx%02hhx%02hhx.pks", dirname, diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 55d6bbfbf..2a7618a1d 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -311,6 +311,11 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint uint64_t start_time = msclock(); +#if defined(__linux__) || defined(__APPLE__) + if ( NUM_BRUTE_FORCE_THREADS < 0 ) + return false; +#endif + pthread_t threads[NUM_BRUTE_FORCE_THREADS]; struct args { bool silent; @@ -322,7 +327,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint uint8_t *best_first_bytes; } thread_args[NUM_BRUTE_FORCE_THREADS]; - for(uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ + for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ thread_args[i].thread_ID = i; thread_args[i].silent = silent; thread_args[i].cuid = cuid; @@ -332,7 +337,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint thread_args[i].best_first_bytes = best_first_bytes; pthread_create(&threads[i], NULL, crack_states_thread, (void*)&thread_args[i]); } - for(uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ + for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++){ pthread_join(threads[i], 0); } From de317d9f4865c4cbafd6691386a52ff4401f1b87 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 15:39:36 +0100 Subject: [PATCH 201/320] fix: mem leaks. --- client/cmdhfmf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 9efb79700..78a9ed138 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1723,7 +1723,7 @@ int CmdHF14AMfChk(const char *Cmd) { if (strlen(Cmd) < 3 || ctmp == 'h') return usage_hf14_chk(); FILE * f; - char filename[FILE_PATH_SIZE]={0}; + char filename[FILE_PATH_SIZE] = {0}; char buf[13]; uint8_t *keyBlock = NULL, *p; sector_t *e_sector = NULL; @@ -1970,8 +1970,10 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) + if (fptr == NULL) { + free(keyBlock); return 1; + } FILE *fkeys = fopen(fptr, "wb"); if (fkeys == NULL) { @@ -2489,15 +2491,18 @@ int CmdHF14AMfELoad(const char *Cmd) { if ( blockWidth == 4 ) { if ((blockNum != numBlocks)) { PrintAndLogEx(FAILED, "Warning, Ultralight/Ntag file content, Loaded %d blocks into emulator memory", blockNum); + free(data); return 0; } } else { if ((blockNum != numBlocks)) { PrintAndLogEx(FAILED, "Error, file content, Only loaded %d blocks, must be %d blocks into emulator memory", blockNum, numBlocks); + free(data); return 4; } } PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: " _YELLOW_(%s), blockNum, filename); + free(data); return 0; } From 00d1fd9d456fc022c7084bb7cf35c59872979dc1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 16:07:14 +0100 Subject: [PATCH 202/320] fix: mem leaks --- uart/uart_posix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 093aaf363..49bcb9b8e 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -103,6 +103,8 @@ serial_port uart_open(const char* pcPortName) int s = getaddrinfo(addrstr, portstr, NULL, &addr); if (s != 0) { printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + freeaddrinfo(addr); + free(addrstr); return INVALID_SERIAL_PORT; } @@ -121,6 +123,8 @@ serial_port uart_open(const char* pcPortName) if (rp == NULL) { /* No address succeeded */ printf("Error: Could not connect\n"); + freeaddrinfo(addr); + free(addrstr); return INVALID_SERIAL_PORT; } From 44392c6afcb75aa94e75b4d3a19930c4ed2d52cb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 16:09:27 +0100 Subject: [PATCH 203/320] fix: whitespaces --- uart/uart_posix.c | 559 +++++++++++++++++++++++----------------------- 1 file changed, 279 insertions(+), 280 deletions(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 49bcb9b8e..aec19c38a 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -62,354 +62,353 @@ typedef struct termios term_info; typedef struct { - int fd; // Serial port file descriptor - term_info tiOld; // Terminal info before using the port - term_info tiNew; // Terminal info during the transaction + int fd; // Serial port file descriptor + term_info tiOld; // Terminal info before using the port + term_info tiNew; // Terminal info during the transaction } serial_port_unix; // Set time-out on 30 miliseconds struct timeval timeout = { - .tv_sec = 0, // 0 second - .tv_usec = 30000 // 30000 micro seconds + .tv_sec = 0, // 0 second + .tv_usec = 30000 // 30 000 micro seconds }; -serial_port uart_open(const char* pcPortName) -{ - serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); - if (sp == 0) return INVALID_SERIAL_PORT; +serial_port uart_open(const char* pcPortName) { + serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); + if (sp == 0) return INVALID_SERIAL_PORT; - if (memcmp(pcPortName, "tcp:", 4) == 0) { - struct addrinfo *addr, *rp; - char *addrstr = strdup(pcPortName + 4); + if (memcmp(pcPortName, "tcp:", 4) == 0) { + struct addrinfo *addr, *rp; + char *addrstr = strdup(pcPortName + 4); - if (addrstr == NULL) { - printf("Error: strdup\n"); - return INVALID_SERIAL_PORT; - } + if (addrstr == NULL) { + printf("Error: strdup\n"); + return INVALID_SERIAL_PORT; + } - char *colon = strrchr(addrstr, ':'); - char *portstr; + timeout.tv_usec = 300000 // 300 000 micro seconds + + char *colon = strrchr(addrstr, ':'); + char *portstr; + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else { + portstr = "7901"; + } - // Set time-out to 300 miliseconds only for TCP port - timeout.tv_usec = 300000; + int s = getaddrinfo(addrstr, portstr, NULL, &addr); + if (s != 0) { + printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + freeaddrinfo(addr); + free(addrstr); + return INVALID_SERIAL_PORT; + } - if (colon) { - portstr = colon + 1; - *colon = '\0'; - } else { - portstr = "7901"; + int sfd; + for (rp = addr; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + printf("Error: Could not connect\n"); + freeaddrinfo(addr); + free(addrstr); + return INVALID_SERIAL_PORT; + } + + freeaddrinfo(addr); + free(addrstr); + + sp->fd = sfd; + + int one = 1; + setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + return sp; } - - int s = getaddrinfo(addrstr, portstr, NULL, &addr); - if (s != 0) { - printf("Error: getaddrinfo: %s\n", gai_strerror(s)); - freeaddrinfo(addr); - free(addrstr); - return INVALID_SERIAL_PORT; - } - - int sfd; - for (rp = addr; rp != NULL; rp = rp->ai_next) { - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (sfd == -1) - continue; - - if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) - break; - - close(sfd); - } - - if (rp == NULL) { /* No address succeeded */ - printf("Error: Could not connect\n"); - freeaddrinfo(addr); - free(addrstr); - return INVALID_SERIAL_PORT; - } - - freeaddrinfo(addr); - free(addrstr); - - sp->fd = sfd; - - int one = 1; - setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); - return sp; - } - sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - if(sp->fd == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if(sp->fd == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } - // Finally figured out a way to claim a serial port interface under unix - // We just try to set a (advisory) lock on the file descriptor - struct flock fl; - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - - // Does the system allows us to place a lock on this file descriptor - if (fcntl(sp->fd, F_SETLK, &fl) == -1) { - // A conflicting lock is held by another process - free(sp); - return CLAIMED_SERIAL_PORT; - } + // Finally figured out a way to claim a serial port interface under unix + // We just try to set a (advisory) lock on the file descriptor + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); + + // Does the system allows us to place a lock on this file descriptor + if (fcntl(sp->fd, F_SETLK, &fl) == -1) { + // A conflicting lock is held by another process + free(sp); + return CLAIMED_SERIAL_PORT; + } + + // Try to retrieve the old (current) terminal info struct + if(tcgetattr(sp->fd,&sp->tiOld) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } + + // Duplicate the (old) terminal info struct + sp->tiNew = sp->tiOld; + + // Configure the serial port + sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; + sp->tiNew.c_iflag = IGNPAR; + sp->tiNew.c_oflag = 0; + sp->tiNew.c_lflag = 0; + + // Block until n bytes are received + sp->tiNew.c_cc[VMIN] = 0; + // Block until a timer expires (n * 100 mSec.) + sp->tiNew.c_cc[VTIME] = 0; + + // Try to set the new terminal info struct + if(tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { + uart_close(sp); + return INVALID_SERIAL_PORT; + } - // Try to retrieve the old (current) terminal info struct - if(tcgetattr(sp->fd,&sp->tiOld) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - - // Duplicate the (old) terminal info struct - sp->tiNew = sp->tiOld; - - // Configure the serial port - sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; - sp->tiNew.c_iflag = IGNPAR; - sp->tiNew.c_oflag = 0; - sp->tiNew.c_lflag = 0; - - // Block until n bytes are received - sp->tiNew.c_cc[VMIN] = 0; - // Block until a timer expires (n * 100 mSec.) - sp->tiNew.c_cc[VTIME] = 0; - - // Try to set the new terminal info struct - if(tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { - uart_close(sp); - return INVALID_SERIAL_PORT; - } - // Flush all lingering data that may exist tcflush(sp->fd, TCIOFLUSH); #ifdef WITH_FPC if ( uart_set_speed(sp, 115200) ) { - printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); + printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); } else { uart_set_speed(sp, 9600); printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n"); } #else - // set speed, works for UBUNTU 14.04 - bool success = uart_set_speed(sp, 460800); - if (success) { - printf("[=] UART Setting serial baudrate 460800\n"); - } else { - uart_set_speed(sp, 115200); - printf("[=] UART Setting serial baudrate 115200\n"); - } + // set speed, works for UBUNTU 14.04 + bool success = uart_set_speed(sp, 460800); + if (success) { + printf("[=] UART Setting serial baudrate 460800\n"); + } else { + uart_set_speed(sp, 115200); + printf("[=] UART Setting serial baudrate 115200\n"); + } #endif - return sp; + return sp; } void uart_close(const serial_port sp) { - serial_port_unix* spu = (serial_port_unix*)sp; - tcflush(spu->fd, TCIOFLUSH); - tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); - struct flock fl; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); + serial_port_unix* spu = (serial_port_unix*)sp; + tcflush(spu->fd, TCIOFLUSH); + tcsetattr(spu->fd, TCSANOW, &(spu->tiOld)); + struct flock fl; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); - // Does the system allows us to place a lock on this file descriptor - int err = fcntl(spu->fd, F_SETLK, &fl); - if ( err == -1) { - //perror("fcntl"); - } - close(spu->fd); - free(sp); + // Does the system allows us to place a lock on this file descriptor + int err = fcntl(spu->fd, F_SETLK, &fl); + if ( err == -1) { + //perror("fcntl"); + } + close(spu->fd); + free(sp); } bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) { - int res; - int byteCount; - fd_set rfds; - struct timeval tv; + int res; + int byteCount; + fd_set rfds; + struct timeval tv; + + // Reset the output count + *pszRxLen = 0; - // Reset the output count - *pszRxLen = 0; - - do { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix*)sp)->fd, &rfds); - tv = timeout; - res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv); - - // Read error - if (res < 0) { - return false; - } - - // Read time-out - if (res == 0) { - if (*pszRxLen == 0) { - // Error, we received no data - return false; - } else { - // We received some data, but nothing more is available - return true; - } - } - - // Retrieve the count of the incoming bytes - res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); - if (res < 0) return false; - - // Cap the number of bytes, so we don't overrun the buffer - if (pszMaxRxLen - (*pszRxLen) < byteCount) { - byteCount = pszMaxRxLen - (*pszRxLen); - } + do { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd, &rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv); - // There is something available, read the data - res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount); + // Read error + if (res < 0) { + return false; + } - // Stop if the OS has some troubles reading the data - if (res <= 0) return false; - - *pszRxLen += res; + // Read time-out + if (res == 0) { + if (*pszRxLen == 0) { + // Error, we received no data + return false; + } else { + // We received some data, but nothing more is available + return true; + } + } - if (*pszRxLen == pszMaxRxLen) { - // We have all the data we wanted. - return true; - } - - } while (byteCount); + // Retrieve the count of the incoming bytes + res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); + if (res < 0) return false; - return true; + // Cap the number of bytes, so we don't overrun the buffer + if (pszMaxRxLen - (*pszRxLen) < byteCount) { + byteCount = pszMaxRxLen - (*pszRxLen); + } + + // There is something available, read the data + res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount); + + // Stop if the OS has some troubles reading the data + if (res <= 0) return false; + + *pszRxLen += res; + + if (*pszRxLen == pszMaxRxLen) { + // We have all the data we wanted. + return true; + } + + } while (byteCount); + + return true; } bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t len) { - int32_t res; - size_t pos = 0; - fd_set rfds; - struct timeval tv; + int32_t res; + size_t pos = 0; + fd_set rfds; + struct timeval tv; - while (pos < len) { - // Reset file descriptor - FD_ZERO(&rfds); - FD_SET(((serial_port_unix*)sp)->fd, &rfds); - tv = timeout; - res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv); - - // Write error - if (res < 0) { - printf("UART:: write error (%d)\n", res); - return false; - } - - // Write time-out - if (res == 0) { - printf("UART:: write time-out\n"); - return false; - } - - // Send away the bytes - res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos); - - // Stop if the OS has some troubles sending the data - if (res <= 0) return false; - - pos += res; - } - return true; + while (pos < len) { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(((serial_port_unix*)sp)->fd, &rfds); + tv = timeout; + res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv); + + // Write error + if (res < 0) { + printf("UART:: write error (%d)\n", res); + return false; + } + + // Write time-out + if (res == 0) { + printf("UART:: write time-out\n"); + return false; + } + + // Send away the bytes + res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos); + + // Stop if the OS has some troubles sending the data + if (res <= 0) return false; + + pos += res; + } + return true; } bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { - const serial_port_unix* spu = (serial_port_unix*)sp; - speed_t stPortSpeed; - switch (uiPortSpeed) { - case 0: stPortSpeed = B0; break; - case 50: stPortSpeed = B50; break; - case 75: stPortSpeed = B75; break; - case 110: stPortSpeed = B110; break; - case 134: stPortSpeed = B134; break; - case 150: stPortSpeed = B150; break; - case 300: stPortSpeed = B300; break; - case 600: stPortSpeed = B600; break; - case 1200: stPortSpeed = B1200; break; - case 1800: stPortSpeed = B1800; break; - case 2400: stPortSpeed = B2400; break; - case 4800: stPortSpeed = B4800; break; - case 9600: stPortSpeed = B9600; break; - case 19200: stPortSpeed = B19200; break; - case 38400: stPortSpeed = B38400; break; + const serial_port_unix* spu = (serial_port_unix*)sp; + speed_t stPortSpeed; + switch (uiPortSpeed) { + case 0: stPortSpeed = B0; break; + case 50: stPortSpeed = B50; break; + case 75: stPortSpeed = B75; break; + case 110: stPortSpeed = B110; break; + case 134: stPortSpeed = B134; break; + case 150: stPortSpeed = B150; break; + case 300: stPortSpeed = B300; break; + case 600: stPortSpeed = B600; break; + case 1200: stPortSpeed = B1200; break; + case 1800: stPortSpeed = B1800; break; + case 2400: stPortSpeed = B2400; break; + case 4800: stPortSpeed = B4800; break; + case 9600: stPortSpeed = B9600; break; + case 19200: stPortSpeed = B19200; break; + case 38400: stPortSpeed = B38400; break; # ifdef B57600 - case 57600: stPortSpeed = B57600; break; + case 57600: stPortSpeed = B57600; break; # endif # ifdef B115200 - case 115200: stPortSpeed = B115200; break; + case 115200: stPortSpeed = B115200; break; # endif # ifdef B230400 - case 230400: stPortSpeed = B230400; break; + case 230400: stPortSpeed = B230400; break; # endif # ifdef B460800 - case 460800: stPortSpeed = B460800; break; + case 460800: stPortSpeed = B460800; break; # endif # ifdef B921600 - case 921600: stPortSpeed = B921600; break; + case 921600: stPortSpeed = B921600; break; # endif - default: return false; - }; - struct termios ti; - if (tcgetattr(spu->fd,&ti) == -1) return false; - // Set port speed (Input and Output) - cfsetispeed(&ti, stPortSpeed); - cfsetospeed(&ti, stPortSpeed); - return (tcsetattr(spu->fd, TCSANOW, &ti) != -1); + default: return false; + }; + struct termios ti; + if (tcgetattr(spu->fd,&ti) == -1) return false; + // Set port speed (Input and Output) + cfsetispeed(&ti, stPortSpeed); + cfsetospeed(&ti, stPortSpeed); + return (tcsetattr(spu->fd, TCSANOW, &ti) != -1); } uint32_t uart_get_speed(const serial_port sp) { - struct termios ti; - uint32_t uiPortSpeed; - const serial_port_unix* spu = (serial_port_unix*)sp; - if (tcgetattr(spu->fd, &ti) == -1) return 0; - // Set port speed (Input) - speed_t stPortSpeed = cfgetispeed(&ti); - switch (stPortSpeed) { - case B0: uiPortSpeed = 0; break; - case B50: uiPortSpeed = 50; break; - case B75: uiPortSpeed = 75; break; - case B110: uiPortSpeed = 110; break; - case B134: uiPortSpeed = 134; break; - case B150: uiPortSpeed = 150; break; - case B300: uiPortSpeed = 300; break; - case B600: uiPortSpeed = 600; break; - case B1200: uiPortSpeed = 1200; break; - case B1800: uiPortSpeed = 1800; break; - case B2400: uiPortSpeed = 2400; break; - case B4800: uiPortSpeed = 4800; break; - case B9600: uiPortSpeed = 9600; break; - case B19200: uiPortSpeed = 19200; break; - case B38400: uiPortSpeed = 38400; break; + struct termios ti; + uint32_t uiPortSpeed; + const serial_port_unix* spu = (serial_port_unix*)sp; + + if (tcgetattr(spu->fd, &ti) == -1) + return 0; + + // Set port speed (Input) + speed_t stPortSpeed = cfgetispeed(&ti); + switch (stPortSpeed) { + case B0: uiPortSpeed = 0; break; + case B50: uiPortSpeed = 50; break; + case B75: uiPortSpeed = 75; break; + case B110: uiPortSpeed = 110; break; + case B134: uiPortSpeed = 134; break; + case B150: uiPortSpeed = 150; break; + case B300: uiPortSpeed = 300; break; + case B600: uiPortSpeed = 600; break; + case B1200: uiPortSpeed = 1200; break; + case B1800: uiPortSpeed = 1800; break; + case B2400: uiPortSpeed = 2400; break; + case B4800: uiPortSpeed = 4800; break; + case B9600: uiPortSpeed = 9600; break; + case B19200: uiPortSpeed = 19200; break; + case B38400: uiPortSpeed = 38400; break; # ifdef B57600 - case B57600: uiPortSpeed = 57600; break; + case B57600: uiPortSpeed = 57600; break; # endif # ifdef B115200 - case B115200: uiPortSpeed = 115200; break; + case B115200: uiPortSpeed = 115200; break; # endif # ifdef B230400 - case B230400: uiPortSpeed = 230400; break; + case B230400: uiPortSpeed = 230400; break; # endif # ifdef B460800 - case B460800: uiPortSpeed = 460800; break; + case B460800: uiPortSpeed = 460800; break; # endif # ifdef B921600 - case B921600: uiPortSpeed = 921600; break; + case B921600: uiPortSpeed = 921600; break; # endif - default: return 0; - }; - return uiPortSpeed; + default: return 0; + }; + return uiPortSpeed; } - #endif From 6d63b3fbed045d851d7741124872da6c82bea029 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 16:17:49 +0100 Subject: [PATCH 204/320] fix: mem leaks. --- client/cmdhffelica.c | 6 +++--- client/cmdhficlass.c | 2 +- client/cmdhfmf.c | 9 +++++++-- client/cmdhfmfu.c | 2 ++ client/cmdsmartcard.c | 4 +++- client/emv/cmdemv.c | 1 + client/loclass/elite_crack.c | 5 +++-- client/loclass/fileutils.c | 9 +++++++-- client/loclass/ikeys.c | 2 +- 9 files changed, 28 insertions(+), 12 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 07422f419..acfc68cf2 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -242,7 +242,7 @@ static void printSep() { PrintAndLogEx(NORMAL, "------------------------------------------------------------------------------------"); } -uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) { +uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { if (tracepos+19 >= tracelen) return tracelen; @@ -273,8 +273,8 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) { case 0x0c: PrintAndLogEx(NORMAL, "S_PAD12: %s",line);break; case 0x0d: PrintAndLogEx(NORMAL, "S_PAD13: %s",line);break; case 0x0E: { - uint32_t regA = trace[3] + (trace[4]>>8) + (trace[5]>>16) + (trace[6]>>24); - uint32_t regB = trace[7] + (trace[8]>>8) + (trace[9]>>16) + (trace[10]>>24); + uint32_t regA = trace[3] | trace[4] << 8 | trace[5] << 16 | trace[ 6] << 24; + uint32_t regB = trace[7] | trace[8] << 8 | trace[9] << 16 | trace[10] << 24; line[0] = 0; for (int j = 0; j < 8; j++) snprintf(line+( j * 2),110, "%02x", trace[j+11]); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 746146758..ddc6fb2c0 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -2163,7 +2163,7 @@ int CmdHFiClassLookUp(const char *Cmd) { uint8_t CSN[8]; uint8_t EPURSE[8] = { 0,0,0,0,0,0,0,0 }; - uint8_t MACS[8]; + uint8_t MACS[8]= { 0,0,0,0,0,0,0,0 }; uint8_t CCNR[12]; uint8_t MAC_TAG[4] = { 0,0,0,0 }; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 78a9ed138..57cf246da 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1245,8 +1245,10 @@ int CmdHF14AMfNested(const char *Cmd) { // Create dump file if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) + if (fptr == NULL) { + free(e_sector); return 1; + } if ((fkeys = fopen(fptr, "wb")) == NULL) { PrintAndLogEx(WARNING, "could not create file " _YELLOW_(%s), fptr); @@ -1276,6 +1278,8 @@ int CmdHF14AMfNested(const char *Cmd) { } free(e_sector); } + + free(e_sector); return 0; } @@ -1971,7 +1975,8 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); if (fptr == NULL) { - free(keyBlock); + free(keyBlock); + free(e_sector); return 1; } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index e583f7f02..d703f980d 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1982,6 +1982,7 @@ int CmdHF14AMfURestore(const char *Cmd){ uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if ( !dump ) { PrintAndLogEx(WARNING, "Failed to allocate memory"); + fclose(f); return 1; } @@ -1990,6 +1991,7 @@ int CmdHF14AMfURestore(const char *Cmd){ fclose(f); if ( bytes_read < 48 ) { PrintAndLogEx(WARNING, "Error, dump file is too small"); + free(dump); return 1; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 9496b5445..3860496de 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -1022,8 +1022,10 @@ int CmdSmartBruteforceSFI(const char *Cmd) { return 1; PrintAndLogEx(INFO, "Selecting card"); - if ( !smart_select(false, NULL) ) + if ( !smart_select(false, NULL) ) { + free(buf); return 1; + } char* caid = NULL; diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 98bc389f4..94df507de 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1807,6 +1807,7 @@ int CmdEMVRoca(const char *cmd) { PrintAndLogEx(ERR, "Can't create PDOL data."); tlvdb_free(tlvRoot); DropFieldEx( channel ); + free(pdol_data_tlv); return 6; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 6619e7aaa..630fa72a6 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -538,18 +538,19 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) { if (fsize < 0) { PrintAndLogDevice(WARNING, "Error, when getting filesize"); - if (f) fclose(f); + fclose(f); return 1; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if ( !dump ) { PrintAndLogDevice(WARNING, "Failed to allocate memory"); + fclose(f); return 2; } size_t bytes_read = fread(dump, 1, fsize, f); - if (f) fclose(f); + fclose(f); if (bytes_read < fsize) { PrintAndLogDevice(WARNING, "Error, could only read %d bytes (should be %d)", bytes_read, fsize ); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index da91b21ec..6ce7c42ea 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -266,8 +266,8 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* FILE *f = fopen(fileName, "rb"); if ( !f ) { PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_(%s)"'", fileName); - retval = 1; - goto out; + free(fileName); + return 1; } // get filesize in order to malloc memory @@ -310,7 +310,12 @@ int loadFile(const char *preferredName, const char *suffix, void* data, size_t* out: fclose(f); + + if (data) + free(data); + free(fileName); + return retval; } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 2d14959ca..16b5513b7 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -685,7 +685,7 @@ static bool readKeyFile(uint8_t key[8]) { sprintf(filename, "%s.bin", "client/loclass/iclass_key"); } - if ( filename == NULL ) + if ( strlen(filename) == 0 ) return retval; FILE *f = fopen(filename, "rb"); From 265c069edc7b8160fbdc9ac113d97a26030a6480 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 16:19:07 +0100 Subject: [PATCH 205/320] chg... missing --- uart/uart_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index aec19c38a..b9df932d6 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -86,7 +86,7 @@ serial_port uart_open(const char* pcPortName) { return INVALID_SERIAL_PORT; } - timeout.tv_usec = 300000 // 300 000 micro seconds + timeout.tv_usec = 300000; // 300 000 micro seconds char *colon = strrchr(addrstr, ':'); char *portstr; From 3b21b175099649f91572953cee1e65100385269e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 21 Feb 2019 19:15:46 +0200 Subject: [PATCH 206/320] move mifare stuff to its folder --- client/Makefile | 6 +- client/cmdanalyse.h | 6 +- client/cmdhf14a.h | 2 +- client/cmdhflist.h | 4 +- client/cmdhfmf.c | 22 +- client/cmdhfmf.h | 14 +- client/cmdhfmfp.c | 2 +- client/cmdhfmfp.h | 2 +- client/loclass/fileutils.h | 2 +- client/{ => mifare}/mfkey.c | 0 client/{ => mifare}/mfkey.h | 0 client/{ => mifare}/mifare4.c | 0 client/{ => mifare}/mifare4.h | 0 client/{ => mifare}/mifaredefault.h | 0 client/{ => mifare}/mifarehost.c | 2033 +++++++++++++-------------- client/{ => mifare}/mifarehost.h | 204 +-- client/obj/mifare/.dummy | 0 client/scripting.h | 2 +- include/mifare.h | 6 + 19 files changed, 1158 insertions(+), 1147 deletions(-) rename client/{ => mifare}/mfkey.c (100%) rename client/{ => mifare}/mfkey.h (100%) rename client/{ => mifare}/mifare4.c (100%) rename client/{ => mifare}/mifare4.h (100%) rename client/{ => mifare}/mifaredefault.h (100%) rename client/{ => mifare}/mifarehost.c (95%) rename client/{ => mifare}/mifarehost.h (97%) create mode 100644 client/obj/mifare/.dummy diff --git a/client/Makefile b/client/Makefile index 0b19d4599..9f8055f8e 100644 --- a/client/Makefile +++ b/client/Makefile @@ -108,7 +108,7 @@ CORESRCS = uart_posix.c \ CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ - mfkey.c \ + mifare/mfkey.c \ tea.c \ fido/additional_ca.c \ fido/cose.c \ @@ -126,7 +126,7 @@ CMDSRCS = crapto1/crapto1.c \ loclass/elite_crack.c \ loclass/fileutils.c \ whereami.c \ - mifarehost.c \ + mifare/mifarehost.c \ parity.c \ crc.c \ crc16.c \ @@ -156,7 +156,7 @@ CMDSRCS = crapto1/crapto1.c \ emv/test/cda_test.c\ emv/cmdemv.c \ emv/emv_roca.c \ - mifare4.c \ + mifare/mifare4.c \ cmdanalyse.c \ cmdhf.c \ cmdhflist.c \ diff --git a/client/cmdanalyse.h b/client/cmdanalyse.h index f834c717d..ab7606f5c 100644 --- a/client/cmdanalyse.h +++ b/client/cmdanalyse.h @@ -16,15 +16,15 @@ #include #include "cmdmain.h" #include "proxmark3.h" -#include "ui.h" // PrintAndLog +#include "ui.h" // PrintAndLog #include "util.h" #include "crc.h" #include "crc16.h" // crc16 ccitt #include "tea.h" #include "legic_prng.h" #include "loclass/elite_crack.h" -#include "mfkey.h" //nonce2key -#include "util_posix.h" // msclock +#include "mifare/mfkey.h" //nonce2key +#include "util_posix.h" // msclock int usage_analyse_lcr(void); diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index 723c31100..3fe04d26c 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -29,7 +29,7 @@ #include "cmdhfmf.h" #include "cmdhfmfu.h" #include "cmdhf.h" // list cmd -#include "mifarehost.h" +#include "mifare/mifarehost.h" #include "emv/apduinfo.h" #include "emv/emvcore.h" diff --git a/client/cmdhflist.h b/client/cmdhflist.h index 1955119f2..60a0a0dfd 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -31,8 +31,8 @@ #include "emv/cmdemv.h" // EMV #include "protocols.h" #include "crapto1/crapto1.h" -#include "mifarehost.h" -#include "mifaredefault.h" +#include "mifare/mifarehost.h" +#include "mifare/mifaredefault.h" #include "parity.h" // oddparity #include "iso15693tools.h" // ISO15693 crc diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 811fa2430..a12bc34c2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #include "cmdhfmf.h" -#include "mifare4.h" +#include "mifare/mifare4.h" #define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 @@ -3216,18 +3216,28 @@ int CmdHF14AMfMAD(const char *cmd) { CLIParserFree(); uint8_t sector[16 * 4] = {0}; - if (mfReadSector(0, 0, (uint8_t *)g_mifare_mad_key, sector)) { + if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); return 2; } if (verbose) { - for(int i = 0; i < 3; i ++) - PrintAndLogEx(NORMAL, "[i] %s", sprint_hex(§or[i * 16], 16)); + for(int i = 0; i < 4; i ++) + PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or[i * 16], 16)); } + /* + bool haveMAD2 = false; + MAD1DecodeAndPrint(sector, verbose, &haveMAD2); -// MADDecodeAndPrint(sector, verbose); - + if (haveMAD2) { + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { + PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + return 2; + } + + MAD2DecodeAndPrint(sector, verbose); + } + */ return 0; } diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index eeb7a74f6..bdd817e41 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -23,14 +23,14 @@ #include "cmdparser.h" #include "common.h" #include "util.h" -#include "mifare.h" // nonces_t struct -#include "mfkey.h" // mfkey32_moebious +#include "mifare.h" // nonces_t struct +#include "mifare/mfkey.h" // mfkey32_moebious #include "cmdhfmfhard.h" -#include "mifarehost.h" // icesector_t, sector_t -#include "util_posix.h" // msclock -#include "mifaredefault.h" // mifare default key array -#include "cmdhf14a.h" // dropfield -#include "cliparser/cliparser.h" // argtable +#include "mifare/mifarehost.h" // icesector_t, sector_t +#include "util_posix.h" // msclock +#include "mifare/mifaredefault.h" // mifare default key array +#include "cmdhf14a.h" // dropfield +#include "cliparser/cliparser.h" // argtable #include "hardnested/hardnested_bf_core.h" // SetSIMDInstr extern int CmdHFMF(const char *Cmd); diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 0d7a623d4..0917728be 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -22,7 +22,7 @@ #include "ui.h" #include "cmdhf14a.h" #include "mifare.h" -#include "mifare4.h" +#include "mifare/mifare4.h" #include "cliparser/cliparser.h" #include "crypto/libpcrypto.h" diff --git a/client/cmdhfmfp.h b/client/cmdhfmfp.h index b1ac7c349..a5cacb518 100644 --- a/client/cmdhfmfp.h +++ b/client/cmdhfmfp.h @@ -10,7 +10,7 @@ #ifndef CMDHFMFP_H__ #define CMDHFMFP_H__ -#include "mifaredefault.h" +#include "mifare/mifaredefault.h" extern int CmdHFMFP(const char *Cmd); diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index 3fc781d2e..9485707f1 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -48,7 +48,7 @@ #include #include "../ui.h" #include "../emv/emvjson.h" -#include "mifare4.h" +#include "mifare/mifare4.h" #include "cmdhfmfu.h" typedef enum { diff --git a/client/mfkey.c b/client/mifare/mfkey.c similarity index 100% rename from client/mfkey.c rename to client/mifare/mfkey.c diff --git a/client/mfkey.h b/client/mifare/mfkey.h similarity index 100% rename from client/mfkey.h rename to client/mifare/mfkey.h diff --git a/client/mifare4.c b/client/mifare/mifare4.c similarity index 100% rename from client/mifare4.c rename to client/mifare/mifare4.c diff --git a/client/mifare4.h b/client/mifare/mifare4.h similarity index 100% rename from client/mifare4.h rename to client/mifare/mifare4.h diff --git a/client/mifaredefault.h b/client/mifare/mifaredefault.h similarity index 100% rename from client/mifaredefault.h rename to client/mifare/mifaredefault.h diff --git a/client/mifarehost.c b/client/mifare/mifarehost.c similarity index 95% rename from client/mifarehost.c rename to client/mifare/mifarehost.c index ba5081441..cd239d585 100644 --- a/client/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1,1020 +1,1015 @@ -// Merlok, 2011, 2012 -// people from mifare@nethemba.com, 2010 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// mifare commands -//----------------------------------------------------------------------------- -#include "mifarehost.h" -#include "cmdmain.h" - -int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { - uint32_t uid = 0; - uint32_t nt = 0, nr = 0, ar = 0; - uint64_t par_list = 0, ks_list = 0; - uint64_t *keylist = NULL, *last_keylist = NULL; - uint32_t keycount = 0; - int16_t isOK = 0; - - UsbCommand c = {CMD_READER_MIFARE, {true, blockno, key_type}}; - - // message - PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); - PrintAndLogEx(NORMAL, "executing Darkside attack. Expected execution time: 25sec on average"); - PrintAndLogEx(NORMAL, "press pm3-button on the proxmark3 device to abort both proxmark3 and client."); - PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); - - while (true) { - clearCommandBuffer(); - SendCommand(&c); - - //flush queue - while (ukbhit()) { - int gc = getchar(); (void)gc; - return -5; - } - - // wait cycle - while (true) { - printf("."); fflush(stdout); - if (ukbhit()) { - int gc = getchar(); (void)gc; - return -5; - } - - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - isOK = resp.arg[0]; - if (isOK < 0) - return isOK; - - uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4); - nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); - par_list = bytes_to_num(resp.d.asBytes + 8, 8); - ks_list = bytes_to_num(resp.d.asBytes + 16, 8); - nr = (uint32_t)bytes_to_num(resp.d.asBytes + 24, 4); - ar = (uint32_t)bytes_to_num(resp.d.asBytes + 28, 4); - break; - } - } - PrintAndLogEx(NORMAL, "\n"); - - if (par_list == 0 && c.arg[0] == true) { - PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication."); - } - c.arg[0] = false; - - keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist); - - if (keycount == 0) { - PrintAndLogEx(FAILED, "key not found (lfsr_common_prefix list is null). Nt=%08x", nt); - PrintAndLogEx(FAILED, "this is expected to happen in 25%% of all cases. Trying again with a different reader nonce..."); - continue; - } - - // only parity zero attack - if (par_list == 0 ) { - qsort(keylist, keycount, sizeof(*keylist), compare_uint64); - keycount = intersection(last_keylist, keylist); - if (keycount == 0) { - free(last_keylist); - last_keylist = keylist; - PrintAndLogEx(FAILED, "no candidates found, trying again"); - continue; - } - } - - PrintAndLogEx(SUCCESS, "found %u candidate key%s\n", keycount, (keycount > 1) ? "s." : "."); - - *key = -1; - uint8_t keyBlock[USB_CMD_DATA_SIZE]; - int max_keys = USB_CMD_DATA_SIZE / 6; - for (int i = 0; i < keycount; i += max_keys) { - - int size = keycount - i > max_keys ? max_keys : keycount - i; - for (int j = 0; j < size; j++) { - if (par_list == 0) { - num_to_bytes(last_keylist[i*max_keys + j], 6, keyBlock+(j*6)); - } else { - num_to_bytes(keylist[i*max_keys + j], 6, keyBlock+(j*6)); - } - } - - if (!mfCheckKeys(blockno, key_type - 0x60, false, size, keyBlock, key)) { - break; - } - } - - if (*key != -1) { - break; - } else { - PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack"); - free(last_keylist); - last_keylist = keylist; - c.arg[0] = true; - } - } - free(last_keylist); - free(keylist); - return 0; -} -int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ - *key = -1; - UsbCommand c = {CMD_MIFARE_CHKKEYS, { (blockNo | (keyType << 8)), clear_trace, keycnt}}; - memcpy(c.d.asBytes, keyBlock, 6 * keycnt); - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) return 1; - if ((resp.arg[0] & 0xff) != 0x01) return 2; - *key = bytes_to_num(resp.d.asBytes, 6); - return 0; -} - -// Sends chunks of keys to device. -// 0 == ok all keys found -// 1 == -// 2 == Time-out, aborting -int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, - uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory) { - - uint64_t t2 = msclock(); - uint32_t timeout = 0; - - // send keychunk - UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (sectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), ((use_flashmemory << 8) | strategy), size}}; - memcpy(c.d.asBytes, keyBlock, 6 * size); - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - - while ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { - timeout++; - printf("."); fflush(stdout); - // max timeout for one chunk of 85keys, 60*3sec = 180seconds - // s70 with 40*2 keys to check, 80*85 = 6800 auth. - // takes about 97s, still some margin before abort - if (timeout > 180) { - PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); - return 2; - } - } - t2 = msclock() - t2; - - // time to convert the returned data. - uint8_t curr_keys = resp.arg[0]; - - PrintAndLogEx(SUCCESS, "\nChunk: %.1fs | found %u/%u keys (%u)", (float)(t2/1000.0), curr_keys, (sectorsCnt<<1), size); - - // all keys? - if ( curr_keys == sectorsCnt*2 || lastChunk ) { - - // success array. each byte is status of key - uint8_t arr[80]; - uint64_t foo = 0; - uint16_t bar = 0; - foo = bytes_to_num(resp.d.asBytes+480, 8); - bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]); - - for (uint8_t i = 0; i < 64; i++) - arr[i] = (foo >> i) & 0x1; - - for (uint8_t i = 0; i < 16; i++) - arr[i+64] = (bar >> i) & 0x1; - - // initialize storage for found keys - icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); - if (tmp == NULL) - return 1; - memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) ); - - for ( int i = 0; i < sectorsCnt; i++) { - // key A - if ( !e_sector[i].foundKey[0] ) { - e_sector[i].Key[0] = bytes_to_num( tmp[i].keyA, 6); - e_sector[i].foundKey[0] = arr[ (i*2) ]; - } - // key B - if ( !e_sector[i].foundKey[1] ) { - e_sector[i].Key[1] = bytes_to_num( tmp[i].keyB, 6); - e_sector[i].foundKey[1] = arr[ (i*2) + 1 ]; - } - } - free(tmp); - - if ( curr_keys == sectorsCnt*2 ) - return 0; - if ( lastChunk ) - return 1; - } - return 1; -} - -// PM3 imp of J-Run mf_key_brute (part 2) -// ref: https://github.com/J-Run/mf_key_brute -int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey){ - - #define KEYS_IN_BLOCK 85 - #define KEYBLOCK_SIZE 510 - #define CANDIDATE_SIZE 0xFFFF * 6 - uint8_t found = false; - uint64_t key64 = 0; - uint8_t candidates[CANDIDATE_SIZE] = {0x00}; - uint8_t keyBlock[KEYBLOCK_SIZE] = {0x00}; - - memset(candidates, 0, sizeof(candidates)); - memset(keyBlock, 0, sizeof(keyBlock)); - - // Generate all possible keys for the first two unknown bytes. - for (uint16_t i = 0; i < 0xFFFF; ++i) { - uint32_t j = i * 6; - candidates[0 + j] = i >> 8; - candidates[1 + j] = i; - candidates[2 + j] = key[2]; - candidates[3 + j] = key[3]; - candidates[4 + j] = key[4]; - candidates[5 + j] = key[5]; - } - uint32_t counter, i; - for ( i = 0, counter = 1; i < CANDIDATE_SIZE; i += KEYBLOCK_SIZE, ++counter){ - - key64 = 0; - - // copy candidatekeys to test key block - memcpy(keyBlock, candidates + i, KEYBLOCK_SIZE); - - // check a block of generated candidate keys. - if (!mfCheckKeys(blockNo, keyType, true, KEYS_IN_BLOCK, keyBlock, &key64)) { - *resultkey = key64; - found = true; - break; - } - - // progress - if ( counter % 20 == 0 ) - PrintAndLogEx(SUCCESS, "tried : %s.. \t %u keys", sprint_hex(candidates + i, 6), counter * KEYS_IN_BLOCK ); - } - return found; -} - -// Compare 16 Bits out of cryptostate -int Compare16Bits(const void * a, const void * b) { - if ((*(uint64_t*)b & 0x00ff000000ff0000) == (*(uint64_t*)a & 0x00ff000000ff0000)) return 0; - if ((*(uint64_t*)b & 0x00ff000000ff0000) > (*(uint64_t*)a & 0x00ff000000ff0000)) return 1; - return -1; -} - -// wrapper function for multi-threaded lfsr_recovery32 -void -#ifdef __has_attribute -#if __has_attribute(force_align_arg_pointer) -__attribute__((force_align_arg_pointer)) -#endif -#endif -*nested_worker_thread(void *arg) { - struct Crypto1State *p1; - StateList_t *statelist = arg; - statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid); - - for (p1 = statelist->head.slhead; *(uint64_t *)p1 != 0; p1++) {}; - - statelist->len = p1 - statelist->head.slhead; - statelist->tail.sltail = --p1; - qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits); - - return statelist->head.slhead; -} - -int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) { - uint16_t i; - uint32_t uid; - UsbCommand resp; - StateList_t statelists[2]; - struct Crypto1State *p1, *p2, *p3, *p4; - - UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}}; - memcpy(c.d.asBytes, key, 6); - clearCommandBuffer(); - SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; - - // error during nested - if (resp.arg[0]) return resp.arg[0]; - - memcpy(&uid, resp.d.asBytes, 4); - - for (i = 0; i < 2; i++) { - statelists[i].blockNo = resp.arg[2] & 0xff; - statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; - statelists[i].uid = uid; - memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); - memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); - } - - // calc keys - pthread_t thread_id[2]; - - // create and run worker threads - for (i = 0; i < 2; i++) - pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]); - - // wait for threads to terminate: - for (i = 0; i < 2; i++) - pthread_join(thread_id[i], (void*)&statelists[i].head.slhead); - - // the first 16 Bits of the cryptostate already contain part of our key. - // Create the intersection of the two lists based on these 16 Bits and - // roll back the cryptostate - p1 = p3 = statelists[0].head.slhead; - p2 = p4 = statelists[1].head.slhead; - - while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) { - if (Compare16Bits(p1, p2) == 0) { - - struct Crypto1State savestate, *savep = &savestate; - savestate = *p1; - while(Compare16Bits(p1, savep) == 0 && p1 <= statelists[0].tail.sltail) { - *p3 = *p1; - lfsr_rollback_word(p3, statelists[0].nt ^ statelists[0].uid, 0); - p3++; - p1++; - } - savestate = *p2; - while(Compare16Bits(p2, savep) == 0 && p2 <= statelists[1].tail.sltail) { - *p4 = *p2; - lfsr_rollback_word(p4, statelists[1].nt ^ statelists[1].uid, 0); - p4++; - p2++; - } - } - else { - while (Compare16Bits(p1, p2) == -1) p1++; - while (Compare16Bits(p1, p2) == 1) p2++; - } - } - - *(uint64_t*)p3 = -1; - *(uint64_t*)p4 = -1; - statelists[0].len = p3 - statelists[0].head.slhead; - statelists[1].len = p4 - statelists[1].head.slhead; - statelists[0].tail.sltail = --p3; - statelists[1].tail.sltail = --p4; - - // the statelists now contain possible keys. The key we are searching for must be in the - // intersection of both lists - qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64); - qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64); - // Create the intersection - statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead); - - //statelists[0].tail.keytail = --p7; - uint32_t keycnt = statelists[0].len; - if ( keycnt == 0 ) goto out; - - memset(resultKey, 0, 6); - uint64_t key64 = -1; - - // The list may still contain several key candidates. Test each of them with mfCheckKeys - uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt; - uint8_t keyBlock[USB_CMD_DATA_SIZE] = {0x00}; - - for (int i = 0; i < keycnt; i += max_keys) { - - int size = keycnt - i > max_keys ? max_keys : keycnt - i; - - for (int j = 0; j < size; j++) { - crypto1_get_lfsr(statelists[0].head.slhead + i, &key64); - num_to_bytes(key64, 6, keyBlock + i * 6); - } - - if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, keyBlock, &key64)) { - free(statelists[0].head.slhead); - free(statelists[1].head.slhead); - num_to_bytes(key64, 6, resultKey); - - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [%012" PRIx64 "]", - (uint16_t)resp.arg[2] & 0xff, - (resp.arg[2] >> 8) ? 'B' : 'A', - key64 - ); - return -5; - } - } - -out: - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c", - (uint16_t)resp.arg[2] & 0xff, - (resp.arg[2] >> 8) ? 'B' : 'A' - ); - - free(statelists[0].head.slhead); - free(statelists[1].head.slhead); - return -4; -} - -// MIFARE -int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { - - UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - clearCommandBuffer(); - SendCommand(&c); - - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - - if (isOK) { - memcpy(data, resp.d.asBytes, mfNumBlocksPerSector(sectorNo) * 16); - for (int i = 0; i < (sectorNo<32?3:15); i++) { - PrintAndLogEx(NORMAL, "data : %s", sprint_hex(data + i * 16, 16)); - } - PrintAndLogEx(NORMAL, "trailer: %s", sprint_hex(data + (sectorNo<32?3:15) * 16, 16)); - - return 0; - } else { - return isOK; - } - } else { - PrintAndLogEx(ERR, "Command execute timeout"); - return 2; - } - - return 0; -} - -// EMULATOR -int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { - UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 1; - memcpy(data, resp.d.asBytes, blocksCount * 16); - return 0; -} - -int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { - return mfEmlSetMem_xt(data, blockNum, blocksCount, 16); -} - -int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) { - UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, blockBtWidth}}; - memcpy(c.d.asBytes, data, blocksCount * blockBtWidth); - clearCommandBuffer(); - SendCommand(&c); - return 0; -} - -// "MAGIC" CARD -int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) { - - uint8_t params = MAGIC_SINGLE; - uint8_t block0[16]; - memset(block0, 0x00, sizeof(block0)); - - int old = mfCGetBlock(0, block0, params); - if (old == 0) - PrintAndLogEx(SUCCESS, "old block 0: %s", sprint_hex(block0, sizeof(block0))); - else - PrintAndLogEx(FAILED, "couldn't get old data. Will write over the last bytes of Block 0."); - - // fill in the new values - // UID - memcpy(block0, uid, 4); - // Mifare UID BCC - block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3]; - // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed) - if ( sak != NULL ) - block0[5] = sak[0]; - - if ( atqa != NULL ) { - block0[6] = atqa[1]; - block0[7] = atqa[0]; - } - PrintAndLogEx(SUCCESS, "new block 0: %s", sprint_hex(block0,16)); - - if ( wipecard ) params |= MAGIC_WIPE; - if ( oldUID == NULL) params |= MAGIC_UID; - - return mfCSetBlock(0, block0, oldUID, params); -} - -int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { - - uint8_t isOK = 0; - UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}}; - memcpy(c.d.asBytes, data, 16); - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - isOK = resp.arg[0] & 0xff; - if (uid != NULL) - memcpy(uid, resp.d.asBytes, 4); - if (!isOK) - return 2; - } else { - PrintAndLogEx(WARNING, "command execute timeout"); - return 1; - } - return 0; -} - -int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { - uint8_t isOK = 0; - UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - isOK = resp.arg[0] & 0xff; - if (!isOK) - return 2; - memcpy(data, resp.d.asBytes, 16); - } else { - PrintAndLogEx(WARNING, "command execute timeout"); - return 1; - } - return 0; -} - -// SNIFFER -// [iceman] so many global variables.... - -// constants -static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00}; - -// variables -char logHexFileName[FILE_PATH_SIZE] = {0x00}; -static uint8_t traceCard[4096] = {0x00}; -static char traceFileName[FILE_PATH_SIZE] = {0x00}; -static int traceState = TRACE_IDLE; -static uint8_t traceCurBlock = 0; -static uint8_t traceCurKey = 0; - -struct Crypto1State *traceCrypto1 = NULL; -struct Crypto1State *revstate = NULL; -uint64_t key = 0; -uint32_t ks2 = 0; -uint32_t ks3 = 0; - -uint32_t cuid = 0; // uid part used for crypto1. -uint32_t nt = 0; // tag challenge -uint32_t nr_enc = 0; // encrypted reader challenge -uint32_t ar_enc = 0; // encrypted reader response -uint32_t at_enc = 0; // encrypted tag response - -int isTraceCardEmpty(void) { - return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0)); -} - -int isBlockEmpty(int blockN) { - for (int i = 0; i < 16; i++) - if (traceCard[blockN * 16 + i] != 0) return 0; - - return 1; -} - -int isBlockTrailer(int blockN) { - return ((blockN & 0x03) == 0x03); -} - -int loadTraceCard(uint8_t *tuid, uint8_t uidlen) { - FILE * f; - char buf[64] = {0x00}; - uint8_t buf8[64] = {0x00}; - int i, blockNum; - uint32_t tmp; - - if (!isTraceCardEmpty()) - saveTraceCard(); - - memset(traceCard, 0x00, 4096); - memcpy(traceCard, tuid, uidlen); - - FillFileNameByUID(traceFileName, tuid, ".eml", uidlen); - - f = fopen(traceFileName, "r"); - if (!f) return 1; - - blockNum = 0; - - while (!feof(f)){ - - memset(buf, 0, sizeof(buf)); - if (fgets(buf, sizeof(buf), f) == NULL) { - PrintAndLogEx(FAILED, "No trace file found or reading error."); - if (f) { - fclose(f); - } - return 2; - } - - if (strlen(buf) < 32){ - if (feof(f)) break; - PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols"); - if (f) { - fclose(f); - } - return 2; - } - for (i = 0; i < 32; i += 2) { - sscanf(&buf[i], "%02X", &tmp); - buf8[i / 2] = tmp & 0xFF; - } - - memcpy(traceCard + blockNum * 16, buf8, 16); - - blockNum++; - } - if (f) { - fclose(f); - } - return 0; -} - -int saveTraceCard(void) { - - if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; - - FILE * f; - f = fopen(traceFileName, "w+"); - if ( !f ) return 1; - - // given 4096 tracecard size, these loop will only match a 1024, 1kb card memory - // 4086/16 == 256blocks. - for (uint16_t i = 0; i < 256; i++) { // blocks - for (uint8_t j = 0; j < 16; j++) // bytes - fprintf(f, "%02X", *(traceCard + i * 16 + j)); - - // no extra line in the end - if ( i < 255 ) - fprintf(f, "\n"); - } - fflush(f); - fclose(f); - return 0; -} -// -int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) { - - if (traceCrypto1) - crypto1_destroy(traceCrypto1); - - traceCrypto1 = NULL; - - if (wantSaveToEmlFile) - loadTraceCard(tuid, uidlen); - - traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3]; - traceCard[5] = sak; - memcpy(&traceCard[6], atqa, 2); - traceCurBlock = 0; - cuid = bytes_to_num(tuid + (uidlen-4), 4); - traceState = TRACE_IDLE; - return 0; -} - -void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted){ - uint8_t bt = 0; - int i; - - if (len != 1) { - for (i = 0; i < len; i++) - data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i]; - } else { - bt = 0; - bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 0)) << 0; - bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 1)) << 1; - bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 2)) << 2; - bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 3)) << 3; - data[0] = bt; - } -} - -int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { - - if (traceState == TRACE_ERROR) - return 1; - - if (len > 255) { - traceState = TRACE_ERROR; - return 1; - } - - uint8_t data[255]; - memset(data, 0x00, sizeof(data)); - - memcpy(data, data_src, len); - - if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) { - mf_crypto1_decrypt(traceCrypto1, data, len, 0); - PrintAndLogEx(NORMAL, "DEC| %s", sprint_hex(data, len)); - AddLogHex(logHexFileName, "DEC| ", data, len); - } - - switch (traceState) { - case TRACE_IDLE: - // check packet crc16! - if ((len >= 4) && (!check_crc(CRC_14443_A, data, len))) { - PrintAndLogEx(NORMAL, "DEC| CRC ERROR!!!"); - AddLogLine(logHexFileName, "DEC| ", "CRC ERROR!!!"); - traceState = TRACE_ERROR; // do not decrypt the next commands - return 1; - } - - // AUTHENTICATION - if ((len == 4) && ((data[0] == MIFARE_AUTH_KEYA) || (data[0] == MIFARE_AUTH_KEYB))) { - traceState = TRACE_AUTH1; - traceCurBlock = data[1]; - traceCurKey = data[0] == 60 ? 1:0; - return 0; - } - - // READ - if ((len == 4) && ((data[0] == ISO14443A_CMD_READBLOCK))) { - traceState = TRACE_READ_DATA; - traceCurBlock = data[1]; - return 0; - } - - // WRITE - if ((len == 4) && ((data[0] == ISO14443A_CMD_WRITEBLOCK))) { - traceState = TRACE_WRITE_OK; - traceCurBlock = data[1]; - return 0; - } - - // HALT - if ((len == 4) && ((data[0] == ISO14443A_CMD_HALT) && (data[1] == 0x00))) { - traceState = TRACE_ERROR; // do not decrypt the next commands - return 0; - } - return 0; - - case TRACE_READ_DATA: - if (len == 18) { - traceState = TRACE_IDLE; - - if (isBlockTrailer(traceCurBlock)) { - memcpy(traceCard + traceCurBlock * 16 + 6, data + 6, 4); - } else { - memcpy(traceCard + traceCurBlock * 16, data, 16); - } - if (wantSaveToEmlFile) saveTraceCard(); - return 0; - } else { - traceState = TRACE_ERROR; - return 1; - } - break; - case TRACE_WRITE_OK: - if ((len == 1) && (data[0] == 0x0a)) { - traceState = TRACE_WRITE_DATA; - return 0; - } else { - traceState = TRACE_ERROR; - return 1; - } - break; - case TRACE_WRITE_DATA: - if (len == 18) { - traceState = TRACE_IDLE; - memcpy(traceCard + traceCurBlock * 16, data, 16); - if (wantSaveToEmlFile) saveTraceCard(); - return 0; - } else { - traceState = TRACE_ERROR; - return 1; - } - break; - case TRACE_AUTH1: - if (len == 4) { - traceState = TRACE_AUTH2; - nt = bytes_to_num(data, 4); - return 0; - } else { - traceState = TRACE_ERROR; - return 1; - } - break; - case TRACE_AUTH2: - if (len == 8) { - traceState = TRACE_AUTH_OK; - nr_enc = bytes_to_num(data, 4); - ar_enc = bytes_to_num(data + 4, 4); - return 0; - } else { - traceState = TRACE_ERROR; - return 1; - } - break; - case TRACE_AUTH_OK: - if (len == 4) { - traceState = TRACE_IDLE; - at_enc = bytes_to_num(data, 4); - - // mfkey64 recover key. - ks2 = ar_enc ^ prng_successor(nt, 64); - ks3 = at_enc ^ prng_successor(nt, 96); - revstate = lfsr_recovery64(ks2, ks3); - lfsr_rollback_word(revstate, 0, 0); - lfsr_rollback_word(revstate, 0, 0); - lfsr_rollback_word(revstate, nr_enc, 1); - lfsr_rollback_word(revstate, cuid ^ nt, 0); - crypto1_get_lfsr(revstate, &key); - PrintAndLogEx(SUCCESS, "found Key: [%012" PRIx64 "]", key); - - //if ( tryMfk64(cuid, nt, nr_enc, ar_enc, at_enc, &key) ) - AddLogUint64(logHexFileName, "Found Key: ", key); - - int blockShift = ((traceCurBlock & 0xFC) + 3) * 16; - if (isBlockEmpty((traceCurBlock & 0xFC) + 3)) - memcpy(traceCard + blockShift + 6, trailerAccessBytes, 4); - - // keytype A/B - if (traceCurKey) - num_to_bytes(key, 6, traceCard + blockShift + 10); - else - num_to_bytes(key, 6, traceCard + blockShift); - - if (wantSaveToEmlFile) - saveTraceCard(); - - if (traceCrypto1) - crypto1_destroy(traceCrypto1); - - // set cryptosystem state - traceCrypto1 = lfsr_recovery64(ks2, ks3); - - } else { - PrintAndLogEx(NORMAL, "[!] nested key recovery not implemented!\n"); - at_enc = bytes_to_num(data, 4); - crypto1_destroy(traceCrypto1); - traceState = TRACE_ERROR; - } - break; - default: - traceState = TRACE_ERROR; - return 1; - } - return 0; -} - -int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){ - PrintAndLogEx(SUCCESS, "\nencrypted data: [%s]", sprint_hex(data, len) ); - struct Crypto1State *s; - ks2 = ar_enc ^ prng_successor(nt, 64); - ks3 = at_enc ^ prng_successor(nt, 96); - s = lfsr_recovery64(ks2, ks3); - mf_crypto1_decrypt(s, data, len, false); - PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len) ); - crypto1_destroy(s); - return 0; -} - -/* Detect Tag Prng, -* function performs a partial AUTH, where it tries to authenticate against block0, key A, but only collects tag nonce. -* the tag nonce is check to see if it has a predictable PRNG. -* @returns -* TRUE if tag uses WEAK prng (ie Now the NACK bug also needs to be present for Darkside attack) -* FALSE is tag uses HARDEND prng (ie hardnested attack possible, with known key) -*/ -int detect_classic_prng(void){ - - UsbCommand resp, respA; - uint8_t cmd[] = {MIFARE_AUTH_KEYA, 0x00}; - uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; - - UsbCommand c = {CMD_READER_ISO_14443a, {flags, sizeof(cmd), 0}}; - memcpy(c.d.asBytes, cmd, sizeof(cmd)); - - clearCommandBuffer(); - SendCommand(&c); - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "PRNG UID: Reply timeout."); - return -1; - } - - // if select tag failed. - if ( resp.arg[0] == 0 ) { - PrintAndLogEx(WARNING, "error: selecting tag failed, can't detect prng\n"); - return -2; - } - if (!WaitForResponseTimeout(CMD_ACK, &respA, 2500)) { - PrintAndLogEx(WARNING, "PRNG data: Reply timeout."); - return -3; - } - - // check respA - if (respA.arg[0] != 4) { - PrintAndLogEx(WARNING, "PRNG data error: Wrong length: %d", respA.arg[0]); - return -4; - } - - uint32_t nonce = bytes_to_num(respA.d.asBytes, respA.arg[0]); - return validate_prng_nonce(nonce); -} -/* Detect Mifare Classic NACK bug - -returns: -0 = error during test / aborted -1 = has nack bug -2 = has not nack bug -3 = always leak nacks (clones) -*/ -int detect_classic_nackbug(bool verbose){ - - UsbCommand c = {CMD_MIFARE_NACK_DETECT, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - - if ( verbose ) - PrintAndLogEx(SUCCESS, "press pm3-button on the proxmark3 device to abort both proxmark3 and client.\n"); - - // for nice animation - bool term = !isatty(STDIN_FILENO); -#if defined(__linux__) || (__APPLE__) - char star[] = {'-', '\\', '|', '/'}; - uint8_t staridx = 0; -#endif - - while (true) { - - if (term) { - printf("."); - } else { - printf( - #if defined(__linux__) || (__APPLE__) - "\e[32m\e[s%c\e[u\e[0m", star[ (staridx++ % 4) ] - #else - "." - #endif - ); - } - fflush(stdout); - if (ukbhit()) { - int gc = getchar(); (void)gc; - return -1; - break; - } - - if (WaitForResponseTimeout(CMD_ACK, &resp, 500)) { - int32_t ok = resp.arg[0]; - uint32_t nacks = resp.arg[1]; - uint32_t auths = resp.arg[2]; - PrintAndLogEx(NORMAL, ""); - - if ( verbose ) { - PrintAndLogEx(SUCCESS, "num of auth requests : %u", auths); - PrintAndLogEx(SUCCESS, "num of received NACK : %u", nacks); - } - switch( ok ) { - case 99 : PrintAndLogEx(WARNING, "button pressed. Aborted."); return 0; - case 96 : - case 98 : { - if (verbose) - PrintAndLogEx(FAILED, "card random number generator is not predictable."); - PrintAndLogEx(WARNING, "detection failed"); - return 2; - } - case 97 : { - if (verbose) { - PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial"); - PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again."); - return 0; - } - } - case 2 : PrintAndLogEx(SUCCESS, "always leak NACK detected"); return 3; - case 1 : PrintAndLogEx(SUCCESS, "NACK bug detected"); return 1; - case 0 : PrintAndLogEx(SUCCESS, "No NACK bug detected"); return 2; - default : PrintAndLogEx(WARNING, "errorcode from device [%i]", ok); return 0; - } - break; - } - } - return 0; -} -/* try to see if card responses to "chinese magic backdoor" commands. */ -void detect_classic_magic(void) { - - uint8_t isGeneration = 0; - UsbCommand resp; - UsbCommand c = {CMD_MIFARE_CIDENT, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) - isGeneration = resp.arg[0] & 0xff; - - switch( isGeneration ){ - case 1: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): YES"); break; - case 2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): YES"); break; - //case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2): YES"); break; - default: PrintAndLogEx(INFO, "Answers to magic commands: NO"); break; - } +// Merlok, 2011, 2012 +// people from mifare@nethemba.com, 2010 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// mifare commands +//----------------------------------------------------------------------------- +#include "mifarehost.h" +#include "cmdmain.h" + +int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { + uint32_t uid = 0; + uint32_t nt = 0, nr = 0, ar = 0; + uint64_t par_list = 0, ks_list = 0; + uint64_t *keylist = NULL, *last_keylist = NULL; + uint32_t keycount = 0; + int16_t isOK = 0; + + UsbCommand c = {CMD_READER_MIFARE, {true, blockno, key_type}}; + + // message + PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); + PrintAndLogEx(NORMAL, "executing Darkside attack. Expected execution time: 25sec on average"); + PrintAndLogEx(NORMAL, "press pm3-button on the proxmark3 device to abort both proxmark3 and client."); + PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); + + while (true) { + clearCommandBuffer(); + SendCommand(&c); + + //flush queue + while (ukbhit()) { + int gc = getchar(); (void)gc; + return -5; + } + + // wait cycle + while (true) { + printf("."); fflush(stdout); + if (ukbhit()) { + int gc = getchar(); (void)gc; + return -5; + } + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + isOK = resp.arg[0]; + if (isOK < 0) + return isOK; + + uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4); + nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); + par_list = bytes_to_num(resp.d.asBytes + 8, 8); + ks_list = bytes_to_num(resp.d.asBytes + 16, 8); + nr = (uint32_t)bytes_to_num(resp.d.asBytes + 24, 4); + ar = (uint32_t)bytes_to_num(resp.d.asBytes + 28, 4); + break; + } + } + PrintAndLogEx(NORMAL, "\n"); + + if (par_list == 0 && c.arg[0] == true) { + PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication."); + } + c.arg[0] = false; + + keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist); + + if (keycount == 0) { + PrintAndLogEx(FAILED, "key not found (lfsr_common_prefix list is null). Nt=%08x", nt); + PrintAndLogEx(FAILED, "this is expected to happen in 25%% of all cases. Trying again with a different reader nonce..."); + continue; + } + + // only parity zero attack + if (par_list == 0 ) { + qsort(keylist, keycount, sizeof(*keylist), compare_uint64); + keycount = intersection(last_keylist, keylist); + if (keycount == 0) { + free(last_keylist); + last_keylist = keylist; + PrintAndLogEx(FAILED, "no candidates found, trying again"); + continue; + } + } + + PrintAndLogEx(SUCCESS, "found %u candidate key%s\n", keycount, (keycount > 1) ? "s." : "."); + + *key = -1; + uint8_t keyBlock[USB_CMD_DATA_SIZE]; + int max_keys = USB_CMD_DATA_SIZE / 6; + for (int i = 0; i < keycount; i += max_keys) { + + int size = keycount - i > max_keys ? max_keys : keycount - i; + for (int j = 0; j < size; j++) { + if (par_list == 0) { + num_to_bytes(last_keylist[i*max_keys + j], 6, keyBlock+(j*6)); + } else { + num_to_bytes(keylist[i*max_keys + j], 6, keyBlock+(j*6)); + } + } + + if (!mfCheckKeys(blockno, key_type - 0x60, false, size, keyBlock, key)) { + break; + } + } + + if (*key != -1) { + break; + } else { + PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack"); + free(last_keylist); + last_keylist = keylist; + c.arg[0] = true; + } + } + free(last_keylist); + free(keylist); + return 0; +} +int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ + *key = -1; + UsbCommand c = {CMD_MIFARE_CHKKEYS, { (blockNo | (keyType << 8)), clear_trace, keycnt}}; + memcpy(c.d.asBytes, keyBlock, 6 * keycnt); + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) return 1; + if ((resp.arg[0] & 0xff) != 0x01) return 2; + *key = bytes_to_num(resp.d.asBytes, 6); + return 0; +} + +// Sends chunks of keys to device. +// 0 == ok all keys found +// 1 == +// 2 == Time-out, aborting +int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, + uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory) { + + uint64_t t2 = msclock(); + uint32_t timeout = 0; + + // send keychunk + UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (sectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), ((use_flashmemory << 8) | strategy), size}}; + memcpy(c.d.asBytes, keyBlock, 6 * size); + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + + while ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { + timeout++; + printf("."); fflush(stdout); + // max timeout for one chunk of 85keys, 60*3sec = 180seconds + // s70 with 40*2 keys to check, 80*85 = 6800 auth. + // takes about 97s, still some margin before abort + if (timeout > 180) { + PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); + return 2; + } + } + t2 = msclock() - t2; + + // time to convert the returned data. + uint8_t curr_keys = resp.arg[0]; + + PrintAndLogEx(SUCCESS, "\nChunk: %.1fs | found %u/%u keys (%u)", (float)(t2/1000.0), curr_keys, (sectorsCnt<<1), size); + + // all keys? + if ( curr_keys == sectorsCnt*2 || lastChunk ) { + + // success array. each byte is status of key + uint8_t arr[80]; + uint64_t foo = 0; + uint16_t bar = 0; + foo = bytes_to_num(resp.d.asBytes+480, 8); + bar = (resp.d.asBytes[489] << 8 | resp.d.asBytes[488]); + + for (uint8_t i = 0; i < 64; i++) + arr[i] = (foo >> i) & 0x1; + + for (uint8_t i = 0; i < 16; i++) + arr[i+64] = (bar >> i) & 0x1; + + // initialize storage for found keys + icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); + if (tmp == NULL) + return 1; + memcpy(tmp, resp.d.asBytes, sectorsCnt * sizeof(icesector_t) ); + + for ( int i = 0; i < sectorsCnt; i++) { + // key A + if ( !e_sector[i].foundKey[0] ) { + e_sector[i].Key[0] = bytes_to_num( tmp[i].keyA, 6); + e_sector[i].foundKey[0] = arr[ (i*2) ]; + } + // key B + if ( !e_sector[i].foundKey[1] ) { + e_sector[i].Key[1] = bytes_to_num( tmp[i].keyB, 6); + e_sector[i].foundKey[1] = arr[ (i*2) + 1 ]; + } + } + free(tmp); + + if ( curr_keys == sectorsCnt*2 ) + return 0; + if ( lastChunk ) + return 1; + } + return 1; +} + +// PM3 imp of J-Run mf_key_brute (part 2) +// ref: https://github.com/J-Run/mf_key_brute +int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey){ + + #define KEYS_IN_BLOCK 85 + #define KEYBLOCK_SIZE 510 + #define CANDIDATE_SIZE 0xFFFF * 6 + uint8_t found = false; + uint64_t key64 = 0; + uint8_t candidates[CANDIDATE_SIZE] = {0x00}; + uint8_t keyBlock[KEYBLOCK_SIZE] = {0x00}; + + memset(candidates, 0, sizeof(candidates)); + memset(keyBlock, 0, sizeof(keyBlock)); + + // Generate all possible keys for the first two unknown bytes. + for (uint16_t i = 0; i < 0xFFFF; ++i) { + uint32_t j = i * 6; + candidates[0 + j] = i >> 8; + candidates[1 + j] = i; + candidates[2 + j] = key[2]; + candidates[3 + j] = key[3]; + candidates[4 + j] = key[4]; + candidates[5 + j] = key[5]; + } + uint32_t counter, i; + for ( i = 0, counter = 1; i < CANDIDATE_SIZE; i += KEYBLOCK_SIZE, ++counter){ + + key64 = 0; + + // copy candidatekeys to test key block + memcpy(keyBlock, candidates + i, KEYBLOCK_SIZE); + + // check a block of generated candidate keys. + if (!mfCheckKeys(blockNo, keyType, true, KEYS_IN_BLOCK, keyBlock, &key64)) { + *resultkey = key64; + found = true; + break; + } + + // progress + if ( counter % 20 == 0 ) + PrintAndLogEx(SUCCESS, "tried : %s.. \t %u keys", sprint_hex(candidates + i, 6), counter * KEYS_IN_BLOCK ); + } + return found; +} + +// Compare 16 Bits out of cryptostate +int Compare16Bits(const void * a, const void * b) { + if ((*(uint64_t*)b & 0x00ff000000ff0000) == (*(uint64_t*)a & 0x00ff000000ff0000)) return 0; + if ((*(uint64_t*)b & 0x00ff000000ff0000) > (*(uint64_t*)a & 0x00ff000000ff0000)) return 1; + return -1; +} + +// wrapper function for multi-threaded lfsr_recovery32 +void +#ifdef __has_attribute +#if __has_attribute(force_align_arg_pointer) +__attribute__((force_align_arg_pointer)) +#endif +#endif +*nested_worker_thread(void *arg) { + struct Crypto1State *p1; + StateList_t *statelist = arg; + statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid); + + for (p1 = statelist->head.slhead; *(uint64_t *)p1 != 0; p1++) {}; + + statelist->len = p1 - statelist->head.slhead; + statelist->tail.sltail = --p1; + qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits); + + return statelist->head.slhead; +} + +int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) { + uint16_t i; + uint32_t uid; + UsbCommand resp; + StateList_t statelists[2]; + struct Crypto1State *p1, *p2, *p3, *p4; + + UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}}; + memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; + + // error during nested + if (resp.arg[0]) return resp.arg[0]; + + memcpy(&uid, resp.d.asBytes, 4); + + for (i = 0; i < 2; i++) { + statelists[i].blockNo = resp.arg[2] & 0xff; + statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; + statelists[i].uid = uid; + memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); + memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); + } + + // calc keys + pthread_t thread_id[2]; + + // create and run worker threads + for (i = 0; i < 2; i++) + pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]); + + // wait for threads to terminate: + for (i = 0; i < 2; i++) + pthread_join(thread_id[i], (void*)&statelists[i].head.slhead); + + // the first 16 Bits of the cryptostate already contain part of our key. + // Create the intersection of the two lists based on these 16 Bits and + // roll back the cryptostate + p1 = p3 = statelists[0].head.slhead; + p2 = p4 = statelists[1].head.slhead; + + while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) { + if (Compare16Bits(p1, p2) == 0) { + + struct Crypto1State savestate, *savep = &savestate; + savestate = *p1; + while(Compare16Bits(p1, savep) == 0 && p1 <= statelists[0].tail.sltail) { + *p3 = *p1; + lfsr_rollback_word(p3, statelists[0].nt ^ statelists[0].uid, 0); + p3++; + p1++; + } + savestate = *p2; + while(Compare16Bits(p2, savep) == 0 && p2 <= statelists[1].tail.sltail) { + *p4 = *p2; + lfsr_rollback_word(p4, statelists[1].nt ^ statelists[1].uid, 0); + p4++; + p2++; + } + } + else { + while (Compare16Bits(p1, p2) == -1) p1++; + while (Compare16Bits(p1, p2) == 1) p2++; + } + } + + *(uint64_t*)p3 = -1; + *(uint64_t*)p4 = -1; + statelists[0].len = p3 - statelists[0].head.slhead; + statelists[1].len = p4 - statelists[1].head.slhead; + statelists[0].tail.sltail = --p3; + statelists[1].tail.sltail = --p4; + + // the statelists now contain possible keys. The key we are searching for must be in the + // intersection of both lists + qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64); + qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64); + // Create the intersection + statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead); + + //statelists[0].tail.keytail = --p7; + uint32_t keycnt = statelists[0].len; + if ( keycnt == 0 ) goto out; + + memset(resultKey, 0, 6); + uint64_t key64 = -1; + + // The list may still contain several key candidates. Test each of them with mfCheckKeys + uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt; + uint8_t keyBlock[USB_CMD_DATA_SIZE] = {0x00}; + + for (int i = 0; i < keycnt; i += max_keys) { + + int size = keycnt - i > max_keys ? max_keys : keycnt - i; + + for (int j = 0; j < size; j++) { + crypto1_get_lfsr(statelists[0].head.slhead + i, &key64); + num_to_bytes(key64, 6, keyBlock + i * 6); + } + + if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, size, keyBlock, &key64)) { + free(statelists[0].head.slhead); + free(statelists[1].head.slhead); + num_to_bytes(key64, 6, resultKey); + + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [%012" PRIx64 "]", + (uint16_t)resp.arg[2] & 0xff, + (resp.arg[2] >> 8) ? 'B' : 'A', + key64 + ); + return -5; + } + } + +out: + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c", + (uint16_t)resp.arg[2] & 0xff, + (resp.arg[2] >> 8) ? 'B' : 'A' + ); + + free(statelists[0].head.slhead); + free(statelists[1].head.slhead); + return -4; +} + +// MIFARE +int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { + + UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; + memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); + SendCommand(&c); + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + + if (isOK) { + memcpy(data, resp.d.asBytes, mfNumBlocksPerSector(sectorNo) * 16); + return 0; + } else { + return 1; + } + } else { + PrintAndLogEx(ERR, "Command execute timeout"); + return 2; + } + + return 0; +} + +// EMULATOR +int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { + UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}}; + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 1; + memcpy(data, resp.d.asBytes, blocksCount * 16); + return 0; +} + +int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { + return mfEmlSetMem_xt(data, blockNum, blocksCount, 16); +} + +int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) { + UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, blockBtWidth}}; + memcpy(c.d.asBytes, data, blocksCount * blockBtWidth); + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +// "MAGIC" CARD +int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) { + + uint8_t params = MAGIC_SINGLE; + uint8_t block0[16]; + memset(block0, 0x00, sizeof(block0)); + + int old = mfCGetBlock(0, block0, params); + if (old == 0) + PrintAndLogEx(SUCCESS, "old block 0: %s", sprint_hex(block0, sizeof(block0))); + else + PrintAndLogEx(FAILED, "couldn't get old data. Will write over the last bytes of Block 0."); + + // fill in the new values + // UID + memcpy(block0, uid, 4); + // Mifare UID BCC + block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3]; + // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed) + if ( sak != NULL ) + block0[5] = sak[0]; + + if ( atqa != NULL ) { + block0[6] = atqa[1]; + block0[7] = atqa[0]; + } + PrintAndLogEx(SUCCESS, "new block 0: %s", sprint_hex(block0,16)); + + if ( wipecard ) params |= MAGIC_WIPE; + if ( oldUID == NULL) params |= MAGIC_UID; + + return mfCSetBlock(0, block0, oldUID, params); +} + +int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { + + uint8_t isOK = 0; + UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}}; + memcpy(c.d.asBytes, data, 16); + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + isOK = resp.arg[0] & 0xff; + if (uid != NULL) + memcpy(uid, resp.d.asBytes, 4); + if (!isOK) + return 2; + } else { + PrintAndLogEx(WARNING, "command execute timeout"); + return 1; + } + return 0; +} + +int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { + uint8_t isOK = 0; + UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}}; + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + isOK = resp.arg[0] & 0xff; + if (!isOK) + return 2; + memcpy(data, resp.d.asBytes, 16); + } else { + PrintAndLogEx(WARNING, "command execute timeout"); + return 1; + } + return 0; +} + +// SNIFFER +// [iceman] so many global variables.... + +// constants +static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00}; + +// variables +char logHexFileName[FILE_PATH_SIZE] = {0x00}; +static uint8_t traceCard[4096] = {0x00}; +static char traceFileName[FILE_PATH_SIZE] = {0x00}; +static int traceState = TRACE_IDLE; +static uint8_t traceCurBlock = 0; +static uint8_t traceCurKey = 0; + +struct Crypto1State *traceCrypto1 = NULL; +struct Crypto1State *revstate = NULL; +uint64_t key = 0; +uint32_t ks2 = 0; +uint32_t ks3 = 0; + +uint32_t cuid = 0; // uid part used for crypto1. +uint32_t nt = 0; // tag challenge +uint32_t nr_enc = 0; // encrypted reader challenge +uint32_t ar_enc = 0; // encrypted reader response +uint32_t at_enc = 0; // encrypted tag response + +int isTraceCardEmpty(void) { + return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0)); +} + +int isBlockEmpty(int blockN) { + for (int i = 0; i < 16; i++) + if (traceCard[blockN * 16 + i] != 0) return 0; + + return 1; +} + +int isBlockTrailer(int blockN) { + return ((blockN & 0x03) == 0x03); +} + +int loadTraceCard(uint8_t *tuid, uint8_t uidlen) { + FILE * f; + char buf[64] = {0x00}; + uint8_t buf8[64] = {0x00}; + int i, blockNum; + uint32_t tmp; + + if (!isTraceCardEmpty()) + saveTraceCard(); + + memset(traceCard, 0x00, 4096); + memcpy(traceCard, tuid, uidlen); + + FillFileNameByUID(traceFileName, tuid, ".eml", uidlen); + + f = fopen(traceFileName, "r"); + if (!f) return 1; + + blockNum = 0; + + while (!feof(f)){ + + memset(buf, 0, sizeof(buf)); + if (fgets(buf, sizeof(buf), f) == NULL) { + PrintAndLogEx(FAILED, "No trace file found or reading error."); + if (f) { + fclose(f); + } + return 2; + } + + if (strlen(buf) < 32){ + if (feof(f)) break; + PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols"); + if (f) { + fclose(f); + } + return 2; + } + for (i = 0; i < 32; i += 2) { + sscanf(&buf[i], "%02X", &tmp); + buf8[i / 2] = tmp & 0xFF; + } + + memcpy(traceCard + blockNum * 16, buf8, 16); + + blockNum++; + } + if (f) { + fclose(f); + } + return 0; +} + +int saveTraceCard(void) { + + if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; + + FILE * f; + f = fopen(traceFileName, "w+"); + if ( !f ) return 1; + + // given 4096 tracecard size, these loop will only match a 1024, 1kb card memory + // 4086/16 == 256blocks. + for (uint16_t i = 0; i < 256; i++) { // blocks + for (uint8_t j = 0; j < 16; j++) // bytes + fprintf(f, "%02X", *(traceCard + i * 16 + j)); + + // no extra line in the end + if ( i < 255 ) + fprintf(f, "\n"); + } + fflush(f); + fclose(f); + return 0; +} +// +int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) { + + if (traceCrypto1) + crypto1_destroy(traceCrypto1); + + traceCrypto1 = NULL; + + if (wantSaveToEmlFile) + loadTraceCard(tuid, uidlen); + + traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3]; + traceCard[5] = sak; + memcpy(&traceCard[6], atqa, 2); + traceCurBlock = 0; + cuid = bytes_to_num(tuid + (uidlen-4), 4); + traceState = TRACE_IDLE; + return 0; +} + +void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted){ + uint8_t bt = 0; + int i; + + if (len != 1) { + for (i = 0; i < len; i++) + data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i]; + } else { + bt = 0; + bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 0)) << 0; + bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 1)) << 1; + bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 2)) << 2; + bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 3)) << 3; + data[0] = bt; + } +} + +int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { + + if (traceState == TRACE_ERROR) + return 1; + + if (len > 255) { + traceState = TRACE_ERROR; + return 1; + } + + uint8_t data[255]; + memset(data, 0x00, sizeof(data)); + + memcpy(data, data_src, len); + + if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) { + mf_crypto1_decrypt(traceCrypto1, data, len, 0); + PrintAndLogEx(NORMAL, "DEC| %s", sprint_hex(data, len)); + AddLogHex(logHexFileName, "DEC| ", data, len); + } + + switch (traceState) { + case TRACE_IDLE: + // check packet crc16! + if ((len >= 4) && (!check_crc(CRC_14443_A, data, len))) { + PrintAndLogEx(NORMAL, "DEC| CRC ERROR!!!"); + AddLogLine(logHexFileName, "DEC| ", "CRC ERROR!!!"); + traceState = TRACE_ERROR; // do not decrypt the next commands + return 1; + } + + // AUTHENTICATION + if ((len == 4) && ((data[0] == MIFARE_AUTH_KEYA) || (data[0] == MIFARE_AUTH_KEYB))) { + traceState = TRACE_AUTH1; + traceCurBlock = data[1]; + traceCurKey = data[0] == 60 ? 1:0; + return 0; + } + + // READ + if ((len == 4) && ((data[0] == ISO14443A_CMD_READBLOCK))) { + traceState = TRACE_READ_DATA; + traceCurBlock = data[1]; + return 0; + } + + // WRITE + if ((len == 4) && ((data[0] == ISO14443A_CMD_WRITEBLOCK))) { + traceState = TRACE_WRITE_OK; + traceCurBlock = data[1]; + return 0; + } + + // HALT + if ((len == 4) && ((data[0] == ISO14443A_CMD_HALT) && (data[1] == 0x00))) { + traceState = TRACE_ERROR; // do not decrypt the next commands + return 0; + } + return 0; + + case TRACE_READ_DATA: + if (len == 18) { + traceState = TRACE_IDLE; + + if (isBlockTrailer(traceCurBlock)) { + memcpy(traceCard + traceCurBlock * 16 + 6, data + 6, 4); + } else { + memcpy(traceCard + traceCurBlock * 16, data, 16); + } + if (wantSaveToEmlFile) saveTraceCard(); + return 0; + } else { + traceState = TRACE_ERROR; + return 1; + } + break; + case TRACE_WRITE_OK: + if ((len == 1) && (data[0] == 0x0a)) { + traceState = TRACE_WRITE_DATA; + return 0; + } else { + traceState = TRACE_ERROR; + return 1; + } + break; + case TRACE_WRITE_DATA: + if (len == 18) { + traceState = TRACE_IDLE; + memcpy(traceCard + traceCurBlock * 16, data, 16); + if (wantSaveToEmlFile) saveTraceCard(); + return 0; + } else { + traceState = TRACE_ERROR; + return 1; + } + break; + case TRACE_AUTH1: + if (len == 4) { + traceState = TRACE_AUTH2; + nt = bytes_to_num(data, 4); + return 0; + } else { + traceState = TRACE_ERROR; + return 1; + } + break; + case TRACE_AUTH2: + if (len == 8) { + traceState = TRACE_AUTH_OK; + nr_enc = bytes_to_num(data, 4); + ar_enc = bytes_to_num(data + 4, 4); + return 0; + } else { + traceState = TRACE_ERROR; + return 1; + } + break; + case TRACE_AUTH_OK: + if (len == 4) { + traceState = TRACE_IDLE; + at_enc = bytes_to_num(data, 4); + + // mfkey64 recover key. + ks2 = ar_enc ^ prng_successor(nt, 64); + ks3 = at_enc ^ prng_successor(nt, 96); + revstate = lfsr_recovery64(ks2, ks3); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, nr_enc, 1); + lfsr_rollback_word(revstate, cuid ^ nt, 0); + crypto1_get_lfsr(revstate, &key); + PrintAndLogEx(SUCCESS, "found Key: [%012" PRIx64 "]", key); + + //if ( tryMfk64(cuid, nt, nr_enc, ar_enc, at_enc, &key) ) + AddLogUint64(logHexFileName, "Found Key: ", key); + + int blockShift = ((traceCurBlock & 0xFC) + 3) * 16; + if (isBlockEmpty((traceCurBlock & 0xFC) + 3)) + memcpy(traceCard + blockShift + 6, trailerAccessBytes, 4); + + // keytype A/B + if (traceCurKey) + num_to_bytes(key, 6, traceCard + blockShift + 10); + else + num_to_bytes(key, 6, traceCard + blockShift); + + if (wantSaveToEmlFile) + saveTraceCard(); + + if (traceCrypto1) + crypto1_destroy(traceCrypto1); + + // set cryptosystem state + traceCrypto1 = lfsr_recovery64(ks2, ks3); + + } else { + PrintAndLogEx(NORMAL, "[!] nested key recovery not implemented!\n"); + at_enc = bytes_to_num(data, 4); + crypto1_destroy(traceCrypto1); + traceState = TRACE_ERROR; + } + break; + default: + traceState = TRACE_ERROR; + return 1; + } + return 0; +} + +int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){ + PrintAndLogEx(SUCCESS, "\nencrypted data: [%s]", sprint_hex(data, len) ); + struct Crypto1State *s; + ks2 = ar_enc ^ prng_successor(nt, 64); + ks3 = at_enc ^ prng_successor(nt, 96); + s = lfsr_recovery64(ks2, ks3); + mf_crypto1_decrypt(s, data, len, false); + PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len) ); + crypto1_destroy(s); + return 0; +} + +/* Detect Tag Prng, +* function performs a partial AUTH, where it tries to authenticate against block0, key A, but only collects tag nonce. +* the tag nonce is check to see if it has a predictable PRNG. +* @returns +* TRUE if tag uses WEAK prng (ie Now the NACK bug also needs to be present for Darkside attack) +* FALSE is tag uses HARDEND prng (ie hardnested attack possible, with known key) +*/ +int detect_classic_prng(void){ + + UsbCommand resp, respA; + uint8_t cmd[] = {MIFARE_AUTH_KEYA, 0x00}; + uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; + + UsbCommand c = {CMD_READER_ISO_14443a, {flags, sizeof(cmd), 0}}; + memcpy(c.d.asBytes, cmd, sizeof(cmd)); + + clearCommandBuffer(); + SendCommand(&c); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "PRNG UID: Reply timeout."); + return -1; + } + + // if select tag failed. + if ( resp.arg[0] == 0 ) { + PrintAndLogEx(WARNING, "error: selecting tag failed, can't detect prng\n"); + return -2; + } + if (!WaitForResponseTimeout(CMD_ACK, &respA, 2500)) { + PrintAndLogEx(WARNING, "PRNG data: Reply timeout."); + return -3; + } + + // check respA + if (respA.arg[0] != 4) { + PrintAndLogEx(WARNING, "PRNG data error: Wrong length: %d", respA.arg[0]); + return -4; + } + + uint32_t nonce = bytes_to_num(respA.d.asBytes, respA.arg[0]); + return validate_prng_nonce(nonce); +} +/* Detect Mifare Classic NACK bug + +returns: +0 = error during test / aborted +1 = has nack bug +2 = has not nack bug +3 = always leak nacks (clones) +*/ +int detect_classic_nackbug(bool verbose){ + + UsbCommand c = {CMD_MIFARE_NACK_DETECT, {0, 0, 0}}; + clearCommandBuffer(); + SendCommand(&c); + UsbCommand resp; + + if ( verbose ) + PrintAndLogEx(SUCCESS, "press pm3-button on the proxmark3 device to abort both proxmark3 and client.\n"); + + // for nice animation + bool term = !isatty(STDIN_FILENO); +#if defined(__linux__) || (__APPLE__) + char star[] = {'-', '\\', '|', '/'}; + uint8_t staridx = 0; +#endif + + while (true) { + + if (term) { + printf("."); + } else { + printf( + #if defined(__linux__) || (__APPLE__) + "\e[32m\e[s%c\e[u\e[0m", star[ (staridx++ % 4) ] + #else + "." + #endif + ); + } + fflush(stdout); + if (ukbhit()) { + int gc = getchar(); (void)gc; + return -1; + break; + } + + if (WaitForResponseTimeout(CMD_ACK, &resp, 500)) { + int32_t ok = resp.arg[0]; + uint32_t nacks = resp.arg[1]; + uint32_t auths = resp.arg[2]; + PrintAndLogEx(NORMAL, ""); + + if ( verbose ) { + PrintAndLogEx(SUCCESS, "num of auth requests : %u", auths); + PrintAndLogEx(SUCCESS, "num of received NACK : %u", nacks); + } + switch( ok ) { + case 99 : PrintAndLogEx(WARNING, "button pressed. Aborted."); return 0; + case 96 : + case 98 : { + if (verbose) + PrintAndLogEx(FAILED, "card random number generator is not predictable."); + PrintAndLogEx(WARNING, "detection failed"); + return 2; + } + case 97 : { + if (verbose) { + PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial"); + PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again."); + return 0; + } + } + case 2 : PrintAndLogEx(SUCCESS, "always leak NACK detected"); return 3; + case 1 : PrintAndLogEx(SUCCESS, "NACK bug detected"); return 1; + case 0 : PrintAndLogEx(SUCCESS, "No NACK bug detected"); return 2; + default : PrintAndLogEx(WARNING, "errorcode from device [%i]", ok); return 0; + } + break; + } + } + return 0; +} +/* try to see if card responses to "chinese magic backdoor" commands. */ +void detect_classic_magic(void) { + + uint8_t isGeneration = 0; + UsbCommand resp; + UsbCommand c = {CMD_MIFARE_CIDENT, {0, 0, 0}}; + clearCommandBuffer(); + SendCommand(&c); + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) + isGeneration = resp.arg[0] & 0xff; + + switch( isGeneration ){ + case 1: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): YES"); break; + case 2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): YES"); break; + //case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2): YES"); break; + default: PrintAndLogEx(INFO, "Answers to magic commands: NO"); break; + } } \ No newline at end of file diff --git a/client/mifarehost.h b/client/mifare/mifarehost.h similarity index 97% rename from client/mifarehost.h rename to client/mifare/mifarehost.h index 69458fdfa..c0633bd35 100644 --- a/client/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -1,103 +1,103 @@ -// Merlok, 2011 -// people from mifare@nethemba.com, 2010 -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency ISO14443A commands -//----------------------------------------------------------------------------- -#ifndef __MIFARE_HOST_H -#define __MIFARE_HOST_H - -#include -#include -#include -#include -#include - -#include "proxmark3.h" // time_t -#include "common.h" -#include "util.h" // FILE_PATH_SIZE -#include "ui.h" // PrintAndLog... -#include "crapto1/crapto1.h" -#include "crc16.h" -#include "protocols.h" -#include "mifare.h" -#include "mfkey.h" -#include "util_posix.h" // msclock - -#define MIFARE_SECTOR_RETRY 10 - -// mifare tracer flags -#define TRACE_IDLE 0x00 -#define TRACE_AUTH1 0x01 -#define TRACE_AUTH2 0x02 -#define TRACE_AUTH_OK 0x03 -#define TRACE_READ_DATA 0x04 -#define TRACE_WRITE_OK 0x05 -#define TRACE_WRITE_DATA 0x06 -#define TRACE_ERROR 0xFF - -typedef struct { - union { - struct Crypto1State *slhead; - uint64_t *keyhead; - } head; - union { - struct Crypto1State *sltail; - uint64_t *keytail; - } tail; - uint32_t len; - uint32_t uid; - uint32_t blockNo; - uint32_t keyType; - uint32_t nt; - uint32_t ks1; -} StateList_t; - -typedef struct { - uint64_t Key[2]; - uint8_t foundKey[2]; -} sector_t; - -typedef struct { - uint8_t keyA[6]; - uint8_t keyB[6]; - //uint8_t foundKey[2]; -} icesector_t; - -extern char logHexFileName[FILE_PATH_SIZE]; - -extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key); -extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate); -extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key); -extern int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, - uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); -extern int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey); - -extern int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); - -extern int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); -extern int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); -extern int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth); - -extern int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard); -extern int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params); -extern int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params); - -extern int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile); -extern int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile); - -extern int isTraceCardEmpty(void); -extern int isBlockEmpty(int blockN); -extern int isBlockTrailer(int blockN); -extern int loadTraceCard(uint8_t *tuid, uint8_t uidlen); -extern int saveTraceCard(void); -extern int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); - -extern int detect_classic_prng(void); -extern int detect_classic_nackbug(bool verbose); -extern void detect_classic_magic(void); -extern void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); +// Merlok, 2011 +// people from mifare@nethemba.com, 2010 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// High frequency ISO14443A commands +//----------------------------------------------------------------------------- +#ifndef __MIFARE_HOST_H +#define __MIFARE_HOST_H + +#include +#include +#include +#include +#include + +#include "proxmark3.h" // time_t +#include "common.h" +#include "util.h" // FILE_PATH_SIZE +#include "ui.h" // PrintAndLog... +#include "crapto1/crapto1.h" +#include "crc16.h" +#include "protocols.h" +#include "mifare.h" +#include "mfkey.h" +#include "util_posix.h" // msclock + +#define MIFARE_SECTOR_RETRY 10 + +// mifare tracer flags +#define TRACE_IDLE 0x00 +#define TRACE_AUTH1 0x01 +#define TRACE_AUTH2 0x02 +#define TRACE_AUTH_OK 0x03 +#define TRACE_READ_DATA 0x04 +#define TRACE_WRITE_OK 0x05 +#define TRACE_WRITE_DATA 0x06 +#define TRACE_ERROR 0xFF + +typedef struct { + union { + struct Crypto1State *slhead; + uint64_t *keyhead; + } head; + union { + struct Crypto1State *sltail; + uint64_t *keytail; + } tail; + uint32_t len; + uint32_t uid; + uint32_t blockNo; + uint32_t keyType; + uint32_t nt; + uint32_t ks1; +} StateList_t; + +typedef struct { + uint64_t Key[2]; + uint8_t foundKey[2]; +} sector_t; + +typedef struct { + uint8_t keyA[6]; + uint8_t keyB[6]; + //uint8_t foundKey[2]; +} icesector_t; + +extern char logHexFileName[FILE_PATH_SIZE]; + +extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key); +extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate); +extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key); +extern int mfCheckKeys_fast( uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, + uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); +extern int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultkey); + +extern int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); + +extern int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); +extern int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); +extern int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth); + +extern int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard); +extern int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params); +extern int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params); + +extern int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile); +extern int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile); + +extern int isTraceCardEmpty(void); +extern int isBlockEmpty(int blockN); +extern int isBlockTrailer(int blockN); +extern int loadTraceCard(uint8_t *tuid, uint8_t uidlen); +extern int saveTraceCard(void); +extern int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); + +extern int detect_classic_prng(void); +extern int detect_classic_nackbug(bool verbose); +extern void detect_classic_magic(void); +extern void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); #endif \ No newline at end of file diff --git a/client/obj/mifare/.dummy b/client/obj/mifare/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/client/scripting.h b/client/scripting.h index 4d39a6c6f..81b95cbe0 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -19,7 +19,7 @@ #include "cmdmain.h" #include "comms.h" #include "util.h" -#include "mifarehost.h" +#include "mifare/mifarehost.h" #include "crc.h" #include "crc16.h" #include "crc64.h" diff --git a/include/mifare.h b/include/mifare.h index 14c0e7e27..90077f60d 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -13,6 +13,12 @@ #include "common.h" +#define MF_KEY_A 0 +#define MF_KEY_B 1 + +#define MF_MAD1_SECTOR 0x00 +#define MF_MAD2_SECTOR 0x10 + //----------------------------------------------------------------------------- // ISO 14443A //----------------------------------------------------------------------------- From db7580203b648be8cb472dc86718dba59318f38f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 21 Feb 2019 19:34:12 +0200 Subject: [PATCH 207/320] create mad.c/h --- client/Makefile | 1 + client/cmdhfmf.c | 5 +++-- client/mifare/mad.c | 31 +++++++++++++++++++++++++++++++ client/mifare/mad.h | 26 ++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 client/mifare/mad.c create mode 100644 client/mifare/mad.h diff --git a/client/Makefile b/client/Makefile index 9f8055f8e..ebbce92dd 100644 --- a/client/Makefile +++ b/client/Makefile @@ -157,6 +157,7 @@ CMDSRCS = crapto1/crapto1.c \ emv/cmdemv.c \ emv/emv_roca.c \ mifare/mifare4.c \ + mifare/mad.c \ cmdanalyse.c \ cmdhf.c \ cmdhflist.c \ diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a12bc34c2..edc3a662f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -10,6 +10,7 @@ #include "cmdhfmf.h" #include "mifare/mifare4.h" +#include "mifare/mad.h" #define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 @@ -3225,7 +3226,7 @@ int CmdHF14AMfMAD(const char *cmd) { for(int i = 0; i < 4; i ++) PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or[i * 16], 16)); } - /* + bool haveMAD2 = false; MAD1DecodeAndPrint(sector, verbose, &haveMAD2); @@ -3237,7 +3238,7 @@ int CmdHF14AMfMAD(const char *cmd) { MAD2DecodeAndPrint(sector, verbose); } - */ + return 0; } diff --git a/client/mifare/mad.c b/client/mifare/mad.c new file mode 100644 index 000000000..88fc2c31b --- /dev/null +++ b/client/mifare/mad.c @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// MIFARE Application Directory (MAD) functions +//----------------------------------------------------------------------------- + +#include "mad.h" +#include "ui.h" + +madAIDDescr madKnownAIDs[] = { + {0x0000, "free"}, + {0x0001, "defect, e.g. access keys are destroyed or unknown"}, + {0x0002, "reserved"}, + {0x0003, "contains additional directory info"}, + {0x0004, "contains card holder information in ASCII format."}, + {0x0005, "not applicable (above memory size)}"} +}; + +int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { + + return 0; +}; + +int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { + + return 0; +}; diff --git a/client/mifare/mad.h b/client/mifare/mad.h new file mode 100644 index 000000000..dc2b2e3c0 --- /dev/null +++ b/client/mifare/mad.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// MIFARE Application Directory (MAD) functions +//----------------------------------------------------------------------------- + +#ifndef _MAD_H_ +#define _MAD_H_ + +#include +#include + +typedef struct { + uint16_t AID; + const char *Description; +} madAIDDescr; + +int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2); +int MAD2DecodeAndPrint(uint8_t *sector, bool verbose); + + +#endif // _MAD_H_ From b9dc841bf923ef131866c8582e93d31b9839940d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 21 Feb 2019 19:44:07 +0200 Subject: [PATCH 208/320] MAD. print GPB --- client/mifare/mad.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 88fc2c31b..03b5b3f77 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -22,6 +22,37 @@ madAIDDescr madKnownAIDs[] = { int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { + uint8_t GPB = sector[3 * 16 + 9]; + PrintAndLogEx(NORMAL, "GPB: 0x%02x", GPB); + + // DA (MAD available) + if (!(GPB & 0x80)) { + PrintAndLogEx(ERR, "DA=0! MAD not available."); + return 1; + } + + // MA (multi-application card) + if (GPB & 0x40) + PrintAndLogEx(NORMAL, "Multi application card."); + else + PrintAndLogEx(NORMAL, "Single application card."); + + uint8_t MADVer = GPB & 0x03; + + // MAD version + if ((MADVer != 0x01) && (MADVer != 0x02)) { + PrintAndLogEx(ERR, "Wrong MAD version: 0x%02x", MADVer); + return 2; + }; + + if (haveMAD2) + *haveMAD2 = (MADVer == 2); + + + + + + return 0; }; From 01c9325469e0b0a7c75c8652202be17f25fa2b40 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 21 Feb 2019 20:06:53 +0200 Subject: [PATCH 209/320] check MAD crc --- client/mifare/mad.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 03b5b3f77..2fbc23e38 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -10,6 +10,7 @@ #include "mad.h" #include "ui.h" +#include "crc.h" madAIDDescr madKnownAIDs[] = { {0x0000, "free"}, @@ -48,7 +49,11 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { if (haveMAD2) *haveMAD2 = (MADVer == 2); - + uint8_t crc = CRC8Mad(§or[16 + 1], 31); + if (crc != sector[16]) { + PrintAndLogEx(ERR, "Wrong MAD CRC. Calculated crc: 0x%02x, from sector: 0x%02x", crc, sector[16]); + return 3; + }; From 0632918a477a90c3985c76843ce5e5d835866167 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 21 Feb 2019 20:07:17 +0200 Subject: [PATCH 210/320] fix MAD crc calculation (was wrong) --- common/crc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/crc.c b/common/crc.c index b710404cc..4d28d120e 100644 --- a/common/crc.c +++ b/common/crc.c @@ -99,14 +99,15 @@ uint32_t CRC8Maxim(uint8_t *buff, size_t size) { crc_update2(&crc, buff[i], 8); return crc_finish(&crc); } -// width=8 poly=0x1d, reversed poly=0x?? init=0xe3 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/MAD" +// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=true refout=true xorout=0x00 name="CRC-8/MAD" // the CRC needs to be reversed before returned. +// init c7, poly 1d, final 0x00. uint32_t CRC8Mad(uint8_t *buff, size_t size) { crc_t crc; - crc_init_ref(&crc, 8, 0x1d, 0xe3, 0, true, true); + crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false); for ( int i = 0; i < size; ++i) crc_update2(&crc, buff[i], 8); - return reflect8(crc_finish(&crc)); + return crc_finish(&crc); } // width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC" uint32_t CRC4Legic(uint8_t *cmd, size_t size) { From 421604a3954fe50c05e921387f408bfabab79a4c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:20:52 +0100 Subject: [PATCH 211/320] fix: sc bruteforce' - wrong assign --- client/cmdsmartcard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index 3860496de..f9b77dad0 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -946,8 +946,8 @@ static int smart_brute_sfi(bool decodeTLV){ return 0; } -static void smart_brute_options(bool decodeTLV){ - +static void smart_brute_options(bool decodeTLV) { + uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); if ( !buf ) return; @@ -1057,7 +1057,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { continue; size_t aidlen = strlen(aid); - char* caid = calloc( 8+2+aidlen+1, sizeof(uint8_t)); + caid = calloc( 8+2+aidlen+1, sizeof(uint8_t)); snprintf(caid, 8+2+aidlen+1, SELECT, aidlen >> 1, aid); int hexlen = 0; From 09791638c8eb44f42653ad239f0a4c6de420e97d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:21:13 +0100 Subject: [PATCH 212/320] fix: 'lf indala' - wrong number of bits --- client/cmdlfindala.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index dd262e0dc..b49455e16 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -377,8 +377,8 @@ int CmdIndalaDemodAlt(const char *Cmd) { int CmdIndalaSim(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_indala_sim(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim(); uint8_t bits[224]; size_t size = sizeof(bits); @@ -392,9 +392,9 @@ int CmdIndalaSim(const char *Cmd) { return usage_lf_indala_sim(); // convert to binarray - uint8_t counter = 224; - for (uint8_t i=0; i< len; i++) { - for(uint8_t j=0; j<8; j++) { + uint8_t counter = 223; + for (uint8_t i = 0; i < len; i++) { + for(uint8_t j = 0; j < 8; j++) { bits[counter--] = hexuid[i] & 1; hexuid[i] >>= 1; } From c980ae109aa409fa56dc5f44b94cfcfd3c8f461a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:21:39 +0100 Subject: [PATCH 213/320] fix: 'lf gprox' - wrong check value --- client/cmdlfguard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index ea97d6f77..afad96686 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -192,7 +192,7 @@ int CmdGuardDemod(const char *Cmd) { PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found"); else if (preambleIndex == -3) PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size); - else if (preambleIndex == -3) + else if (preambleIndex == -5) PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits"); else PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex); From b11f767c5530afaf548c9903a649e50fa23cac3f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:22:13 +0100 Subject: [PATCH 214/320] fix: 'lf em brute' - mem leak --- client/cmdlfem4x.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 762b4fe0b..3260b8d74 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -474,14 +474,14 @@ int CmdEM410xBrute(const char *Cmd) { /* default pause time: 1 second */ uint32_t delay = 1000; - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_brute(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h') return usage_lf_em410x_brute(); - cmdp = param_getchar(Cmd, 1); - if (cmdp == 'd' || cmdp == 'D') { + cmdp = tolower(param_getchar(Cmd, 1)); + if (cmdp == 'd') { delay = param_get32ex(Cmd, 2, 1000, 10); param_getdec(Cmd, 4, &clock); - } else if (cmdp == 'c' || cmdp == 'C') { + } else if (cmdp == 'c') { param_getdec(Cmd, 2, &clock); delay = param_get32ex(Cmd, 4, 1000, 10); } @@ -498,7 +498,10 @@ int CmdEM410xBrute(const char *Cmd) { } uidBlock = calloc(stUidBlock, 5); - if (uidBlock == NULL) return 1; + if (uidBlock == NULL) { + fclose(f); + return 1; + } while( fgets(buf, sizeof(buf), f) ) { if (strlen(buf) < 10 || buf[9] == '\n') continue; From 7ea7061ed019782d18b82983e5e83b82c62afa19 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:22:39 +0100 Subject: [PATCH 215/320] fix: 'hf mf cload' - wrong free --- client/cmdhfmf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 57cf246da..e69fd6ba3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2752,10 +2752,9 @@ int CmdHF14AMfCLoad(const char *Cmd) { res = loadFileEML( Cmd, "eml", data, &datalen); } } - if ( res ) { - free(data); + + if ( res ) return 1; - } // PrintAndLogEx(INFO, "DATA | %s", sprint_hex(data+1000, 24) ); From 439f767b4de6e7674a7fc3bcfe2736a4c328567f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:35:03 +0100 Subject: [PATCH 216/320] fix: mem leak --- uart/uart_posix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index b9df932d6..c77457d91 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -102,6 +102,7 @@ serial_port uart_open(const char* pcPortName) { printf("Error: getaddrinfo: %s\n", gai_strerror(s)); freeaddrinfo(addr); free(addrstr); + free(sp); return INVALID_SERIAL_PORT; } From 697af67bf19a425ffe4b5791b070b22edcd959bc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:37:18 +0100 Subject: [PATCH 217/320] fix: 'hf 14b info' - missing break --- client/cmdhf14b.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 4077e16e6..92052e02c 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -461,6 +461,7 @@ bool HF14B_Std_Info(bool verbose){ PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid); print_atqb_resp(card.atqb, card.cid); isSuccess = true; + break; case 2: if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail"); break; From 954e01c363d8edc52a17e5eb030cb8efbc67584f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:38:07 +0100 Subject: [PATCH 218/320] fix: bad loop --- client/cmdhf14b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 92052e02c..11b0aabb3 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -246,7 +246,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) { if (!card) return false; - uint8_t retry = 3; + int8_t retry = 3; UsbCommand resp; UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}}; From 43bd82b7789d93dd94d04cd83dc852d044d0025f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 Feb 2019 23:44:56 +0100 Subject: [PATCH 219/320] update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a6fc2d6..90fbd53bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Fix - A lot of bugfixes, like memory leaks (@iceman) - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - Fix 'hf mf fchk' (@iceman) - Fix 'usb slow on posix based systems' (@fl0-0) From 140c327cc2fb533ae72d55885cc23f2361a809e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 22 Feb 2019 09:43:03 +0100 Subject: [PATCH 220/320] CHG: 'hf mf list' - readded it. calls trace list mf in the back --- client/cmdhfmf.c | 14 ++++++++++---- client/cmdhfmf.h | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e69fd6ba3..2412aecee 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -434,7 +434,7 @@ char * GenerateFilename(const char *prefix, const char *suffix){ return fptr; } -int CmdHF14ADarkside(const char *Cmd) { +int CmdHF14AMfDarkside(const char *Cmd) { uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA; uint64_t key = 0; @@ -3174,7 +3174,7 @@ out: return 0; } -int CmdHF14AMfAuth4(const char *cmd) { +int CmdHF14AMfAuth4(const char *Cmd) { uint8_t keyn[20] = {0}; int keynlen = 0; uint8_t key[16] = {0}; @@ -3191,7 +3191,7 @@ int CmdHF14AMfAuth4(const char *cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(Cmd, argtable, true); CLIGetHexWithReturn(1, keyn, &keynlen); CLIGetHexWithReturn(2, key, &keylen); @@ -3210,9 +3210,15 @@ int CmdHF14AMfAuth4(const char *cmd) { return MifareAuth4(NULL, keyn, key, true, false, true); } +int CmdHF14AMfList(const char *Cmd) { + CmdTraceList("mf"); + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"darkside", CmdHF14ADarkside, 0, "Darkside attack. read parity error messages."}, + {"list", CmdHF14AMfList, 0, "[Deprecated] List ISO 14443-a / Mifare history"}, + {"darkside", CmdHF14AMfDarkside, 0, "Darkside attack. read parity error messages."}, {"nested", CmdHF14AMfNested, 0, "Nested attack. Test nested authentication"}, {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"}, {"keybrute", CmdHF14AMfKeyBrute, 0, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index eeb7a74f6..a87da449f 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -35,6 +35,7 @@ extern int CmdHFMF(const char *Cmd); +extern int CmdHF14AMfList(const char *Cmd); extern int CmdHF14AMfDbg(const char* cmd); extern int CmdHF14AMfRdBl(const char* cmd); extern int CmdHF14AMfURdBl(const char* cmd); @@ -45,7 +46,7 @@ extern int CmdHF14AMfRestore(const char* cmd); extern int CmdHF14AMfWrBl(const char* cmd); extern int CmdHF14AMfUWrBl(const char* cmd); extern int CmdHF14AMfChk(const char* cmd); -extern int CmdHF14ADarkside(const char* cmd); +extern int CmdHF14AMfDarkside(const char* cmd); extern int CmdHF14AMfNested(const char* cmd); extern int CmdHF14AMfNestedHard(const char *Cmd); //extern int CmdHF14AMfSniff(const char* cmd); From 99101e56fd71b19a8a2f0a5fa18c23a9b71bad29 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 22 Feb 2019 09:43:42 +0100 Subject: [PATCH 221/320] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90fbd53bb..ce939d980 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Add 'hf mf list' - readded it again (@iceman) - Fix - A lot of bugfixes, like memory leaks (@iceman) - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - Fix 'hf mf fchk' (@iceman) From ef9d1fa3786be56c2c46552e9a975d7487abe904 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 22 Feb 2019 15:21:20 +0100 Subject: [PATCH 222/320] fix: mem leak, --- uart/uart_posix.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index c77457d91..e3d7753a9 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -123,6 +123,7 @@ serial_port uart_open(const char* pcPortName) { printf("Error: Could not connect\n"); freeaddrinfo(addr); free(addrstr); + free(sp); return INVALID_SERIAL_PORT; } @@ -132,13 +133,17 @@ serial_port uart_open(const char* pcPortName) { sp->fd = sfd; int one = 1; - setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + int res = setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + if ( res != 0) { + free(sp); + return INVALID_SERIAL_PORT; + } return sp; } sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - if(sp->fd == -1) { + if (sp->fd == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } @@ -160,7 +165,7 @@ serial_port uart_open(const char* pcPortName) { } // Try to retrieve the old (current) terminal info struct - if(tcgetattr(sp->fd,&sp->tiOld) == -1) { + if (tcgetattr(sp->fd,&sp->tiOld) == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } @@ -180,7 +185,7 @@ serial_port uart_open(const char* pcPortName) { sp->tiNew.c_cc[VTIME] = 0; // Try to set the new terminal info struct - if(tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { + if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } @@ -359,8 +364,11 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { # endif default: return false; }; + struct termios ti; - if (tcgetattr(spu->fd,&ti) == -1) return false; + if (tcgetattr(spu->fd,&ti) == -1) + return false; + // Set port speed (Input and Output) cfsetispeed(&ti, stPortSpeed); cfsetospeed(&ti, stPortSpeed); From 1b64c4cb63470803bb6fa0300fd2b89a58ee485b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 22 Feb 2019 15:23:09 +0100 Subject: [PATCH 223/320] fix: overflow was possible since 1000 is type long --- client/util_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/util_posix.c b/client/util_posix.c index 7704e9d4b..a45dc48e9 100644 --- a/client/util_posix.c +++ b/client/util_posix.c @@ -130,7 +130,7 @@ uint64_t msclock(void) { #else struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); - return (t.tv_sec * 1000 + t.tv_nsec / 1000000); + return ( 1000 * (uint64_t)t.tv_sec + t.tv_nsec / 1000000); #endif } From c5a1b06f25a68d00ef9eb4009e9195f71ac03e83 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 22 Feb 2019 16:58:49 +0200 Subject: [PATCH 224/320] mad comment fix --- common/crc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/crc.c b/common/crc.c index 4d28d120e..77bea0b47 100644 --- a/common/crc.c +++ b/common/crc.c @@ -99,9 +99,7 @@ uint32_t CRC8Maxim(uint8_t *buff, size_t size) { crc_update2(&crc, buff[i], 8); return crc_finish(&crc); } -// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=true refout=true xorout=0x00 name="CRC-8/MAD" -// the CRC needs to be reversed before returned. -// init c7, poly 1d, final 0x00. +// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD" uint32_t CRC8Mad(uint8_t *buff, size_t size) { crc_t crc; crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false); From 8010f2dc5e77b3135037ba2645ca2d52de979265 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 22 Feb 2019 18:05:45 +0200 Subject: [PATCH 225/320] MAD1 OK --- client/mifare/mad.c | 131 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 2fbc23e38..e7a611384 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -11,16 +11,119 @@ #include "mad.h" #include "ui.h" #include "crc.h" +#include "util.h" -madAIDDescr madKnownAIDs[] = { +static madAIDDescr madKnownAIDs[] = { {0x0000, "free"}, {0x0001, "defect, e.g. access keys are destroyed or unknown"}, {0x0002, "reserved"}, {0x0003, "contains additional directory info"}, {0x0004, "contains card holder information in ASCII format."}, - {0x0005, "not applicable (above memory size)}"} + {0x0005, "not applicable (above memory size)"}, + + {0x03e1, "NDEF"}, }; +static madAIDDescr madKnownClusterCodes[] = { + {0x00, "cluster: card administration"}, + {0x01, "cluster: miscellaneous applications"}, + {0x02, "cluster: miscellaneous applications"}, + {0x03, "cluster: miscellaneous applications"}, + {0x04, "cluster: miscellaneous applications"}, + {0x05, "cluster: miscellaneous applications"}, + {0x06, "cluster: miscellaneous applications"}, + {0x07, "cluster: miscellaneous applications"}, + {0x08, "cluster: airlines"}, + {0x09, "cluster: ferry traffic"}, + {0x10, "cluster: railway services"}, + {0x11, "cluster: miscellaneous applications"}, + {0x12, "cluster: transport"}, + {0x14, "cluster: security solutions"}, + {0x18, "cluster: city traffic"}, + {0x19, "cluster: Czech Railways"}, + {0x20, "cluster: bus services"}, + {0x21, "cluster: multi modal transit"}, + {0x28, "cluster: taxi"}, + {0x30, "cluster: road toll"}, + {0x31, "cluster: generic transport"}, + {0x38, "cluster: company services"}, + {0x40, "cluster: city card services"}, + {0x47, "cluster: access control & security"}, + {0x48, "cluster: access control & security"}, + {0x49, "cluster: VIGIK"}, + {0x4A, "cluster: Ministry of Defence, Netherlands"}, + {0x4B, "cluster: Bosch Telecom, Germany"}, + {0x4C, "cluster: European Union Institutions"}, + {0x50, "cluster: ski ticketing"}, + {0x51, "cluster: access control & security"}, + {0x52, "cluster: access control & security"}, + {0x53, "cluster: access control & security"}, + {0x54, "cluster: access control & security"}, + {0x55, "cluster: SOAA standard for offline access standard"}, + {0x56, "cluster: access control & security"}, + {0x58, "cluster: academic services"}, + {0x60, "cluster: food"}, + {0x68, "cluster: non-food trade"}, + {0x70, "cluster: hotel"}, + {0x71, "cluster: loyalty"}, + {0x75, "cluster: airport services"}, + {0x78, "cluster: car rental"}, + {0x79, "cluster: Dutch government"}, + {0x80, "cluster: administration services"}, + {0x88, "cluster: electronic purse"}, + {0x90, "cluster: television"}, + {0x91, "cluster: cruise ship"}, + {0x95, "cluster: IOPTA"}, + {0x97, "cluster: metering"}, + {0x98, "cluster: telephone"}, + {0xA0, "cluster: health services"}, + {0xA8, "cluster: warehouse"}, + {0xB0, "cluster: electronic trade"}, + {0xB8, "cluster: banking"}, + {0xC0, "cluster: entertainment & sports"}, + {0xC8, "cluster: car parking"}, + {0xC9, "cluster: fleet management"}, + {0xD0, "cluster: fuel, gasoline"}, + {0xD8, "cluster: info services"}, + {0xE0, "cluster: press"}, + {0xE1, "cluster: NFC Forum"}, + {0xE8, "cluster: computer"}, + {0xF0, "cluster: mail"}, + {0xF8, "cluster: miscellaneous applications"}, +}; + +static const char unknownAID[] = ""; + +static const char *GetAIDDescription(uint16_t AID) { + for(int i = 0; i < ARRAYLEN(madKnownAIDs); i++) + if (madKnownAIDs[i].AID == AID) + return madKnownAIDs[i].Description; + + for(int i = 0; i < ARRAYLEN(madKnownClusterCodes); i++) + if (madKnownClusterCodes[i].AID == AID) + return madKnownClusterCodes[i].Description; + + return unknownAID; +} + +int madCRCCheck(uint8_t *sector, bool verbose, int MADver) { + if (MADver == 1) { + uint8_t crc = CRC8Mad(§or[16 + 1], 31); + if (crc != sector[16]) { + if (verbose) + PrintAndLogEx(ERR, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); + return 3; + }; + } else { + } + + return 0; +} + +uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) { + return (sector[16 + 2 + (sectorNo - 1) * 2] << 8) + (sector[16 + 2 + (sectorNo - 1) * 2 + 1]); +} + int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { uint8_t GPB = sector[3 * 16 + 9]; @@ -39,6 +142,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { PrintAndLogEx(NORMAL, "Single application card."); uint8_t MADVer = GPB & 0x03; + PrintAndLogEx(NORMAL, "MAD version: %d", MADVer); // MAD version if ((MADVer != 0x01) && (MADVer != 0x02)) { @@ -48,20 +152,27 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { if (haveMAD2) *haveMAD2 = (MADVer == 2); + + int res = madCRCCheck(sector, true, 1); + if (res) + return res; - uint8_t crc = CRC8Mad(§or[16 + 1], 31); - if (crc != sector[16]) { - PrintAndLogEx(ERR, "Wrong MAD CRC. Calculated crc: 0x%02x, from sector: 0x%02x", crc, sector[16]); - return 3; + if (verbose) + PrintAndLogEx(NORMAL, "CRC8-MAD OK."); + + for(int i = 1; i < 16; i++) { + uint16_t AID = madGetAID(sector, 1, i); + PrintAndLogEx(NORMAL, "%02d [%04X] %s", i, AID, GetAIDDescription(AID)); }; - - - - + return 0; }; int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { + int res = madCRCCheck(sector, true, 2); + if (res) + return res; + return 0; }; From 91ed51c673fffb26375e48e02a98bf95c2adad60 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 22 Feb 2019 18:06:37 +0200 Subject: [PATCH 226/320] add comment --- client/mifare/mad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index e7a611384..2b6033588 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -13,6 +13,7 @@ #include "crc.h" #include "util.h" +// https://www.nxp.com/docs/en/application-note/AN10787.pdf static madAIDDescr madKnownAIDs[] = { {0x0000, "free"}, {0x0001, "defect, e.g. access keys are destroyed or unknown"}, From 5122e1289d584bb7deb9dc46b3febeabe9c1b6a5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 22 Feb 2019 18:24:22 +0200 Subject: [PATCH 227/320] info-byte --- client/mifare/mad.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 2b6033588..421b4844f 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -161,6 +161,17 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { if (verbose) PrintAndLogEx(NORMAL, "CRC8-MAD OK."); + // info byte + uint8_t InfoByte = sector[16 + 1] & 0x3f; + if (InfoByte) { + PrintAndLogEx(NORMAL, "Card publisher sector: 0x%02x", InfoByte); + } else { + if (verbose) + PrintAndLogEx(NORMAL, "Card publisher sector not present."); + } + if (InfoByte == 0x10 || InfoByte >= 0x28) + PrintAndLogEx(WARNING, "Info byte error"); + for(int i = 1; i < 16; i++) { uint16_t AID = madGetAID(sector, 1, i); PrintAndLogEx(NORMAL, "%02d [%04X] %s", i, AID, GetAIDDescription(AID)); From 20be5c5d9f030abae2d122edda8a94947d48ea51 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 22 Feb 2019 19:58:50 +0200 Subject: [PATCH 228/320] some of MAD2 code --- client/cmdhfmf.c | 6 +++--- client/mifare/mad.c | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index edc3a662f..a7966bee8 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3230,9 +3230,9 @@ int CmdHF14AMfMAD(const char *cmd) { bool haveMAD2 = false; MAD1DecodeAndPrint(sector, verbose, &haveMAD2); - if (haveMAD2) { - if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { - PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + if (haveMAD2) { // MF_MAD2_SECTOR + if (mfReadSector(1, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { + PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); return 2; } diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 421b4844f..9f28de394 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -122,7 +122,10 @@ int madCRCCheck(uint8_t *sector, bool verbose, int MADver) { } uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) { - return (sector[16 + 2 + (sectorNo - 1) * 2] << 8) + (sector[16 + 2 + (sectorNo - 1) * 2 + 1]); + if (MADver == 1) + return (sector[16 + 2 + (sectorNo - 1) * 2] << 8) + (sector[16 + 2 + (sectorNo - 1) * 2 + 1]); + else + return (sector[2 + (sectorNo - 1) * 2] << 8) + (sector[2 + (sectorNo - 1) * 2 + 1]); } int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { @@ -185,6 +188,11 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { if (res) return res; + for(int i = 1; i < 8 + 8 + 7; i++) { + uint16_t AID = madGetAID(sector, 2, i); + PrintAndLogEx(NORMAL, "%02d [%04X] %s", i + 15, AID, GetAIDDescription(AID)); + }; + return 0; }; From 22510b6f224289e7bd2c9a19218d62282ec9d4d1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 14:15:54 +0100 Subject: [PATCH 229/320] CHG: cleanups --- client/cmdhfmfhard.c | 77 ++++++++++---------------- client/hardnested/hardnested_bf_core.c | 6 +- 2 files changed, 32 insertions(+), 51 deletions(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 0c661d410..9d9406c11 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -1048,7 +1048,7 @@ static bool shrink_key_space(float *brute_forces) //iceman 2018 return ((hardnested_stage & CHECK_2ND_BYTES) && reduction_rate >= 0.0 && - ( reduction_rate < brute_force_per_second * (float)sample_period / 1000.0 || *brute_forces < 0x1F000000000)); + ( reduction_rate < brute_force_per_second * (float)sample_period / 1000.0 || *brute_forces < 0x1F00000000)); } @@ -1672,9 +1672,9 @@ static inline bool bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_e } #endif return false; - } else { - return true; } + + return true; } @@ -1714,11 +1714,13 @@ static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even #ifdef DEBUG_KEY_ELIMINATION if (known_target_key != -1 && state == test_state[odd_even]) { PrintAndLogEx(NORMAL, "all_bitflips_match() 1st Byte: %s test state (0x%06x): Eliminated. Bytes = %02x, %02x, Common Bits = %d\n", - odd_even==ODD_STATE?"odd":"even", + odd_even == ODD_STATE ? "odd" : "even", test_state[odd_even], - byte, byte2, num_common); + byte, + byte2, + num_common); if (failstr[0] == '\0') { - sprintf(failstr, "Other 1st Byte %s, all_bitflips_match(), no match", odd_even?"odd":"even"); + sprintf(failstr, "Other 1st Byte %s, all_bitflips_match(), no match", odd_even ? "odd" : "even"); } } #endif @@ -1770,12 +1772,10 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui uint32_t *bitarray_a8 = part_sum_a8_bitarrays[odd_even][part_sum_a8/2]; uint32_t *bitarray_bitflips = nonces[best_first_bytes[0]].states_bitarray[odd_even]; - // for (uint32_t i = 0; i < (1<<19); i++) { - // candidates_bitarray[i] = bitarray_a0[i] & bitarray_a8[i] & bitarray_bitflips[i]; - // } bitarray_AND4(candidates_bitarray, bitarray_a0, bitarray_a8, bitarray_bitflips); bitarray_to_list(best_first_bytes[0], candidates_bitarray, candidates->states[odd_even], &(candidates->len[odd_even]), odd_even); + if (candidates->len[odd_even] == 0) { free(candidates->states[odd_even]); candidates->states[odd_even] = NULL; @@ -1784,17 +1784,14 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui } free_bitarray(candidates_bitarray); - pthread_mutex_lock(&statelist_cache_mutex); sl_cache[part_sum_a0/2][part_sum_a8/2][odd_even].sl = candidates->states[odd_even]; sl_cache[part_sum_a0/2][part_sum_a8/2][odd_even].len = candidates->len[odd_even]; sl_cache[part_sum_a0/2][part_sum_a8/2][odd_even].cache_status = COMPLETED; pthread_mutex_unlock(&statelist_cache_mutex); - return; } - static statelist_t *add_more_candidates(void) { statelist_t *new_candidates = candidates; @@ -1888,7 +1885,6 @@ static bool TestIfKeyExists(uint64_t key) static work_status_t book_of_work[NUM_PART_SUMS][NUM_PART_SUMS][NUM_PART_SUMS][NUM_PART_SUMS]; - static void init_book_of_work(void) { for (uint8_t p = 0; p < NUM_PART_SUMS; p++) { @@ -2052,19 +2048,6 @@ __attribute__((force_align_arg_pointer)) static void generate_candidates(uint8_t sum_a0_idx, uint8_t sum_a8_idx) { - // PrintAndLogEx(NORMAL, "Generating crypto1 state candidates... \n"); - - // estimate maximum candidate states - // maximum_states = 0; - // for (uint16_t sum_odd = 0; sum_odd <= 16; sum_odd += 2) { - // for (uint16_t sum_even = 0; sum_even <= 16; sum_even += 2) { - // if (sum_odd*(16-sum_even) + (16-sum_odd)*sum_even == sum_a0) { - // maximum_states += (uint64_t)count_states(part_sum_a0_bitarrays[EVEN_STATE][sum_even/2]) - // * count_states(part_sum_a0_bitarrays[ODD_STATE][sum_odd/2]); - // } - // } - // } - // PrintAndLogEx(NORMAL, "Number of possible keys with Sum(a0) = %d: %" PRIu64 " (2^%1.1f)\n", sum_a0, maximum_states, log(maximum_states)/log(2.0)); init_statelist_cache(); init_book_of_work(); @@ -2111,12 +2094,11 @@ static void generate_candidates(uint8_t sum_a0_idx, uint8_t sum_a8_idx) static void free_candidates_memory(statelist_t *sl) { - if (sl == NULL) { + if (sl == NULL) return; - } else { - free_candidates_memory(sl->next); - free(sl); - } + + free_candidates_memory(sl->next); + free(sl); } @@ -2137,7 +2119,6 @@ static void pre_XOR_nonces(void) } } } - static bool brute_force(uint64_t *found_key) { @@ -2147,7 +2128,6 @@ static bool brute_force(uint64_t *found_key) return brute_force_bs(NULL, candidates, cuid, num_acquired_nonces, maximum_states, nonces, best_first_bytes, found_key); } - static uint16_t SumProperty(struct Crypto1State *s) { uint16_t sum_odd = PartialSumProperty(s->odd, ODD_STATE); @@ -2223,11 +2203,11 @@ static void set_test_state(uint8_t byte) 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, uint64_t *foundkey, char *filename) { - char progress_text[80]; - + char progress_text[80]; char instr_set[12] = {0}; + get_SIMD_instruction_set(instr_set); - PrintAndLog("Using %s SIMD core.", instr_set); + PrintAndLogEx(SUCCESS,"Using %s SIMD core.", instr_set); srand((unsigned) time(NULL)); brute_force_per_second = brute_force_benchmark(); @@ -2241,6 +2221,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc PrintAndLogEx(WARNING, "Could not create/open file hardnested_stats.txt"); return 3; } + for (uint32_t i = 0; i < tests; i++) { start_time = msclock(); print_progress_header(); @@ -2282,6 +2263,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc float expected_brute_force1 = (float)num_odd * num_even / 2.0; float expected_brute_force2 = nonces[best_first_bytes[0]].expected_num_brute_force; fprintf(fstats, "%1.1f;%1.1f;", log(expected_brute_force1)/log(2.0), log(expected_brute_force2)/log(2.0)); + if (expected_brute_force1 < expected_brute_force2) { hardnested_print_progress(num_acquired_nonces, "(Ignoring Sum(a8) properties)", expected_brute_force1, 0); set_test_state(best_first_byte_smallest_bitarray); @@ -2291,12 +2273,11 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) { maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE]; } - //PrintAndLogEx(NORMAL, "Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0)); - // fPrintAndLogEx(NORMAL, "fstats, "%" PRIu64 ";", maximum_states); + best_first_bytes[0] = best_first_byte_smallest_bitarray; pre_XOR_nonces(); prepare_bf_test_nonces(nonces, best_first_bytes[0]); - //hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0); + key_found = brute_force(foundkey); free(candidates->states[ODD_STATE]); free(candidates->states[EVEN_STATE]); @@ -2313,10 +2294,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc sprintf(progress_text, "(Estimated Sum(a8) is WRONG! Correct Sum(a8) = %" PRIu16 ")", real_sum_a8); hardnested_print_progress(num_acquired_nonces, progress_text, expected_brute_force, 0); } - // PrintAndLogEx(NORMAL, "Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0)); generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx); - // PrintAndLogEx(NORMAL, "Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0); - //hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0); + key_found = brute_force(foundkey); free_statelist_cache(); free_candidates_memory(candidates); @@ -2399,40 +2378,44 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc uint32_t num_even = nonces[best_first_byte_smallest_bitarray].num_states_bitarray[EVEN_STATE]; float expected_brute_force1 = (float)num_odd * num_even / 2.0; float expected_brute_force2 = nonces[best_first_bytes[0]].expected_num_brute_force; + if (expected_brute_force1 < expected_brute_force2) { hardnested_print_progress(num_acquired_nonces, "(Ignoring Sum(a8) properties)", expected_brute_force1, 0); set_test_state(best_first_byte_smallest_bitarray); add_bitflip_candidates(best_first_byte_smallest_bitarray); Tests2(); maximum_states = 0; + for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) { maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE]; } - // PrintAndLogEx(NORMAL, "Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0)); + best_first_bytes[0] = best_first_byte_smallest_bitarray; pre_XOR_nonces(); prepare_bf_test_nonces(nonces, best_first_bytes[0]); - //hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0); + key_found = brute_force(foundkey); free(candidates->states[ODD_STATE]); free(candidates->states[EVEN_STATE]); + free_statelist_cache(); free_candidates_memory(candidates); candidates = NULL; } else { + pre_XOR_nonces(); prepare_bf_test_nonces(nonces, best_first_bytes[0]); + for (uint8_t j = 0; j < NUM_SUMS && !key_found; j++) { float expected_brute_force = nonces[best_first_bytes[0]].expected_num_brute_force; sprintf(progress_text, "(%d. guess: Sum(a8) = %" PRIu16 ")", j+1, sums[nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx]); hardnested_print_progress(num_acquired_nonces, progress_text, expected_brute_force, 0); + if (trgkey != NULL && sums[nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx] != real_sum_a8) { sprintf(progress_text, "(Estimated Sum(a8) is WRONG! Correct Sum(a8) = %" PRIu16 ")", real_sum_a8); hardnested_print_progress(num_acquired_nonces, progress_text, expected_brute_force, 0); } - // PrintAndLogEx(NORMAL, "Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0)); + generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx); - // PrintAndLogEx(NORMAL, "Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0); - //hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0); key_found = brute_force(foundkey); free_statelist_cache(); free_candidates_memory(candidates); diff --git a/client/hardnested/hardnested_bf_core.c b/client/hardnested/hardnested_bf_core.c index c00434a52..6bf29b795 100644 --- a/client/hardnested/hardnested_bf_core.c +++ b/client/hardnested/hardnested_bf_core.c @@ -59,6 +59,7 @@ THE SOFTWARE. #include #include "crapto1/crapto1.h" #include "parity.h" +#include "util.h" // bitslice type // while AVX supports 256 bit vector floating point operations, we need integer operations for boolean logic @@ -99,9 +100,6 @@ typedef union { // size of nonce to be decrypted #define KEYSTREAM_SIZE 24 -// endianness conversion -#define rev32(word) ((((word) & 0xff) << 24) | ((((word) >> 8) & 0xff) << 16) | ((((word) >> 16) & 0xff) << 8) | ((((word) >> 24) & 0xff))) - // this needs to be compiled several times for each instruction set. // For each instruction set, define a dedicated function name: #if defined (__AVX512F__) @@ -184,7 +182,7 @@ void BITSLICE_TEST_NONCES(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce // bitslice nonces' 2nd to 4th byte for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { for(uint32_t bit_idx = 0; bit_idx < KEYSTREAM_SIZE; bit_idx++){ - bool bit = get_bit(KEYSTREAM_SIZE-1-bit_idx, rev32(bf_test_nonce[i] << 8)); + bool bit = get_bit(KEYSTREAM_SIZE-1-bit_idx, BSWAP_32(bf_test_nonce[i] << 8)); if(bit){ bitsliced_encrypted_nonces[i][bit_idx].value = bs_ones.value; } else { From c58f487cab2fce86967f85cc0295a278dda28ab0 Mon Sep 17 00:00:00 2001 From: sh7d Date: Sun, 17 Feb 2019 12:54:44 +0100 Subject: [PATCH 230/320] em41 - spoof fix --- client/cmdlfem4x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 3260b8d74..7b4386fbb 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -404,8 +404,7 @@ int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { // this read is the "normal" read, which download lf signal and tries to demod here. int CmdEM410xRead(const char *Cmd) { lf_read(true, 8192); - CmdEM410xDemod(Cmd); - return 0; + return CmdEM410xDemod(Cmd); } // this read loops on device side. From 2dc3bc6af3599f86849d996ae44b7c06713c467f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 15:44:34 +0100 Subject: [PATCH 231/320] ADD: 'lf keri' - basic commands. --- client/Makefile | 1 + client/cmdlfkeri.c | 233 +++++++++++++++++++++++++++++++++++++++++++++ client/cmdlfkeri.h | 36 +++++++ 3 files changed, 270 insertions(+) create mode 100644 client/cmdlfkeri.c create mode 100644 client/cmdlfkeri.h diff --git a/client/Makefile b/client/Makefile index 0b19d4599..324aaef01 100644 --- a/client/Makefile +++ b/client/Makefile @@ -187,6 +187,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdlfio.c \ cmdlfindala.c \ cmdlfjablotron.c \ + cmdlfkeri.c \ cmdlfnexwatch.c \ cmdlfnedap.c \ cmdlfnoralsy.c \ diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c new file mode 100644 index 000000000..b5f6fa793 --- /dev/null +++ b/client/cmdlfkeri.c @@ -0,0 +1,233 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency KERI tag commands +// PSK1, RF/128, RF/2, 64 bits long +//----------------------------------------------------------------------------- +#include "cmdlfkeri.h" + +static int CmdHelp(const char *Cmd); + +int usage_lf_keri_clone(void){ + PrintAndLogEx(NORMAL, "clone a KERI tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " : KERI Internal ID"); + PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf keri clone 112233"); + return 0; +} + +int usage_lf_keri_sim(void) { + PrintAndLogEx(NORMAL, "Enables simulation of KERI card with specified card number."); + PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf keri sim [h] "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : This help"); + PrintAndLogEx(NORMAL, " : Keri Internal ID"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf keri sim 112233"); + return 0; +} + +// find KERI preamble in already demoded data +int detectKeri(uint8_t *dest, size_t *size, bool *invert) { + + uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + uint8_t preamble_i[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}; + + // sanity check. + if ( *size < sizeof(preamble) + 100) return -1; + + size_t startIdx = 0; + + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) { + + // if didn't find preamble try again inverting + if (!preambleSearch(DemodBuffer, preamble_i, sizeof(preamble_i), size, &startIdx)) + return -2; + + *invert ^= 1; + } + + if (*size != 64) return -3; //wrong demoded size + + return (int)startIdx; +} + +int CmdKeriDemod(const char *Cmd) { + + if (!PSKDemod("", false)) { + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: PSK1 Demod failed"); + return 0; + } + bool invert = false; + size_t size = DemodBufferLen; + int idx = detectKeri(DemodBuffer, &size, &invert); + if (idx < 0) { + if (idx == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: too few bits found"); + else if (idx == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: preamble not found"); + else if (idx == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: Size not correct: 64 != %d", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: ans: %d", idx); + + return 0; + } + setDemodBuf(DemodBuffer, size, idx); + setClockGrid(g_DemodClock, g_DemodStartIdx + (idx * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer , 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32); + + //get internal id + uint32_t ID = 0; + for (uint8_t i = 30; i < 59; i++){ + ID = (ID << 1) | DemodBuffer[i]; + } + + /* + 000000000000000000000000000001XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX111 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1###############################^^^ + Preamble block 29 bits of ZEROS + 32 bit Internal ID (First bit always 1) + 3 bit of 1s in the end + + How this is decoded to Facility ID, Card number is unknown + Facility ID = 0-31 (indicates 5 bits) + Card number = up to 10 digits + + Might be a hash of FC & CN to generate Internal ID + */ + + PrintAndLogEx(NORMAL, "KERI Tag Found -- Raw: %08X%08X", raw1 ,raw2); + + PrintAndLogEx(NORMAL, "KERI Internal ID: %d", ID); + + if (invert){ + PrintAndLogEx(NORMAL, "Had to Invert - probably KERI"); + for (size_t i = 0; i < size; i++) + DemodBuffer[i] ^= 1; + } + + CmdPrintDemodBuff("x"); + + return 1; +} + +int CmdKeriRead(const char *Cmd) { + lf_read(true, 10000); + return CmdKeriDemod(Cmd); +} + +int CmdKeriClone(const char *Cmd) { + + PrintAndLogEx(ERR, "TO BE DONE - Cloning KERI is not implemented yet"); + /* + uint32_t internalid = 0; + uint32_t blocks[3] = {T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT | T55x7_BITRATE_RF_16, 0, 0}; + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_clone(); + + internalid = param_get32ex(Cmd, 0, 0, 10); + + //Q5 + if (tolower(param_getchar(Cmd, 1)) == 'q') + blocks[0] = T5555_MODULATION_PSK1 | T5555_SET_BITRATE(16) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; + + + // MSB is ONE, and 3 LSB is ONE + uint32_t pre = + internalid &= 0x80000003; + + // + blocks[1] = internalid & 0x + blocks[2] = bytebits_to_byte(bits + 32, 32); + + PrintAndLogEx(NORMAL, "Preparing to clone KERI to T55x7 with Internal Id: %u", id); + print_blocks(blocks, 3); + + UsbCommand resp; + UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; + + for (uint8_t i=0; i<3; i++) { + c.arg[0] = blocks[i]; + c.arg[1] = i; + clearCommandBuffer(); + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)){ + PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + return -1; + } + } + */ + return 0; +} + +int CmdKeriSim(const char *Cmd) { + + PrintAndLogEx(ERR, "TO BE DONE - Simulating KERI is not implemented yet"); +/* + uint8_t bits[64]; + uint8_t *bs = bits; + memset(bs, 0, sizeof(bits)); + + uint32_t internalid = 0; + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim(); + + internalid = param_get32ex(Cmd, 0, 0, 10); + + uint8_t clk = 32, encoding = 1, separator = 1, invert = 0; + uint16_t arg1, arg2; + size_t size = 64; + arg1 = clk << 8 | encoding; + arg2 = invert << 8 | separator; + + if ( !getkeriBits(internalid, bs)) { + PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + return 1; + } + + PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", id); + + UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; + memcpy(c.d.asBytes, bs, size); + clearCommandBuffer(); + SendCommand(&c); +*/ + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "This help"}, + {"demod", CmdKeriDemod, 1, "Demodulate an KERI tag from the GraphBuffer"}, + {"read", CmdKeriRead, 0, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdKeriClone, 0, "clone KERI to T55x7"}, + {"sim", CmdKeriSim, 0, "simulate KERI tag"}, + {NULL, NULL, 0, NULL} +}; + +int CmdLFKeri(const char *Cmd) { + clearCommandBuffer(); + CmdsParse(CommandTable, Cmd); + return 0; +} + +int CmdHelp(const char *Cmd) { + CmdsHelp(CommandTable); + return 0; +} diff --git a/client/cmdlfkeri.h b/client/cmdlfkeri.h new file mode 100644 index 000000000..ed0629b37 --- /dev/null +++ b/client/cmdlfkeri.h @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency Stanley/PAC tag commands +//----------------------------------------------------------------------------- +#ifndef CMDLFKERI_H__ +#define CMDLFKERI_H__ + +#include +#include +#include "proxmark3.h" +#include "ui.h" +#include "util.h" +#include "graph.h" +#include "cmdparser.h" +#include "cmddata.h" +#include "cmdmain.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // preamble test + +extern int CmdLFKeri(const char *Cmd); +extern int CmdKeriRead(const char *Cmd); +extern int CmdKeriDemod(const char *Cmd); +extern int CmdKeriClone(const char *Cmd); +extern int CmdKeriSim(const char *Cmd); + +extern int detectKeri(uint8_t *dest, size_t *size, bool *invert); + +extern int usage_lf_keri_clone(void); +extern int usage_lf_keri_sim(void); +#endif + From 9851f88139fecd3fc7c5f4dc880de7ddbed63623 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 15:45:22 +0100 Subject: [PATCH 232/320] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce939d980..0c7891297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Add 'lf keri' - basic support for Keri tags (@iceman) - Add 'hf mf list' - readded it again (@iceman) - Fix - A lot of bugfixes, like memory leaks (@iceman) - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit From f5f6f5d9162230a669eba99fda15a220a9efff0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 15:47:37 +0100 Subject: [PATCH 233/320] chg: linking in keri --- client/cmdlf.c | 1 + client/cmdlf.h | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 50077add2..4fc877061 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -957,6 +957,7 @@ static command_t CommandTable[] = { {"indala", CmdLFINDALA, 1, "{ Indala RFIDs... }"}, {"io", CmdLFIO, 1, "{ ioProx RFIDs... }"}, {"jablotron", CmdLFJablotron, 1, "{ Jablotron RFIDs... }"}, + {"keri", CmdLFKeri, 1, "{ KERI RFIDs... }"}, {"nedap", CmdLFNedap, 1, "{ Nedap RFIDs... }"}, {"nexwatch", CmdLFNEXWATCH, 1, "{ NexWatch RFIDs... }"}, {"noralsy", CmdLFNoralsy, 1, "{ Noralsy RFIDs... }"}, diff --git a/client/cmdlf.h b/client/cmdlf.h index de216435f..04c7317a1 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -42,13 +42,14 @@ #include "cmdlfnoralsy.h" // for NORALSY meny #include "cmdlffdx.h" // for FDX-B meny #include "cmdlfcotag.h" // for COTAG meny -#include "cmdlfindala.h" // for indala menu -#include "cmdlfguard.h"// for gproxii menu -#include "cmdlffdx.h" // for fdx-b menu -#include "cmdlfparadox.h"// for paradox menu +#include "cmdlfindala.h" // for indala menu +#include "cmdlfguard.h" // for gproxii menu +#include "cmdlffdx.h" // for fdx-b menu +#include "cmdlfparadox.h" // for paradox menu #include "cmdlfnexwatch.h" //for nexwatch menu #include "cmdlfsecurakey.h" //for securakey menu #include "cmdlfpac.h" // for pac menu +#include "cmdlfkeri.h" // for keri menu #define T55XX_WRITE_TIMEOUT 1500 From e0bf2e3fbf69b107977caf29908bef5dd767cd65 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 15:56:11 +0100 Subject: [PATCH 234/320] chg: 'lf search' - hooked up Keri detection --- client/cmdlf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmdlf.c b/client/cmdlf.c index 4fc877061..fc0aa5f6e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -891,6 +891,7 @@ int CmdLFfind(const char *Cmd) { if (CmdLFNedapDemod("")) { PrintAndLogEx(SUCCESS, "\nValid NEDAP ID Found!"); goto out;} if (CmdNexWatchDemod("")) { PrintAndLogEx(SUCCESS, "\nValid NexWatch ID Found!"); goto out;} if (CmdNoralsyDemod("")) { PrintAndLogEx(SUCCESS, "\nValid Noralsy ID Found!"); goto out;} + if (CmdKeriDemod("")) { PrintAndLogEx(SUCCESS, "\nValid KERI ID Found!"); goto out;} if (CmdPacDemod("")) { PrintAndLogEx(SUCCESS, "\nValid PAC/Stanley ID Found!"); goto out;} if (CmdParadoxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid Paradox ID Found!"); goto out;} if (CmdPrescoDemod("")) { PrintAndLogEx(SUCCESS, "\nValid Presco ID Found!"); goto out;} From 92b1f417930896e748788ca4511fe36ef28f740a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 16:02:44 +0100 Subject: [PATCH 235/320] revert chg, double free... --- client/cmdhfmfhard.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 9d9406c11..1ebf2131d 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -2397,7 +2397,6 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc key_found = brute_force(foundkey); free(candidates->states[ODD_STATE]); free(candidates->states[EVEN_STATE]); - free_statelist_cache(); free_candidates_memory(candidates); candidates = NULL; } else { From dc0dc7b00a374aff058b5b3cebe0d28285b90115 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 16:05:24 +0100 Subject: [PATCH 236/320] chg: cleanup --- client/cmdlfnexwatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index c90557665..4057fe452 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -34,14 +34,13 @@ int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) { int CmdNexWatchDemod(const char *Cmd) { if (!PSKDemod("", false)) { - if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); + PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); return 0; } bool invert = false; size_t size = DemodBufferLen; int idx = detectNexWatch(DemodBuffer, &size, &invert); - if (idx <= 0){ - if (g_debugMode){ + if (idx <= 0) { if (idx == -1) PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch not enough samples"); // else if (idx == -2) @@ -54,7 +53,7 @@ int CmdNexWatchDemod(const char *Cmd) { // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size); else PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch error %d",idx); - } + return 0; } @@ -101,6 +100,7 @@ static command_t CommandTable[] = { }; int CmdLFNEXWATCH(const char *Cmd) { + clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } From d1c22d0800034e65f09682a09645d72b2db4c14a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 16:29:00 +0100 Subject: [PATCH 237/320] fix: 'lf keri demod' - proper demod now --- client/cmdlfkeri.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index b5f6fa793..cfd01fedc 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -92,10 +92,8 @@ int CmdKeriDemod(const char *Cmd) { uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32); //get internal id - uint32_t ID = 0; - for (uint8_t i = 30; i < 59; i++){ - ID = (ID << 1) | DemodBuffer[i]; - } + uint32_t ID = bytebits_to_byte(DemodBuffer+29, 32); + ID &= 0x7FFFFFFF; /* 000000000000000000000000000001XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX111 @@ -111,18 +109,16 @@ int CmdKeriDemod(const char *Cmd) { Might be a hash of FC & CN to generate Internal ID */ - PrintAndLogEx(NORMAL, "KERI Tag Found -- Raw: %08X%08X", raw1 ,raw2); - - PrintAndLogEx(NORMAL, "KERI Internal ID: %d", ID); + PrintAndLogEx(NORMAL, "KERI Tag Found -- Raw: %08X%08X", raw1 ,raw2); + PrintAndLogEx(NORMAL, "KERI Internal ID: %u", ID); if (invert){ PrintAndLogEx(NORMAL, "Had to Invert - probably KERI"); for (size_t i = 0; i < size; i++) DemodBuffer[i] ^= 1; + + CmdPrintDemodBuff("x"); } - - CmdPrintDemodBuff("x"); - return 1; } From fe9c65b65fbcbe6cbab97e0d925171a0e19f39f0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Feb 2019 17:19:34 +0100 Subject: [PATCH 238/320] chg: 'lf keri clone' - now works --- client/cmdlfkeri.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index cfd01fedc..70cdb4ca9 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -129,10 +129,15 @@ int CmdKeriRead(const char *Cmd) { int CmdKeriClone(const char *Cmd) { - PrintAndLogEx(ERR, "TO BE DONE - Cloning KERI is not implemented yet"); - /* + uint32_t internalid = 0; - uint32_t blocks[3] = {T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT | T55x7_BITRATE_RF_16, 0, 0}; + uint32_t blocks[3] = { + T55x7_X_MODE | T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT | T55x7_BITRATE_RF_128, + 0, + 0}; + + // safe key + blocks[0] |= 6 << 28; char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_clone(); @@ -141,18 +146,20 @@ int CmdKeriClone(const char *Cmd) { //Q5 if (tolower(param_getchar(Cmd, 1)) == 'q') - blocks[0] = T5555_MODULATION_PSK1 | T5555_SET_BITRATE(16) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; + blocks[0] = T5555_MODULATION_PSK1 | T5555_SET_BITRATE(128) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; - // MSB is ONE, and 3 LSB is ONE - uint32_t pre = - internalid &= 0x80000003; + // MSB is ONE + internalid |= 0x80000000; + // 3 LSB is ONE + uint64_t data = ((uint64_t)internalid << 3 ) + 7; + // - blocks[1] = internalid & 0x - blocks[2] = bytebits_to_byte(bits + 32, 32); + blocks[1] = data >> 32; + blocks[2] = data & 0xFFFFFFFF; - PrintAndLogEx(NORMAL, "Preparing to clone KERI to T55x7 with Internal Id: %u", id); + PrintAndLogEx(NORMAL, "Preparing to clone KERI to T55x7 with Internal Id: %u", internalid); print_blocks(blocks, 3); UsbCommand resp; @@ -168,7 +175,7 @@ int CmdKeriClone(const char *Cmd) { return -1; } } - */ + return 0; } From a07dcf79240e310f7ced60e4f0b819be5b9abb15 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 10:25:53 +0100 Subject: [PATCH 239/320] chg: 'lf keri clone' - correct config block (use extended modes bit rates) --- client/cmdlfkeri.c | 56 ++++++++++++++++++++++++++++------------------ common/protocols.h | 1 + 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 70cdb4ca9..fb4f26703 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -130,14 +130,19 @@ int CmdKeriRead(const char *Cmd) { int CmdKeriClone(const char *Cmd) { + uint32_t internalid = 0; uint32_t blocks[3] = { - T55x7_X_MODE | T55x7_MODULATION_PSK1 | T55x7_PSKCF_RF_2 | 2 << T55x7_MAXBLOCK_SHIFT | T55x7_BITRATE_RF_128, + T55x7_TESTMODE_DISABLED | + T55x7_X_MODE | + T55x7_MODULATION_PSK1 | + T55x7_PSKCF_RF_2 | + 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - // safe key - blocks[0] |= 6 << 28; + // dynamic bitrate used + blocks[0] |= 0xF << 18; char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_clone(); @@ -145,8 +150,13 @@ int CmdKeriClone(const char *Cmd) { internalid = param_get32ex(Cmd, 0, 0, 10); //Q5 - if (tolower(param_getchar(Cmd, 1)) == 'q') - blocks[0] = T5555_MODULATION_PSK1 | T5555_SET_BITRATE(128) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT; + if (tolower(param_getchar(Cmd, 1)) == 'q') { + blocks[0] = + T5555_MODULATION_PSK1 | + T5555_SET_BITRATE(128) | + T5555_PSK_RF_2 | + 2 << T5555_MAXBLOCK_SHIFT; + } // MSB is ONE @@ -161,11 +171,13 @@ int CmdKeriClone(const char *Cmd) { PrintAndLogEx(NORMAL, "Preparing to clone KERI to T55x7 with Internal Id: %u", internalid); print_blocks(blocks, 3); - + + UsbCommand resp; UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; - for (uint8_t i=0; i<3; i++) { + + for (uint8_t i = 0; i < 3; i++) { c.arg[0] = blocks[i]; c.arg[1] = i; clearCommandBuffer(); @@ -181,37 +193,37 @@ int CmdKeriClone(const char *Cmd) { int CmdKeriSim(const char *Cmd) { - PrintAndLogEx(ERR, "TO BE DONE - Simulating KERI is not implemented yet"); -/* + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim(); + uint8_t bits[64]; uint8_t *bs = bits; memset(bs, 0, sizeof(bits)); - uint32_t internalid = 0; + uint32_t internalid = param_get32ex(Cmd, 0, 0, 10); - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim(); + // loop to bits. + internalid |= 0x80000000; - internalid = param_get32ex(Cmd, 0, 0, 10); + // 3 LSB is ONE + uint64_t data = ((uint64_t)internalid << 3 ) + 7; + - uint8_t clk = 32, encoding = 1, separator = 1, invert = 0; + + uint8_t clk = 32, carrier = 2, invert = 0; uint16_t arg1, arg2; size_t size = 64; - arg1 = clk << 8 | encoding; - arg2 = invert << 8 | separator; + arg1 = clk << 8 | carrier; + arg2 = invert; - if ( !getkeriBits(internalid, bs)) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); - return 1; - } - PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", id); + PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", internalid); UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bs, size); clearCommandBuffer(); SendCommand(&c); -*/ + return 0; } diff --git a/common/protocols.h b/common/protocols.h index 3c2e79a8d..73355c85d 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -389,6 +389,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T55x7_BITRATE_RF_64 0x00140000 #define T55x7_BITRATE_RF_100 0x00180000 #define T55x7_BITRATE_RF_128 0x001C0000 +#define T55x7_TESTMODE_DISABLED 0x60000000 /* T5555 (Q5) configuration register definitions */ #define T5555_ST_TERMINATOR 0x00000001 From 9f10ff6e1794bea5e7dff43624926bf86737be07 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 10:26:55 +0100 Subject: [PATCH 240/320] sugar --- client/cmdhfmfu.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index d703f980d..8b27d9b22 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2381,7 +2381,7 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_gendiverse(); if ( cmdp == 'r' ) { - // read uid from tag + // read uid from tag UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0}}; clearCommandBuffer(); SendCommand(&c); @@ -2390,8 +2390,13 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); - uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision - if(select_status == 0) { + uint64_t select_status = resp.arg[0]; + // 0: couldn't read, + // 1: OK, with ATS + // 2: OK, no ATS + // 3: proprietary Anticollision + + if ( select_status == 0 ) { PrintAndLogEx(WARNING, "iso14443a card select failed"); return 1; } @@ -2446,12 +2451,12 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ PrintAndLogEx(NORMAL, "Diversified key: %s", sprint_hex(divkey+1, 6)); for (int i=0; i < sizeof(mifarekeyA); ++i){ - dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; - dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1); + dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; + dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1); } for (int i=0; i < sizeof(mifarekeyB); ++i){ - dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1); + dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1); dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff; } @@ -2488,6 +2493,7 @@ int CmdHF14AMfuPwdGen(const char *Cmd){ uint8_t uid[7] = {0x00}; char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_hf_mfu_pwdgen(); + if (cmdp == 't') return ul_ev1_pwdgen_selftest(); if ( cmdp == 'r') { @@ -2500,8 +2506,12 @@ int CmdHF14AMfuPwdGen(const char *Cmd){ iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); - uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision - if(select_status == 0) { + uint64_t select_status = resp.arg[0]; + // 0: couldn't read + // 1: OK with ATS + // 2: OK, no ATS + // 3: proprietary Anticollision + if ( select_status == 0 ) { PrintAndLogEx(WARNING, "iso14443a card select failed"); return 1; } @@ -2514,6 +2524,7 @@ int CmdHF14AMfuPwdGen(const char *Cmd){ else { if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen(); } + PrintAndLogEx(NORMAL, "---------------------------------"); PrintAndLogEx(NORMAL, " Using UID : %s", sprint_hex(uid, 7)); PrintAndLogEx(NORMAL, "---------------------------------"); @@ -2531,8 +2542,7 @@ int CmdHF14AMfuPwdGen(const char *Cmd){ //------------------------------------ // Menu Stuff //------------------------------------ -static command_t CommandTable[] = -{ +static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"info", CmdHF14AMfUInfo, 0, "Tag information"}, @@ -2552,7 +2562,6 @@ static command_t CommandTable[] = int CmdHFMFUltra(const char *Cmd){ clearCommandBuffer(); - //WaitForResponseTimeout(CMD_ACK,NULL,100); CmdsParse(CommandTable, Cmd); return 0; } From 730b4940f8c19d2cd3631b605bcbc064babcbf31 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 11:14:51 +0100 Subject: [PATCH 241/320] chg: 'lf keri sim' - is kind of up, *untested* --- client/cmdlfkeri.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index fb4f26703..ec8020aa2 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -16,7 +16,7 @@ int usage_lf_keri_clone(void){ PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : KERI Internal ID"); + PrintAndLogEx(NORMAL, " : Keri Internal ID"); PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -128,8 +128,6 @@ int CmdKeriRead(const char *Cmd) { } int CmdKeriClone(const char *Cmd) { - - uint32_t internalid = 0; uint32_t blocks[3] = { @@ -196,19 +194,17 @@ int CmdKeriSim(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim(); - uint8_t bits[64]; - uint8_t *bs = bits; - memset(bs, 0, sizeof(bits)); - - uint32_t internalid = param_get32ex(Cmd, 0, 0, 10); - - // loop to bits. + uint64_t internalid = param_get32ex(Cmd, 0, 0, 10); internalid |= 0x80000000; + internalid <<= 3; + internalid += 7; - // 3 LSB is ONE - uint64_t data = ((uint64_t)internalid << 3 ) + 7; - - + uint8_t bits[64] = {0x00}; + // loop to bits + uint8_t j = 0; + for ( int8_t i = 63; i >= 0; --i) { + bits[j++] = ((internalid >> i) & 1 ); + } uint8_t clk = 32, carrier = 2, invert = 0; uint16_t arg1, arg2; @@ -216,14 +212,13 @@ int CmdKeriSim(const char *Cmd) { arg1 = clk << 8 | carrier; arg2 = invert; - PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", internalid); - + UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bs, size); clearCommandBuffer(); SendCommand(&c); - + return 0; } From 1c2dea29bb56f0757d01f029538eeee9328724e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 14:38:33 +0100 Subject: [PATCH 242/320] chg --- client/cmdlfem4x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 7b4386fbb..97e0668cc 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -364,9 +364,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) { int ans = Em410xDecode(bits, &size, &idx, hi, lo); if ( ans < 0){ - if (ans == -1) - PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x not only 0|1 in decoded bitstream"); - else if (ans == -2) + if (ans == -2) PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x not enough samples after demod"); else if (ans == -4) PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x preamble not found"); From 8cc9cc312f72ef0bb599f22fc2642893baa0673a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 14:39:20 +0100 Subject: [PATCH 243/320] chg... names names..sigh --- client/cmdlfkeri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index ec8020aa2..884e89933 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -215,7 +215,7 @@ int CmdKeriSim(const char *Cmd) { PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", internalid); UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; - memcpy(c.d.asBytes, bs, size); + memcpy(c.d.asBytes, bits, size); clearCommandBuffer(); SendCommand(&c); From cea5b5214d3ceab5fcf374984f52bd01af3f8758 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 14:51:21 +0100 Subject: [PATCH 244/320] chg: colors --- client/cmdhficlass.c | 4 ++-- client/cmdhfmf.c | 2 +- client/cmdlft55xx.c | 27 ++++++++++++++------------- client/cmdsmartcard.c | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index ddc6fb2c0..82e14d5ea 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -626,7 +626,7 @@ int CmdHFiClassELoad(const char *Cmd) { f = fopen(filename, "rb"); if ( !f ){ - PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename); return 1; } @@ -2304,7 +2304,7 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) { int keyitems = 0; if ( !(f = fopen( filename , "r")) ) { - PrintAndLogEx(ERR, "file: %s: not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename); return 1; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 2412aecee..76f0fc2b6 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1812,7 +1812,7 @@ int CmdHF14AMfChk(const char *Cmd) { f = fopen( filename , "r"); if ( !f ) { - PrintAndLogEx(FAILED, "File: " _YELLOW_(%s)": not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename); continue; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index abf8f04ec..52240f0db 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -691,7 +691,7 @@ bool tryDetectModulation(){ bool retval = false; if ( hits > 1) { - PrintAndLogEx(NORMAL, "Found [%d] possible matches for modulation.",hits); + PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits); for(int i=0; i>28==6 || b.block0>>28==9))) ); - PrintAndLogEx(NORMAL, "Inverted : %s", (b.inverted) ? "Yes" : "No" ); + PrintAndLogEx(NORMAL, "Inverted : %s", (b.inverted) ? _GREEN_(Yes) : "No" ); PrintAndLogEx(NORMAL, "Offset : %d", b.offset); - PrintAndLogEx(NORMAL, "Seq. Term. : %s", (b.ST) ? "Yes" : "No" ); + PrintAndLogEx(NORMAL, "Seq. Term. : %s", (b.ST) ? _GREEN_(Yes) : "No" ); PrintAndLogEx(NORMAL, "Block0 : 0x%08X", b.block0); PrintAndLogEx(NORMAL, ""); return 0; @@ -1264,24 +1264,25 @@ int CmdT55xxInfo(const char *Cmd){ uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; uint32_t por = PackBits(si, 1, DemodBuffer); si += 1; - if (config.Q5) PrintAndLogEx(NORMAL, "*** Warning *** Config Info read off a Q5 will not display as expected"); + if (config.Q5) PrintAndLogEx(NORMAL, _RED_(*** Warning ***) " Config Info read off a Q5 will not display as expected"); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "-- T55x7 Configuration & Tag Information --------------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " Safer key : %s", GetSaferStr(safer)); PrintAndLogEx(NORMAL, " reserved : %d", resv); PrintAndLogEx(NORMAL, " Data bit rate : %s", GetBitRateStr(dbr, extend)); - PrintAndLogEx(NORMAL, " eXtended mode : %s", (extend) ? "Yes - Warning":"No"); + PrintAndLogEx(NORMAL, " eXtended mode : %s", (extend) ? _YELLOW_("Yes - Warning") : "No"); PrintAndLogEx(NORMAL, " Modulation : %s", GetModulationStr(datamod)); PrintAndLogEx(NORMAL, " PSK clock frequency : %d", pskcf); - PrintAndLogEx(NORMAL, " AOR - Answer on Request : %s", (aor) ? "Yes":"No"); - PrintAndLogEx(NORMAL, " OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" ); + PrintAndLogEx(NORMAL, " AOR - Answer on Request : %s", (aor) ? _GREEN_(Yes) : "No"); + PrintAndLogEx(NORMAL, " OTP - One Time Pad : %s", (otp) ? _YELLOW_(Yes - Warning) : "No" ); PrintAndLogEx(NORMAL, " Max block : %d", maxblk); - PrintAndLogEx(NORMAL, " Password mode : %s", (pwd) ? "Yes":"No"); - PrintAndLogEx(NORMAL, " Sequence Start Terminator : %s", (sst) ? "Yes":"No"); - PrintAndLogEx(NORMAL, " Fast Write : %s", (fw) ? "Yes":"No"); - PrintAndLogEx(NORMAL, " Inverse data : %s", (inv) ? "Yes":"No"); - PrintAndLogEx(NORMAL, " POR-Delay : %s", (por) ? "Yes":"No"); + PrintAndLogEx(NORMAL, " Password mode : %s", (pwd) ? _GREEN_(Yes) : "No"); + PrintAndLogEx(NORMAL, " Sequence Start Terminator : %s", (sst) ? _GREEN_(Yes) : "No"); + PrintAndLogEx(NORMAL, " Fast Write : %s", (fw) ? _GREEN_(Yes) : "No"); + PrintAndLogEx(NORMAL, " Inverse data : %s", (inv) ? _GREEN_(Yes) : "No"); + PrintAndLogEx(NORMAL, " POR-Delay : %s", (por) ? _GREEN_(Yes) : "No"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " Raw Data - Page 0"); PrintAndLogEx(NORMAL, " Block 0 : 0x%08X %s", block0, sprint_bin(DemodBuffer + config.offset, 32) ); @@ -1581,7 +1582,7 @@ int CmdT55xxChkPwds(const char *Cmd) { FILE * f = fopen( filename , "r"); if ( !f ) { - PrintAndLogEx(WARNING, "File: %s: not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename); free(keyBlock); return 1; } diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index f9b77dad0..8b10dc6fe 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -595,7 +595,7 @@ int CmdSmartUpgrade(const char *Cmd) { // load file f = fopen(filename, "rb"); if ( !f ){ - PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename); + PrintAndLogEx(FAILED, "File: " _YELLOW_(%s) ": not found or locked.", filename); return 1; } From 38262389fc29dc4ca6bde51ef1f8db60a6098856 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 14:58:22 +0100 Subject: [PATCH 245/320] chg: colors --- client/cmdlft55xx.c | 51 ++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 52240f0db..535b6fa1c 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -954,13 +954,11 @@ int CmdT55xxWakeUp(const char *Cmd) { uint32_t password = 0; uint8_t cmdp = 0; bool errors = false; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_t55xx_wakup(); case 'p': - case 'P': password = param_get32ex(Cmd, cmdp+1, 0, 16); cmdp += 2; errors = false; @@ -976,7 +974,7 @@ int CmdT55xxWakeUp(const char *Cmd) { UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; clearCommandBuffer(); SendCommand(&c); - PrintAndLogEx(NORMAL, "Wake up command sent. Try read now"); + PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); return 0; } @@ -990,30 +988,25 @@ int CmdT55xxWriteBlock(const char *Cmd) { bool testMode = false; bool errors = false; uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_t55xx_write(); case 'b': - case 'B': errors |= param_getdec(Cmd, cmdp+1, &block); cmdp += 2; break; case 'd': - case 'D': data = param_get32ex(Cmd, cmdp+1, 0, 16); gotdata = true; cmdp += 2; break; case 'p': - case 'P': password = param_get32ex(Cmd, cmdp+1, 0, 16); usepwd = true; cmdp += 2; break; case 't': - case 'T': testMode = true; cmdp++; break; @@ -1030,7 +1023,7 @@ int CmdT55xxWriteBlock(const char *Cmd) { if (errors || !gotdata) return usage_t55xx_write(); if (block > 7) { - PrintAndLogEx(NORMAL, "Block number must be between 0 and 7"); + PrintAndLogEx(WARNING, "Block number must be between 0 and 7"); return 0; } @@ -1042,7 +1035,7 @@ int CmdT55xxWriteBlock(const char *Cmd) { char pwdStr[16] = {0}; snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); - PrintAndLogEx(NORMAL, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "" ); + PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "" ); //Password mode if (usepwd) { @@ -1059,12 +1052,13 @@ int CmdT55xxWriteBlock(const char *Cmd) { } int CmdT55xxReadTrace(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - bool pwdmode = false; - uint32_t password = 0; - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_trace(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) > 1 || cmdp == 'h') return usage_t55xx_trace(); - if (strlen(Cmd)==0) { + bool pwdmode = false; + uint32_t password = 0; + + if (strlen(Cmd) == 0) { // sanity check. if (!SanityOfflineCheck(false)) return 1; @@ -1091,7 +1085,7 @@ int CmdT55xxReadTrace(const char *Cmd) { uint32_t hdr = PackBits(si, 9, DemodBuffer); si += 9; if (hdr != 0x1FF) { - PrintAndLogEx(NORMAL, "Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr); + PrintAndLogEx(FAILED, "Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr); return 1; } @@ -1130,7 +1124,7 @@ int CmdT55xxReadTrace(const char *Cmd) { data.acl = PackBits(si, 8, DemodBuffer); si += 8; if ( data.acl != 0xE0 ) { - PrintAndLogEx(NORMAL, "The modulation is most likely wrong since the ACL is not 0xE0. "); + PrintAndLogEx(FAILED, "The modulation is most likely wrong since the ACL is not 0xE0. "); return 1; } @@ -1227,11 +1221,11 @@ int CmdT55xxInfo(const char *Cmd){ */ bool pwdmode = false; uint32_t password = 0; - char cmdp = param_getchar(Cmd, 0); + char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_info(); + if (strlen(Cmd) > 1 || cmdp == 'h') return usage_t55xx_info(); - if (strlen(Cmd)==0){ + if (strlen(Cmd) == 0) { // sanity check. if (!SanityOfflineCheck(false)) return 1; @@ -1264,7 +1258,8 @@ int CmdT55xxInfo(const char *Cmd){ uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; uint32_t por = PackBits(si, 1, DemodBuffer); si += 1; - if (config.Q5) PrintAndLogEx(NORMAL, _RED_(*** Warning ***) " Config Info read off a Q5 will not display as expected"); + if (config.Q5) + PrintAndLogEx(NORMAL, _RED_(*** Warning ***) " Config Info read off a Q5 will not display as expected"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "-- T55x7 Configuration & Tag Information --------------------"); @@ -1272,7 +1267,7 @@ int CmdT55xxInfo(const char *Cmd){ PrintAndLogEx(NORMAL, " Safer key : %s", GetSaferStr(safer)); PrintAndLogEx(NORMAL, " reserved : %d", resv); PrintAndLogEx(NORMAL, " Data bit rate : %s", GetBitRateStr(dbr, extend)); - PrintAndLogEx(NORMAL, " eXtended mode : %s", (extend) ? _YELLOW_("Yes - Warning") : "No"); + PrintAndLogEx(NORMAL, " eXtended mode : %s", (extend) ? _YELLOW_(Yes - Warning) : "No"); PrintAndLogEx(NORMAL, " Modulation : %s", GetModulationStr(datamod)); PrintAndLogEx(NORMAL, " PSK clock frequency : %d", pskcf); PrintAndLogEx(NORMAL, " AOR - Answer on Request : %s", (aor) ? _GREEN_(Yes) : "No"); @@ -1294,8 +1289,8 @@ int CmdT55xxDump(const char *Cmd){ uint32_t password = 0; bool override = false; - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if ( cmdp == 'h') return usage_t55xx_dump(); bool usepwd = ( strlen(Cmd) > 0); if ( usepwd ){ From 7bbb2cdb9d55c04ba8fd84a1f4b736862ed0bb7d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:07:41 +0100 Subject: [PATCH 246/320] chg: 'lf t55xx chk' - logic params. chg: colors --- client/cmdlft55xx.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 535b6fa1c..8d850f5d0 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1475,7 +1475,7 @@ int CmdT55xxWipe(const char *Cmd) { // Try with the default password to reset block 0 // With a pwd should work even if pwd bit not set - PrintAndLogEx(NORMAL, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); + PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); if ( Q5 ) snprintf(ptrData,sizeof(writeData),"b 0 d 6001F004 p 0"); @@ -1490,7 +1490,7 @@ int CmdT55xxWipe(const char *Cmd) { if (!CmdT55xxWriteBlock(ptrData)) PrintAndLogEx(WARNING, "Error writing blk %d", blk); - memset(writeData,0x00, sizeof(writeData)); + memset(writeData, 0x00, sizeof(writeData)); } return 0; } @@ -1517,7 +1517,7 @@ int CmdT55xxChkPwds(const char *Cmd) { memset(line, 0, sizeof(line)); char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_chk(); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_t55xx_chk(); /* if ( T55xxReadBlock(7, 0, 0, 0, 0) ) { @@ -1618,7 +1618,8 @@ int CmdT55xxChkPwds(const char *Cmd) { // PrintAndLogEx(NORMAL, "chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) ); keycnt++; memset(line, 0, sizeof(line)); - } + } + if (f) fclose(f); @@ -1731,7 +1732,7 @@ int CmdT55xxBruteForce(const char *Cmd) { } int tryOnePassword(uint32_t password) { - PrintAndLogEx(NORMAL, "Trying password %08x", password); + PrintAndLogEx(INFO, "Trying password %08x", password); if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password)) { PrintAndLogEx(NORMAL, "Acquire data from device failed. Quitting"); return -1; @@ -1750,8 +1751,8 @@ int CmdT55xxRecoverPW(const char *Cmd) { uint32_t prev_password = 0xffffffff; uint32_t mask = 0x0; int found = 0; - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_recoverpw(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (cmdp == 'h' ) return usage_t55xx_recoverpw(); orig_password = param_get32ex(Cmd, 0, 0x51243648, 16); //password used by handheld cloners @@ -1934,13 +1935,11 @@ int CmdT55xxDetectPage1(const char *Cmd){ uint32_t password = 0; uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_t55xx_detectP1(); case 'p': - case 'P': password = param_get32ex(Cmd, cmdp+1, 0, 16); usepwd = true; cmdp += 2; @@ -1963,7 +1962,7 @@ int CmdT55xxDetectPage1(const char *Cmd){ return false; } bool success = tryDetectP1(false); - if (success) PrintAndLogEx(NORMAL, "T55xx chip found!"); + if (success) PrintAndLogEx(SUCCESS, "T55xx chip found!"); return success; } From 730304ca926a538effa8e3c65269a371ebe84981 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:10:19 +0100 Subject: [PATCH 247/320] texts --- client/cmdlf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index fc0aa5f6e..d51dfe7c7 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -819,14 +819,16 @@ int CheckChipType(bool getDeviceData) { //check for em4x05/em4x69 chips first uint32_t word = 0; if (EM4x05IsBlock0(&word)) { - PrintAndLogEx(NORMAL, "\nValid EM4x05/EM4x69 Chip Found\nTry lf em 4x05... commands\n"); + PrintAndLogEx(SUCCESS, "\nValid EM4x05/EM4x69 Chip Found"); + PrintAndLogEx(SUCCESS, "Try lf em 4x05... commands"); save_restoreGB(GRAPH_RESTORE); return 1; } //check for t55xx chip... if (tryDetectP1(true)) { - PrintAndLogEx(NORMAL, "\nValid T55xx Chip Found\nTry `lf t55xx` commands\n"); + PrintAndLogEx(SUCCESS, "\nValid T55xx Chip Found"); + PrintAndLogEx(SUCCESS, "Try `lf t55xx` commands"); save_restoreGB(GRAPH_RESTORE); return 1; } From 8551f811ca0f0dfa620f56f9aa6d804b3ccfc100 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:13:31 +0100 Subject: [PATCH 248/320] colors --- client/cmdlf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index d51dfe7c7..f882a7ca3 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -858,9 +858,10 @@ int CmdLFfind(const char *Cmd) { return 0; } - PrintAndLogEx(NORMAL, "NOTE: some demods output possible binary\n if it finds something that looks like a tag"); - PrintAndLogEx(NORMAL, "False Positives ARE possible\n"); - PrintAndLogEx(NORMAL, "\nChecking for known tags:\n"); + PrintAndLogEx(INFO, "NOTE: some demods output possible binary"); + PrintAndLogEx(INFO, "if it finds something that looks like a tag"); + PrintAndLogEx(INFO, "False Positives " _YELLOW_(ARE) "possible\n"); + PrintAndLogEx(INFO, "\nChecking for known tags:\n"); // only run these tests if device is online if (isOnline) { From cc2c440683d4a842745dd77754bfa61841a4014a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:16:57 +0100 Subject: [PATCH 249/320] chg: 'lf search' - colors --- client/cmdlf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index f882a7ca3..e41f2d6aa 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -820,7 +820,7 @@ int CheckChipType(bool getDeviceData) { uint32_t word = 0; if (EM4x05IsBlock0(&word)) { PrintAndLogEx(SUCCESS, "\nValid EM4x05/EM4x69 Chip Found"); - PrintAndLogEx(SUCCESS, "Try lf em 4x05... commands"); + PrintAndLogEx(SUCCESS, "Try " _YELLOW_(`lf em 4x05`) " commands"); save_restoreGB(GRAPH_RESTORE); return 1; } @@ -828,7 +828,7 @@ int CheckChipType(bool getDeviceData) { //check for t55xx chip... if (tryDetectP1(true)) { PrintAndLogEx(SUCCESS, "\nValid T55xx Chip Found"); - PrintAndLogEx(SUCCESS, "Try `lf t55xx` commands"); + PrintAndLogEx(SUCCESS, "Try " _YELLOW_(`lf t55xx`)" commands"); save_restoreGB(GRAPH_RESTORE); return 1; } From 69b691494d5633a5e040656536599574bdc73e91 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:26:31 +0100 Subject: [PATCH 250/320] text --- client/cmdlfcotag.c | 2 +- client/cmdlffdx.c | 38 +++++++++++++++++++------------------- client/cmdlfguard.c | 8 ++++---- client/cmdlfviking.c | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index dce160192..ff0167938 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -58,7 +58,7 @@ int CmdCOTAGDemod(const char *Cmd) { 0 1001 1100 1100 0001 1000 0101 0000 0000 100001010000000001111011100000011010000010000000000000000000000000000000000000000000000000000000100111001100000110000101000 1001 1100 1100 0001 10000101 */ - PrintAndLogEx(NORMAL, "COTAG Found: FC %u, CN: %u Raw: %08X%08X%08X%08X", fc, cn, raw1 ,raw2, raw3, raw4); + PrintAndLogEx(SUCCESS, "COTAG Found: FC %u, CN: %u Raw: %08X%08X%08X%08X", fc, cn, raw1 ,raw2, raw3, raw4); return 1; } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index c2b54b497..8b67358ca 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -196,7 +196,7 @@ int CmdFDXBdemodBI(const char *Cmd){ PrintAndLogEx(DEBUG, "DEBUG: Error - FDXB error removeParity:: %d", size); return 0; } - PrintAndLogEx(NORMAL, "\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); + PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); //got a good demod uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32); @@ -211,17 +211,17 @@ int CmdFDXBdemodBI(const char *Cmd){ uint8_t raw[8]; num_to_bytes(rawid, 8, raw); - PrintAndLogEx(NORMAL, "Raw ID Hex: %s", sprint_hex(raw,8)); + PrintAndLogEx(SUCCESS, "Raw ID Hex: %s", sprint_hex(raw,8)); uint16_t calcCrc = crc16_kermit(raw, 8); - PrintAndLogEx(NORMAL, "Animal ID: %04u-%012" PRIu64, countryCode, NationalCode); - PrintAndLogEx(NORMAL, "National Code: %012" PRIu64, NationalCode); - PrintAndLogEx(NORMAL, "CountryCode: %04u", countryCode); + PrintAndLogEx(SUCCESS, "Animal ID: %04u-%012" PRIu64, countryCode, NationalCode); + PrintAndLogEx(SUCCESS, "National Code: %012" PRIu64, NationalCode); + PrintAndLogEx(SUCCESS, "CountryCode: %04u", countryCode); - PrintAndLogEx(NORMAL, "Reserved/RFU: %u", reservedCode); - PrintAndLogEx(NORMAL, "Animal Tag: %s", animalBit ? "True" : "False"); - PrintAndLogEx(NORMAL, "Has extended data: %s [0x%X]", dataBlockBit ? "True" : "False", extended); - PrintAndLogEx(NORMAL, "CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); + PrintAndLogEx(SUCCESS, "Reserved/RFU: %u", reservedCode); + PrintAndLogEx(SUCCESS, "Animal Tag: %s", animalBit ? "True" : "False"); + PrintAndLogEx(SUCCESS, "Has extended data: %s [0x%X]", dataBlockBit ? "True" : "False", extended); + PrintAndLogEx(SUCCESS, "CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); @@ -282,14 +282,14 @@ int CmdFdxDemod(const char *Cmd) { uint16_t calcCrc = crc16_kermit(raw, 8); - PrintAndLogEx(NORMAL, "\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); - PrintAndLogEx(NORMAL, "Animal ID %04u-%012" PRIu64, countryCode, NationalCode); - PrintAndLogEx(NORMAL, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); - PrintAndLogEx(NORMAL, "Country Code %04u", countryCode); - PrintAndLogEx(NORMAL, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); - PrintAndLogEx(NORMAL, "Animal Tag %s", animalBit ? "True" : "False"); - PrintAndLogEx(NORMAL, "Has extended data %s [0x%X]", dataBlockBit ? "True" : "False", extended); - PrintAndLogEx(NORMAL, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? "Ok" : "Failed"); + PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); + PrintAndLogEx(SUCCESS, "Animal ID %04u-%012" PRIu64, countryCode, NationalCode); + PrintAndLogEx(SUCCESS, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); + PrintAndLogEx(SUCCESS, "Country Code %04u", countryCode); + PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); + PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? "True" : "False"); + PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? "True" : "False", extended); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? "Ok" : "Failed"); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); @@ -341,7 +341,7 @@ int CmdFdxClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bs + 64, 32); blocks[4] = bytebits_to_byte(bs + 96, 32); - PrintAndLogEx(NORMAL, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); + PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); print_blocks(blocks, 5); UsbCommand resp; @@ -379,7 +379,7 @@ int CmdFdxSim(const char *Cmd) { arg1 = clk << 8 | encoding; arg2 = invert << 8 | separator; - PrintAndLogEx(NORMAL, "Simulating FDX-B animal ID: %04u-%"PRIu64, countryid, animalid); + PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: %04u-%"PRIu64, countryid, animalid); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index afad96686..593dcf2b8 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -246,9 +246,9 @@ int CmdGuardDemod(const char *Cmd) { break; } if ( !unknown) - PrintAndLogEx(NORMAL, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3); else - PrintAndLogEx(NORMAL, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3); return 1; } @@ -290,7 +290,7 @@ int CmdGuardClone(const char *Cmd) { blocks[2] = bytebits_to_byte(bs + 32, 32); blocks[3] = bytebits_to_byte(bs + 64, 32); - PrintAndLogEx(NORMAL, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); + PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, 4); UsbCommand resp; @@ -333,7 +333,7 @@ int CmdGuardSim(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber ); + PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber ); uint64_t arg1, arg2; arg1 = (clock << 8) | encoding; diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 984e5ec83..5ead8ef03 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -118,7 +118,7 @@ int CmdVikingClone(const char *Cmd) { rawID = getVikingBits(id); - PrintAndLogEx(NORMAL, "Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); + PrintAndLogEx(INFO, "Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); UsbCommand c = {CMD_VIKING_CLONE_TAG, {rawID >> 32, rawID & 0xFFFFFFFF, Q5}}; clearCommandBuffer(); @@ -149,7 +149,7 @@ int CmdVikingSim(const char *Cmd) { arg1 = clk << 8 | encoding; arg2 = invert << 8 | separator; - PrintAndLogEx(NORMAL, "Simulating Viking - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); + PrintAndLogEx(SUCCESS, "Simulating Viking - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; num_to_bytebits(rawID, size, c.d.asBytes); From 9f26c0d6b7faa9d733a2e1eb3990b19e95ee01fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:29:28 +0100 Subject: [PATCH 251/320] text --- client/cmdlfkeri.c | 10 +++++----- client/cmdlfnoralsy.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 884e89933..560cd5c96 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -109,11 +109,11 @@ int CmdKeriDemod(const char *Cmd) { Might be a hash of FC & CN to generate Internal ID */ - PrintAndLogEx(NORMAL, "KERI Tag Found -- Raw: %08X%08X", raw1 ,raw2); - PrintAndLogEx(NORMAL, "KERI Internal ID: %u", ID); + PrintAndLogEx(SUCCESS, "KERI Tag Found -- Internal ID: %u", ID); + PrintAndLogEx(SUCCESS, "Raw: %08X%08X", raw1 ,raw2); if (invert){ - PrintAndLogEx(NORMAL, "Had to Invert - probably KERI"); + PrintAndLogEx(INFO, "Had to Invert - probably KERI"); for (size_t i = 0; i < size; i++) DemodBuffer[i] ^= 1; @@ -167,7 +167,7 @@ int CmdKeriClone(const char *Cmd) { blocks[1] = data >> 32; blocks[2] = data & 0xFFFFFFFF; - PrintAndLogEx(NORMAL, "Preparing to clone KERI to T55x7 with Internal Id: %u", internalid); + PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %u", internalid); print_blocks(blocks, 3); @@ -212,7 +212,7 @@ int CmdKeriSim(const char *Cmd) { arg1 = clk << 8 | carrier; arg2 = invert; - PrintAndLogEx(NORMAL, "Simulating KERI - Internal Id: %u", internalid); + PrintAndLogEx(SUCCESS, "Simulating KERI - Internal Id: %u", internalid); UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bits, size); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index bb28ad5e5..0f61e26ea 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -161,10 +161,10 @@ int CmdNoralsyDemod(const char *Cmd) { return 0; } - PrintAndLogEx(NORMAL, "Noralsy Tag Found: Card ID %u, Year: %u Raw: %08X%08X%08X", cardid, year, raw1 ,raw2, raw3); + PrintAndLogEx(SUCCESS, "Noralsy Tag Found: Card ID %u, Year: %u Raw: %08X%08X%08X", cardid, year, raw1 ,raw2, raw3); if (raw1 != 0xBB0214FF) { - PrintAndLogEx(NORMAL, "Unknown bits set in first block! Expected 0xBB0214FF, Found: 0x%08X", raw1); - PrintAndLogEx(NORMAL, "Please post this output in forum to further research on this format"); + PrintAndLogEx(WARNING, "Unknown bits set in first block! Expected 0xBB0214FF, Found: 0x%08X", raw1); + PrintAndLogEx(WARNING, "Please post this output in forum to further research on this format"); } return 1; } @@ -202,7 +202,7 @@ int CmdNoralsyClone(const char *Cmd) { blocks[2] = bytebits_to_byte(bits + 32, 32); blocks[3] = bytebits_to_byte(bits + 64, 32); - PrintAndLogEx(NORMAL, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); + PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id); print_blocks(blocks, 4); UsbCommand resp; @@ -247,7 +247,7 @@ int CmdNoralsySim(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "Simulating Noralsy - CardId: %u", id); + PrintAndLogEx(SUCCESS, "Simulating Noralsy - CardId: %u", id); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bs, size); From 49ba54419002f1914fc549ed4a2df50ba9896a0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 15:33:34 +0100 Subject: [PATCH 252/320] fix: 'lf search' - indala wrong identified --- client/cmdlfindala.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index b49455e16..674931159 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -136,7 +136,7 @@ int CmdIndalaDemod(const char *Cmd) { idx = indala224decode(DemodBuffer, &size, &invert); if (idx < 0 || size != 224) { PrintAndLogEx(DEBUG, "DEBUG: Error - Indala wrong size, expected [64|224] got: %d (startindex %i)", size, idx); - return -1; + return 0; } } From 8ddf03b302e617636349f5754f23538b7f9d417b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 16:43:48 +0100 Subject: [PATCH 253/320] text --- client/cmdlfawid.c | 62 +++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index b17864dcf..61f33f636 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -101,7 +101,7 @@ static bool sendPing(void){ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose){ if ( verbose ) - PrintAndLogEx(NORMAL, "Trying FC: %u; CN: %u", fc, cn); + PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); if ( !getAWIDBits(fmtlen, fc, cn, bits)) { PrintAndLogEx(WARNING, "Error with tag bitstream generation."); @@ -171,7 +171,7 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { if (bitLen != 88) return 0; - PrintAndLogEx(NORMAL, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen)); + PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen)); return 1; } @@ -181,27 +181,27 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){ case 50: if ((*fc & 0xFFFF) != *fc) { *fc &= 0xFFFF; - PrintAndLogEx(NORMAL, "Facility-Code Truncated to 16-bits (AWID50): %u", *fc); + PrintAndLogEx(INFO, "Facility-Code Truncated to 16-bits (AWID50): %u", *fc); } break; case 37: if ((*fc & 0x1FFF) != *fc) { *fc &= 0x1FFF; - PrintAndLogEx(NORMAL, "Facility-Code Truncated to 13-bits (AWID37): %u", *fc); + PrintAndLogEx(INFO, "Facility-Code Truncated to 13-bits (AWID37): %u", *fc); } if ((*cn & 0x3FFFF) != *cn) { *cn &= 0x3FFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 18-bits (AWID37): %u", *cn); + PrintAndLogEx(INFO, "Card Number Truncated to 18-bits (AWID37): %u", *cn); } break; case 34: if ((*fc & 0xFF) != *fc) { *fc &= 0xFF; - PrintAndLogEx(NORMAL, "Facility-Code Truncated to 8-bits (AWID34): %u", *fc); + PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID34): %u", *fc); } if ((*cn & 0xFFFFFF) != *cn) { *cn &= 0xFFFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 24-bits (AWID34): %u", *cn); + PrintAndLogEx(INFO, "Card Number Truncated to 24-bits (AWID34): %u", *cn); } break; case 26: @@ -209,11 +209,11 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){ *fmtlen = 26; if ((*fc & 0xFF) != *fc) { *fc &= 0xFF; - PrintAndLogEx(NORMAL, "Facility-Code Truncated to 8-bits (AWID26): %u", *fc); + PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID26): %u", *fc); } if ((*cn & 0xFFFF) != *cn) { *cn &= 0xFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 16-bits (AWID26): %u", *cn); + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (AWID26): %u", *cn); } break; } @@ -323,21 +323,21 @@ int CmdAWIDDemod(const char *Cmd) { fc = bytebits_to_byte(bits + 9, 8); cardnum = bytebits_to_byte(bits + 17, 16); code1 = bytebits_to_byte(bits + 8,fmtLen); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); break; case 34: fc = bytebits_to_byte(bits + 9, 8); cardnum = bytebits_to_byte(bits + 17, 24); code1 = bytebits_to_byte(bits + 8, (fmtLen-32) ); code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); break; case 37: fc = bytebits_to_byte(bits + 9, 13); cardnum = bytebits_to_byte(bits + 22, 18); code1 = bytebits_to_byte(bits + 8, (fmtLen-32) ); code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); break; // case 40: // break; @@ -346,18 +346,18 @@ int CmdAWIDDemod(const char *Cmd) { cardnum = bytebits_to_byte(bits + 25, 32); code1 = bytebits_to_byte(bits + 8, (fmtLen-32) ); code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); break; default: if (fmtLen > 32 ) { cardnum = bytebits_to_byte(bits + 8 + (fmtLen-17), 16); code1 = bytebits_to_byte(bits + 8, fmtLen-32); code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); } else { cardnum = bytebits_to_byte(bits + 8 + (fmtLen-17), 16); code1 = bytebits_to_byte(bits + 8, fmtLen); - PrintAndLogEx(NORMAL, "AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + PrintAndLogEx(SUCCESS, "AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); } break; } @@ -386,8 +386,8 @@ int CmdAWIDSim(const char *Cmd) { verify_values(&fmtlen, &fc, &cn); - PrintAndLogEx(NORMAL, "Emulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn); - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation or run another command"); + PrintAndLogEx(SUCCESS, "Emulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); if (!getAWIDBits(fmtlen, fc, cn, bits)) { PrintAndLogEx(WARNING, "Error with tag bitstream generation."); @@ -417,8 +417,8 @@ int CmdAWIDClone(const char *Cmd) { uint8_t *bs=bits; memset(bs,0,sizeof(bits)); - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_awid_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_clone(); fmtlen = param_get8(Cmd, 0); fc = param_get32ex(Cmd, 1, 0, 10); @@ -426,7 +426,7 @@ int CmdAWIDClone(const char *Cmd) { if ( !fc || !cn) return usage_lf_awid_clone(); - if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') + if (tolower(param_getchar(Cmd, 3)) == 'q') //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3< Date: Sun, 24 Feb 2019 16:45:18 +0100 Subject: [PATCH 254/320] text --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c7891297..a9ebb49b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,9 @@ 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] + - Fix 'lf search' - false positive indala identification fixed (@iceman) - Add 'lf keri' - basic support for Keri tags (@iceman) - - Add 'hf mf list' - readded it again (@iceman) + - Add 'hf mf list' - re-added it again (@iceman) - Fix - A lot of bugfixes, like memory leaks (@iceman) - Change 'hf 14a antifuzz' - original implementation (@asfabw), reworked a bit - Fix 'hf mf fchk' (@iceman) From c310640b037e254a2b7d6eb53a1a1c3d376291cb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 16:47:43 +0100 Subject: [PATCH 255/320] fix: 'lf jabltron clone' - wrong number of blocks --- client/cmdlfjablotron.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 39cbc0651..541e7b31b 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -130,14 +130,14 @@ int CmdJablotronDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Jablotron Tag Found: Card ID: %"PRIx64" :: Raw: %08X%08X", id, raw1, raw2); uint8_t chksum = raw2 & 0xFF; - PrintAndLogEx(NORMAL, "Checksum: %02X [%s]", + PrintAndLogEx(INFO, "Checksum: %02X [%s]", chksum, - (chksum == jablontron_chksum(DemodBuffer)) ? "OK":"FAIL" + (chksum == jablontron_chksum(DemodBuffer)) ? _GREEN_(OK) : _RED_(FAIL) ); id = DEC2BCD(id); // Printed format: 1410-nn-nnnn-nnnn - PrintAndLogEx(NORMAL, "Printed: 1410-%02X-%04X-%04X", + PrintAndLogEx(SUCCESS, "Printed: 1410-%02X-%04X-%04X", (uint8_t)(id >> 32) & 0xFF, (uint16_t)(id >> 16) & 0xFFFF, (uint16_t)id & 0xFFFF @@ -158,8 +158,8 @@ int CmdJablotronClone(const char *Cmd) { uint8_t bits[64]; memset(bits, 0, sizeof(bits)); - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_clone(); fullcode = param_get64ex(Cmd, 0, 0, 16); @@ -170,7 +170,7 @@ int CmdJablotronClone(const char *Cmd) { // clearing the topbit needed for the preambl detection. if ((fullcode & 0x7FFFFFFFFF) != fullcode) { fullcode &= 0x7FFFFFFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 39bits: %"PRIx64, fullcode); + PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode); } if ( !getJablotronBits(fullcode, bits)) { @@ -181,13 +181,13 @@ int CmdJablotronClone(const char *Cmd) { blocks[1] = bytebits_to_byte(bits, 32); blocks[2] = bytebits_to_byte(bits + 32, 32); - PrintAndLogEx(NORMAL, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); + PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); print_blocks(blocks, 3); UsbCommand resp; UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; - for (uint8_t i=0; i<4; i++) { + for (uint8_t i=0; i<3; i++) { c.arg[0] = blocks[i]; c.arg[1] = i; clearCommandBuffer(); @@ -203,15 +203,15 @@ int CmdJablotronClone(const char *Cmd) { int CmdJablotronSim(const char *Cmd) { uint64_t fullcode = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_sim(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_sim(); fullcode = param_get64ex(Cmd, 0, 0, 16); // clearing the topbit needed for the preambl detection. if ((fullcode & 0x7FFFFFFFFF) != fullcode) { fullcode &= 0x7FFFFFFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 39bits: %"PRIx64, fullcode); + PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode); } uint8_t clk = 64, encoding = 2, separator = 0, invert = 1; @@ -220,7 +220,7 @@ int CmdJablotronSim(const char *Cmd) { arg1 = clk << 8 | encoding; arg2 = invert << 8 | separator; - PrintAndLogEx(NORMAL, "Simulating Jablotron - FullCode: %"PRIx64, fullcode); + PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: %"PRIx64, fullcode); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; getJablotronBits(fullcode, c.d.asBytes); From e0579223f0006547e80d80b3c34aaea2d4cd0234 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 16:48:54 +0100 Subject: [PATCH 256/320] text --- client/cmdlfpyramid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 8e7dbd57f..1153fccc3 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -285,7 +285,7 @@ int CmdPyramidClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bs + 64, 32); blocks[4] = bytebits_to_byte(bs + 96, 32); - PrintAndLogEx(NORMAL, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); + PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, 5); UsbCommand resp; @@ -331,7 +331,7 @@ int CmdPyramidSim(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "Simulating Farpointe/Pyramid - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber ); + PrintAndLogEx(SUCCESS, "Simulating Farpointe/Pyramid - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber ); UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bs, size); From f750ddb2c861a7e52bc499f4c948e9d1547ce76a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:06:46 +0100 Subject: [PATCH 257/320] text --- client/cmdlfindala.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 674931159..3148958ce 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -231,8 +231,8 @@ int CmdIndalaDemodAlt(const char *Cmd) { } if (rawbit > 0){ - PrintAndLogEx(NORMAL, "Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLogEx(NORMAL, "worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + PrintAndLogEx(INFO, "Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLogEx(INFO, "worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); } else { return 0; } @@ -262,7 +262,7 @@ int CmdIndalaDemodAlt(const char *Cmd) { } if (start == rawbit - uidlen + 1) { - PrintAndLogEx(NORMAL, "nothing to wait for"); + PrintAndLogEx(FAILED, "nothing to wait for"); return 0; } @@ -288,7 +288,7 @@ int CmdIndalaDemodAlt(const char *Cmd) { showbits[bit] = '.' + bits[bit]; } showbits[bit+1]='\0'; - PrintAndLogEx(NORMAL, "Partial UID=%s", showbits); + PrintAndLogEx(SUCCESS, "Partial UID | %s", showbits); return 0; } else { for (bit = 0; bit < uidlen; bit++) { @@ -313,7 +313,7 @@ int CmdIndalaDemodAlt(const char *Cmd) { uid2 = (uid2<<1) | 1; } } - PrintAndLogEx(NORMAL, "UID=%s (%x%08x)", showbits, uid1, uid2); + PrintAndLogEx(SUCCESS, "UID | %s (%x%08x)", showbits, uid1, uid2); } else { uid3 = uid4 = uid5 = uid6 = uid7 = 0; @@ -331,7 +331,7 @@ int CmdIndalaDemodAlt(const char *Cmd) { else uid7 = (uid7<<1) | 1; } - PrintAndLogEx(NORMAL, "UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + PrintAndLogEx(SUCCESS, "UID | %s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); } // Checking UID against next occurrences @@ -350,7 +350,7 @@ int CmdIndalaDemodAlt(const char *Cmd) { times += 1; } - PrintAndLogEx(NORMAL, "Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + PrintAndLogEx(DEBUG, "Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); // Remodulating for tag cloning // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) @@ -409,8 +409,8 @@ int CmdIndalaSim(const char *Cmd) { // It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not. // lf simpsk 1 c 32 r 2 d 0102030405060708 -// PrintAndLogEx(NORMAL, "Emulating Indala UID: %u \n", cn); -// PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation or run another command"); + PrintAndLogEx(SUCCESS, "Simulating Indala UID: %u \n", cn); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bits, size); @@ -427,6 +427,7 @@ int CmdIndalaClone(const char *Cmd) { uint32_t n = 0, i = 0; if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { uid1 = (uid1 << 4) | (uid2 >> 28); uid2 = (uid2 << 4) | (uid3 >> 28); @@ -436,7 +437,8 @@ int CmdIndalaClone(const char *Cmd) { uid6 = (uid6 << 4) | (uid7 >> 28); uid7 = (uid7 << 4) | (n & 0xf); } - PrintAndLogEx(NORMAL, "Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + + PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); c.cmd = CMD_INDALA_CLONE_TAG_L; c.d.asDwords[0] = uid1; c.d.asDwords[1] = uid2; @@ -450,7 +452,7 @@ int CmdIndalaClone(const char *Cmd) { uid1 = (uid1 << 4) | (uid2 >> 28); uid2 = (uid2 << 4) | (n & 0xf); } - PrintAndLogEx(NORMAL, "Cloning 64bit tag with UID %x%08x", uid1, uid2); + PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with UID %x%08x", uid1, uid2); c.cmd = CMD_INDALA_CLONE_TAG; c.arg[0] = uid1; c.arg[1] = uid2; From 8b33d45016598fb7bb7ed803d268c7d615c3c6ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:08:58 +0100 Subject: [PATCH 258/320] fix --- client/cmdlfindala.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 3148958ce..1707895b0 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -409,7 +409,7 @@ int CmdIndalaSim(const char *Cmd) { // It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not. // lf simpsk 1 c 32 r 2 d 0102030405060708 - PrintAndLogEx(SUCCESS, "Simulating Indala UID: %u \n", cn); + PrintAndLogEx(SUCCESS, "Simulating Indala UID: %s", sprint_hex(hexuid, len)); PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; From 7de440a8a0203d052878882409066e9df8e7db89 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:10:30 +0100 Subject: [PATCH 259/320] text --- client/cmdlfpresco.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 9c8037457..98df02fe5 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -12,11 +12,11 @@ static int CmdHelp(const char *Cmd); int usage_lf_presco_clone(void){ PrintAndLogEx(NORMAL, "clone a Presco tag to a T55x7 tag."); - PrintAndLogEx(NORMAL, "Usage: lf presco clone [h] d H "); + PrintAndLogEx(NORMAL, "Usage: lf presco clone [h] d c "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " d : 9 digit presco card ID"); - PrintAndLogEx(NORMAL, " H : 8 digit hex card number"); + PrintAndLogEx(NORMAL, " c : 8 digit hex card number"); PrintAndLogEx(NORMAL, " : specify write to Q5 (t5555 instead of t55x7)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -29,11 +29,11 @@ int usage_lf_presco_sim(void) { PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Per presco format, the card number is 9 digit number and can contain *# chars. Larger values are truncated."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf presco sim [h] d or H "); + PrintAndLogEx(NORMAL, "Usage: lf presco sim [h] d or c "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " d : 9 digit presco card number"); - PrintAndLogEx(NORMAL, " H : 8 digit hex card number"); + PrintAndLogEx(NORMAL, " c : 8 digit hex card number"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf presco sim d 123456789"); @@ -62,24 +62,22 @@ int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode int stringlen = 0; memset(id, 0x00, sizeof(id)); - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return -1; - case 'H': + case 'c': hex = true; //get hex *fullcode = param_get32ex(Cmd, cmdp+1, 0, 16); cmdp+=2; break; - case 'D': case 'd': //param get string int param_getstr(const char *line, int paramnum, char * str) stringlen = param_getstr(Cmd, cmdp+1, id, sizeof(id)); if (stringlen < 2) return -1; cmdp += 2; break; - case 'Q': case 'q': *Q5 = true; cmdp++; @@ -136,7 +134,6 @@ int CmdPrescoDemod(const char *Cmd) { size_t size = DemodBufferLen; int ans = detectPresco(DemodBuffer, &size); if (ans < 0) { - if (ans == -1) PrintAndLogEx(DEBUG, "DEBUG: Error - Presco: too few bits found"); else if (ans == -2) @@ -163,7 +160,7 @@ int CmdPrescoDemod(const char *Cmd) { char cmd[12] = {0}; sprintf(cmd, "H %08X", cardid); GetWiegandFromPresco(cmd, &sitecode, &usercode, &fullcode, &Q5); - PrintAndLogEx(NORMAL, "SiteCode %u, UserCode %u, FullCode, %08X", sitecode, usercode, fullcode); + PrintAndLogEx(SUCCESS, "SiteCode %u, UserCode %u, FullCode, %08X", sitecode, usercode, fullcode); return 1; } @@ -190,12 +187,12 @@ int CmdPrescoClone(const char *Cmd) { if ((sitecode & 0xFF) != sitecode) { sitecode &= 0xFF; - PrintAndLogEx(NORMAL, "Facility-Code Truncated to 8-bits (Presco): %u", sitecode); + PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (Presco): %u", sitecode); } if ((usercode & 0xFFFF) != usercode) { usercode &= 0xFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 16-bits (Presco): %u", usercode); + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (Presco): %u", usercode); } blocks[1] = 0x10D00000; //preamble @@ -203,7 +200,7 @@ int CmdPrescoClone(const char *Cmd) { blocks[3] = 0x00000000; blocks[4] = fullcode; - PrintAndLogEx(NORMAL, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode); + PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode); print_blocks(blocks, 5); UsbCommand resp; @@ -236,7 +233,7 @@ int CmdPrescoSim(const char *Cmd) { arg1 = clk << 8 | encoding; arg2 = invert << 8 | separator; - PrintAndLogEx(NORMAL, "Simulating Presco - SiteCode: %u, UserCode: %u, FullCode: %08X",sitecode, usercode, fullcode); + PrintAndLogEx(SUCCESS, "Simulating Presco - SiteCode: %u, UserCode: %u, FullCode: %08X",sitecode, usercode, fullcode); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; GetPrescoBits(fullcode, c.d.asBytes); From b22189b4159b9715f292a5accea761b2d3800fdc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:11:59 +0100 Subject: [PATCH 260/320] text --- client/cmdlfnedap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 19e83d3cc..25f9b624b 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -194,15 +194,15 @@ int CmdLFNedapDemod(const char *Cmd) { chksum2 = bytebits_to_byte(DemodBuffer+110, 8); chksum2 |= bytebits_to_byte(DemodBuffer+119, 8) << 8; - PrintAndLogEx(NORMAL, "NEDAP ID Found - Raw: %08x%08x%08x%08x", raw[3], raw[2], raw[1], raw[0]); - PrintAndLogEx(NORMAL, " - UID: %06X", uid); - PrintAndLogEx(NORMAL, " - i: %04X", two); - PrintAndLogEx(NORMAL, " - Checksum2 %04X", chksum2); + PrintAndLogEx(SUCCESS, "NEDAP ID Found - Raw: %08x%08x%08x%08x", raw[3], raw[2], raw[1], raw[0]); + PrintAndLogEx(SUCCESS, " - UID: %06X", uid); + PrintAndLogEx(SUCCESS, " - i: %04X", two); + PrintAndLogEx(SUCCESS, " - Checksum2 %04X", chksum2); if (g_debugMode){ PrintAndLogEx(DEBUG, "DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); printDemodBuff(); - PrintAndLogEx(NORMAL, "BIN:\n%s", sprint_bin_break( DemodBuffer, 128, 64) ); + PrintAndLogEx(DEBUG, "BIN:\n%s", sprint_bin_break( DemodBuffer, 128, 64) ); } return 1; @@ -268,7 +268,7 @@ int CmdLFNedapClone(const char *Cmd) { blocks[3] = bytebits_to_byte(bits + 64, 32); blocks[4] = bytebits_to_byte(bits + 96, 32); - PrintAndLogEx(NORMAL, "Preparing to clone NEDAP to T55x7 with card number: %u", cardnumber); + PrintAndLogEx(INFO, "Preparing to clone NEDAP to T55x7 with card number: %u", cardnumber); print_blocks(blocks, 5); UsbCommand resp; @@ -314,8 +314,8 @@ int CmdLFNedapSim(const char *Cmd) { return 1; } - PrintAndLogEx(NORMAL, "bin %s", sprint_bin_break(bs, 128, 32)); - PrintAndLogEx(NORMAL, "Simulating Nedap - CardNumber: %u", cardnumber ); + PrintAndLogEx(SUCCESS, "bin %s", sprint_bin_break(bs, 128, 32)); + PrintAndLogEx(SUCCESS, "Simulating Nedap - CardNumber: %u", cardnumber ); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; memcpy(c.d.asBytes, bs, size); @@ -332,7 +332,7 @@ int CmdLFNedapChk(const char *Cmd){ len = ( len == 0 ) ? 5 : len>>1; - PrintAndLogEx(NORMAL, "Input: [%d] %s", len, sprint_hex(data, len)); + PrintAndLogEx(SUCCESS, "Input: [%d] %s", len, sprint_hex(data, len)); //uint8_t last = GetParity(data, EVEN, 62); //PrintAndLogEx(NORMAL, "TEST PARITY:: %d | %d ", DemodBuffer[62], last); @@ -367,7 +367,7 @@ int CmdLFNedapChk(const char *Cmd){ } } - PrintAndLogEx(NORMAL, "Nedap checksum: 0x%X", ((ch << 8) | cl) ); + PrintAndLogEx(SUCCESS, "Nedap checksum: 0x%X", ((ch << 8) | cl) ); return 0; } From 63659fd352c063e816e36a918040cc7193e2d32c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:22:03 +0100 Subject: [PATCH 261/320] text --- client/cmdlfguard.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 593dcf2b8..5707c78fb 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -107,21 +107,21 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { for (i = 0; i < 4; ++i) rawbytes[i+4] = bytebits_to_byte( pre + (i*8), 8); - if (g_debugMode) PrintAndLogEx(NORMAL, " WIE | %s\n", sprint_hex(rawbytes, sizeof(rawbytes))); + PrintAndLogEx(DEBUG, " WIE | %s\n", sprint_hex(rawbytes, sizeof(rawbytes))); // XOR (only works on wiegand stuff) for (i = 1; i < 12; ++i) rawbytes[i] ^= xorKey ; - if (g_debugMode) PrintAndLogEx(NORMAL, " XOR | %s \n", sprint_hex(rawbytes, sizeof(rawbytes))); + PrintAndLogEx(DEBUG, " XOR | %s \n", sprint_hex(rawbytes, sizeof(rawbytes))); // convert rawbytes to bits in pre for (i = 0; i < 12; ++i) num_to_bytebitsLSBF( rawbytes[i], 8, pre + (i*8)); - if (g_debugMode) PrintAndLogEx(NORMAL, "\n Raw | %s \n", sprint_hex(rawbytes, sizeof(rawbytes))); - if (g_debugMode) PrintAndLogEx(NORMAL, " Raw | %s\n", sprint_bin(pre, 64) ); + PrintAndLogEx(DEBUG, "\n Raw | %s \n", sprint_hex(rawbytes, sizeof(rawbytes))); + PrintAndLogEx(DEBUG, " Raw | %s\n", sprint_bin(pre, 64) ); // add spacer bit 0 every 4 bits, starting with index 0, // 12 bytes, 24 nibbles. 24+1 extra bites. 3bytes. ie 9bytes | 1byte xorkey, 8bytes rawdata (64bits, should be enough for a 40bit wiegand) @@ -135,7 +135,7 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { guardBits[4] = 1; guardBits[5] = 0; - if (g_debugMode) PrintAndLogEx(NORMAL, " FIN | %s\n", sprint_bin(guardBits, 96) ); + PrintAndLogEx(DEBUG, " FIN | %s\n", sprint_bin(guardBits, 96) ); return 1; } From 528ffd9e66f829a55a28170b6f64cd406c1bda8d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:23:33 +0100 Subject: [PATCH 262/320] text --- client/cmdlfawid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 61f33f636..3cc56f56c 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -290,7 +290,7 @@ int CmdAWIDDemod(const char *Cmd) { uint32_t rawHi2 = bytebits_to_byte(bits + idx, 32); size = removeParity(bits, idx+8, 4, 1, 88); - if (size != 66){ + if (size != 66) { PrintAndLogEx(DEBUG, "DEBUG: Error - AWID at parity check-tag size does not match AWID format"); return 0; } @@ -386,7 +386,7 @@ int CmdAWIDSim(const char *Cmd) { verify_values(&fmtlen, &fc, &cn); - PrintAndLogEx(SUCCESS, "Emulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn); + PrintAndLogEx(SUCCESS, "Simulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn); PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); if (!getAWIDBits(fmtlen, fc, cn, bits)) { From 4b0f13a2e43bf62c22c500aa8518e2a16a4bb3a7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:25:40 +0100 Subject: [PATCH 263/320] text --- client/cmdlfio.c | 50 +++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/client/cmdlfio.c b/client/cmdlfio.c index d2cecec4b..61fe9d00d 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -86,15 +86,15 @@ int CmdIOProxDemod(const char *Cmd) { uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; size_t size = getFromGraphBuf(bits); if (size < 65) { - if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox not enough samples in GraphBuffer"); + PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox not enough samples in GraphBuffer"); return 0; } //get binary from fsk wave int waveIdx = 0; idx = detectIOProx(bits, &size, &waveIdx); - if (idx < 0){ - if (g_debugMode){ - if (idx == -1){ + if (idx < 0) { + if (g_debugMode) { + if (idx == -1) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox not enough samples"); } else if (idx == -2) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox just noise detected"); @@ -115,10 +115,10 @@ int CmdIOProxDemod(const char *Cmd) { setDemodBuf(bits, size, idx); setClockGrid(64, waveIdx + (idx*64)); - if (idx==0){ - if (g_debugMode){ + if (idx == 0) { + if (g_debugMode) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox data not found - FSK Bits: %d", size); - if (size > 92) PrintAndLogEx(NORMAL, "%s", sprint_bin_break(bits, 92, 16)); + if (size > 92) PrintAndLogEx(DEBUG, "%s", sprint_bin_break(bits, 92, 16)); } return retval; } @@ -132,15 +132,13 @@ int CmdIOProxDemod(const char *Cmd) { // //XSF(version)facility:codeone+codetwo (raw) - if (g_debugMode) { - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d", bits[idx], bits[idx+1], bits[idx+2], bits[idx+3], bits[idx+4], bits[idx+5], bits[idx+6], bits[idx+7], bits[idx+8]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d", bits[idx+9], bits[idx+10], bits[idx+11],bits[idx+12],bits[idx+13],bits[idx+14],bits[idx+15],bits[idx+16],bits[idx+17]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d facility", bits[idx+18], bits[idx+19], bits[idx+20],bits[idx+21],bits[idx+22],bits[idx+23],bits[idx+24],bits[idx+25],bits[idx+26]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d version", bits[idx+27], bits[idx+28], bits[idx+29],bits[idx+30],bits[idx+31],bits[idx+32],bits[idx+33],bits[idx+34],bits[idx+35]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d code1", bits[idx+36], bits[idx+37], bits[idx+38],bits[idx+39],bits[idx+40],bits[idx+41],bits[idx+42],bits[idx+43],bits[idx+44]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d code2", bits[idx+45], bits[idx+46], bits[idx+47],bits[idx+48],bits[idx+49],bits[idx+50],bits[idx+51],bits[idx+52],bits[idx+53]); - PrintAndLogEx(NORMAL, "%d%d%d%d%d%d%d%d %d%d checksum", bits[idx+54],bits[idx+55],bits[idx+56],bits[idx+57],bits[idx+58],bits[idx+59],bits[idx+60],bits[idx+61],bits[idx+62],bits[idx+63]); - } + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d", bits[idx], bits[idx+1], bits[idx+2], bits[idx+3], bits[idx+4], bits[idx+5], bits[idx+6], bits[idx+7], bits[idx+8]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d", bits[idx+9], bits[idx+10], bits[idx+11],bits[idx+12],bits[idx+13],bits[idx+14],bits[idx+15],bits[idx+16],bits[idx+17]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d facility", bits[idx+18], bits[idx+19], bits[idx+20],bits[idx+21],bits[idx+22],bits[idx+23],bits[idx+24],bits[idx+25],bits[idx+26]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d version", bits[idx+27], bits[idx+28], bits[idx+29],bits[idx+30],bits[idx+31],bits[idx+32],bits[idx+33],bits[idx+34],bits[idx+35]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d code1", bits[idx+36], bits[idx+37], bits[idx+38],bits[idx+39],bits[idx+40],bits[idx+41],bits[idx+42],bits[idx+43],bits[idx+44]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d code2", bits[idx+45], bits[idx+46], bits[idx+47],bits[idx+48],bits[idx+49],bits[idx+50],bits[idx+51],bits[idx+52],bits[idx+53]); + PrintAndLogEx(DEBUG, "%d%d%d%d%d%d%d%d %d%d checksum", bits[idx+54],bits[idx+55],bits[idx+56],bits[idx+57],bits[idx+58],bits[idx+59],bits[idx+60],bits[idx+61],bits[idx+62],bits[idx+63]); uint32_t code = bytebits_to_byte(bits+idx,32); uint32_t code2 = bytebits_to_byte(bits+idx+32,32); @@ -163,13 +161,13 @@ int CmdIOProxDemod(const char *Cmd) { snprintf(crcStr, 3, "ok"); retval = 1; } else { - if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox crc failed"); + PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox crc failed"); snprintf(crcStr, sizeof(crcStr), "failed 0x%02X != 0x%02X", crc, calccrc); retval = 0; } - PrintAndLogEx(NORMAL, "IO Prox XSF(%02d)%02x:%05d (%08x%08x) [crc %s]", version, facilitycode, number, code, code2, crcStr); + PrintAndLogEx(SUCCESS, "IO Prox XSF(%02d)%02x:%05d (%08x%08x) [crc %s]", version, facilitycode, number, code, code2, crcStr); if (g_debugMode){ PrintAndLogEx(DEBUG, "DEBUG: IO prox idx: %d, Len: %d, Printing demod buffer:", idx, size); @@ -241,7 +239,7 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) { memcpy(bits, pre, sizeof(pre)); - PrintAndLogEx(NORMAL, "IO raw bits:\n %s \n", sprint_bin(bits, 64)); + PrintAndLogEx(SUCCESS, "IO raw bits:\n %s \n", sprint_bin(bits, 64)); return 1; } @@ -252,8 +250,8 @@ int CmdIOProxSim(const char *Cmd) { size_t size = sizeof(bits); memset(bits, 0x00, size); - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_sim(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim(); version = param_get8(Cmd, 0); fc = param_get8(Cmd, 1); @@ -263,7 +261,7 @@ int CmdIOProxSim(const char *Cmd) { if ((cn & 0xFFFF) != cn) { cn &= 0xFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 16-bits (IOProx): %u", cn); + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); } // clock 64, FSK2a fcHIGH 10 | fcLOW 8 @@ -272,8 +270,8 @@ int CmdIOProxSim(const char *Cmd) { arg1 = high << 8 | low; arg2 = invert << 8 | clk; - PrintAndLogEx(NORMAL, "Emulating IOProx Version: %u FC: %u; CN: %u\n", version, fc, cn); - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation or run another command"); + PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); if ( !getIOProxBits(version, fc, cn, bits)) { PrintAndLogEx(WARNING, "Error with tag bitstream generation."); @@ -309,7 +307,7 @@ int CmdIOProxClone(const char *Cmd) { if ((cn & 0xFFFF) != cn) { cn &= 0xFFFF; - PrintAndLogEx(NORMAL, "Card Number Truncated to 16-bits (IOProx): %u", cn); + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); } if ( !getIOProxBits(version, fc, cn, bits)) { @@ -323,7 +321,7 @@ int CmdIOProxClone(const char *Cmd) { blocks[1] = bytebits_to_byte(bits, 32); blocks[2] = bytebits_to_byte(bits + 32, 32); - PrintAndLogEx(NORMAL, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); + PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); print_blocks(blocks, 3); //UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; From 92631bdfb407cbefba23cfe76fbf3a21294a3e66 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:25:47 +0100 Subject: [PATCH 264/320] text --- client/cmdlfem4x.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 97e0668cc..6d90e550f 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -443,14 +443,14 @@ int CmdEM410xSim(const char *Cmd) { uint8_t clock = 64; if (param_gethex(Cmd, 0, uid, 10)) { - PrintAndLogEx(NORMAL, "UID must include 10 HEX symbols"); + PrintAndLogEx(FAILED, "UID must include 10 HEX symbols"); return 0; } param_getdec(Cmd, 1, &clock); - PrintAndLogEx(NORMAL, "Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock); - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation"); + PrintAndLogEx(SUCCESS, "Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation"); ConstructEM410xEmulGraph(Cmd, clock); @@ -508,7 +508,7 @@ int CmdEM410xBrute(const char *Cmd) { if( buf[0]=='#' ) continue; if (param_gethex(buf, 0, uid, 10)) { - PrintAndLogEx(NORMAL, "UIDs must include 10 HEX symbols"); + PrintAndLogEx(FAILED, "UIDs must include 10 HEX symbols"); free(uidBlock); fclose(f); return 1; @@ -535,11 +535,12 @@ int CmdEM410xBrute(const char *Cmd) { fclose(f); if (uidcnt == 0) { - PrintAndLogEx(NORMAL, "No UIDs found in file"); + PrintAndLogEx(FAILED, "No UIDs found in file"); free(uidBlock); return 1; } - PrintAndLogEx(NORMAL, "Loaded %d UIDs from %s, pause delay: %d ms", uidcnt, filename, delay); + + PrintAndLogEx(SUCCESS, "Loaded %d UIDs from %s, pause delay: %d ms", uidcnt, filename, delay); // loop for(uint32_t c = 0; c < uidcnt; ++c ) { @@ -599,7 +600,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd) { // loops if the captured ID was in XL-format. CmdEM410xWatch(Cmd); - PrintAndLogEx(NORMAL, "# Replaying captured ID: %010" PRIx64 , g_em410xid); + PrintAndLogEx(SUCCESS, "# Replaying captured ID: %010" PRIx64 , g_em410xid); CmdLFaskSim(""); return 0; } @@ -645,17 +646,17 @@ int CmdEM410xWrite(const char *Cmd) { } if (card == 1) { - PrintAndLogEx(NORMAL, "Writing %s tag with UID 0x%010" PRIx64 " (clock rate: %d)", "T55x7", id, clock); + PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64 " (clock rate: %d)", "T55x7", id, clock); // NOTE: We really should pass the clock in as a separate argument, but to // provide for backwards-compatibility for older firmware, and to avoid // having to add another argument to CMD_EM410X_WRITE_TAG, we just store // the clock rate in bits 8-15 of the card value card = (card & 0xFF) | ((clock << 8) & 0xFF00); } else if (card == 0) { - PrintAndLogEx(NORMAL, "Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock); + PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock); card = (card & 0xFF) | ((clock << 8) & 0xFF00); } else { - PrintAndLogEx(WARNING, "Error! Bad card type selected.\n"); + PrintAndLogEx(FAILED, "Error! Bad card type selected.\n"); return 0; } From e2d253f641c3607a7a11bbc5e24797230c9551ba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:25:55 +0100 Subject: [PATCH 265/320] text --- client/cmdlffdx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 8b67358ca..194bb7f32 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -82,11 +82,11 @@ int detectFDXB(uint8_t *dest, size_t *size) { static void verify_values(uint32_t countryid, uint64_t animalid){ if ((animalid & 0x3FFFFFFFFF) != animalid) { animalid &= 0x3FFFFFFFFF; - PrintAndLogEx(NORMAL, "Animal ID Truncated to 38bits: %"PRIx64, animalid); + PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, animalid); } if ( (countryid & 0x3ff) != countryid ) { countryid &= 0x3ff; - PrintAndLogEx(NORMAL, "Country ID Truncated to 10bits: %03d", countryid); + PrintAndLogEx(INFO, "Country ID Truncated to 10bits: %03d", countryid); } } From 95f8a48b560dc3feea9cff08ee05501e1e0b24a0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:28:54 +0100 Subject: [PATCH 266/320] text --- client/cmdlfhid.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 7bc3bb9e9..7d1bda95c 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -106,7 +106,7 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui // this should be optional. if ( verbose ) - PrintAndLogEx(NORMAL, "Trying FC: %u; CN: %u", fc, cn); + PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); calcWiegand( fmtlen, fc, cn, bits); @@ -164,7 +164,7 @@ int CmdHIDDemod(const char *Cmd) { } if (hi2 != 0){ //extra large HID tags - PrintAndLogEx(NORMAL, "HID Prox TAG ID: %x%08x%08x (%u)", hi2, hi, lo, (lo>>1) & 0xFFFF); + PrintAndLogEx(SUCCESS, "HID Prox TAG ID: %x%08x%08x (%u)", hi2, hi, lo, (lo>>1) & 0xFFFF); } else { //standard HID tags <38 bits uint8_t fmtLen = 0; uint32_t cc = 0; @@ -209,9 +209,9 @@ int CmdHIDDemod(const char *Cmd) { } } if(fmtLen==32 && (lo & 0x40000000)){//if 32 bit and Kastle bit set - PrintAndLogEx(NORMAL, "HID Prox TAG (Kastle format) ID: %08x (%u) - Format Len: 32bit - CC: %u - FC: %u - Card: %u", lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); + PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: %08x (%u) - Format Len: 32bit - CC: %u - FC: %u - Card: %u", lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum); }else{ - PrintAndLogEx(NORMAL, "HID Prox TAG ID: %x%08x (%u) - Format Len: %ubit - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, fmtLen, fc, cardnum); + PrintAndLogEx(SUCCESS, "HID Prox TAG ID: %x%08x (%u) - Format Len: %ubit - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, fmtLen, fc, cardnum); } } @@ -244,16 +244,16 @@ int CmdHIDSim(const char *Cmd) { uint32_t hi = 0, lo = 0; uint32_t n = 0, i = 0; - uint8_t ctmp = param_getchar(Cmd, 0); - if ( strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h' ) return usage_lf_hid_sim(); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if ( strlen(Cmd) == 0 || ctmp == 'h' ) return usage_lf_hid_sim(); while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { hi = (hi << 4) | (lo >> 28); lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(NORMAL, "Emulating tag with ID %x%08x", hi, lo); - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation"); + PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation"); UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}}; clearCommandBuffer(); @@ -277,7 +277,7 @@ int CmdHIDClone(const char *Cmd) { lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(NORMAL, "Cloning tag with long ID %x%08x%08x", hi2, hi, lo); + PrintAndLogEx(INFO, "Preparing to clone HID tag with long ID %x%08x%08x", hi2, hi, lo); c.d.asBytes[0] = 1; } else { @@ -285,7 +285,7 @@ int CmdHIDClone(const char *Cmd) { hi = (hi << 4) | (lo >> 28); lo = (lo << 4) | (n & 0xf); } - PrintAndLogEx(NORMAL, "Cloning tag with ID %x%08x", hi, lo); + PrintAndLogEx(INFO, "Preparing to clone HID tag with ID %x%08x", hi, lo); hi2 = 0; c.d.asBytes[0] = 0; } @@ -492,33 +492,28 @@ int CmdHIDBrute(const char *Cmd){ memset(bits, 0, sizeof(bits)); uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': - case 'H': return usage_lf_hid_brute(); case 'f': - case 'F': fc = param_get32ex(Cmd ,cmdp+1, 0, 10); if ( !fc ) errors = true; cmdp += 2; break; case 'd': - case 'D': // delay between attemps, defaults to 1000ms. delay = param_get32ex(Cmd, cmdp+1, 1000, 10); cmdp += 2; break; case 'c': - case 'C': cn = param_get32ex(Cmd, cmdp+1, 0, 10); // truncate cardnumber. cn &= 0xFFFF; cmdp += 2; break; case 'a': - case 'A': fmtlen = param_get8(Cmd, cmdp+1); cmdp += 2; bool is_ftm_ok = false; @@ -532,7 +527,6 @@ int CmdHIDBrute(const char *Cmd){ errors = !is_ftm_ok; break; case 'v': - case 'V': verbose = true; cmdp++; break; @@ -545,8 +539,8 @@ int CmdHIDBrute(const char *Cmd){ if ( fc == 0 ) errors = true; if ( errors ) return usage_lf_hid_brute(); - PrintAndLogEx(NORMAL, "Brute-forcing HID reader"); - PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation or run another command"); + PrintAndLogEx(INFO, "Brute-forcing HID reader"); + PrintAndLogEx(INFO, "Press pm3-button to abort simulation or run another command"); uint16_t up = cn; uint16_t down = cn; From 4b7f6089ae442c92a45cc600b19fa9ac7e7d74ed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:30:05 +0100 Subject: [PATCH 267/320] text --- client/cmdlfsecurakey.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 793c30fce..64e491d7f 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -97,12 +97,12 @@ int CmdSecurakeyDemod(const char *Cmd) { // test parities - evenparity32 looks to add an even parity returns 0 if already even... bool parity = !evenparity32(lWiegand) && !oddparity32(rWiegand); - PrintAndLogEx(NORMAL, "Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1 ,raw2, raw3); + PrintAndLogEx(SUCCESS, "Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1 ,raw2, raw3); if (bitLen <= 32) - PrintAndLogEx(NORMAL, "Wiegand: %08X, Parity: %s", (lWiegand<<(bitLen/2)) | rWiegand, parity ? "Passed" : "Failed"); - PrintAndLogEx(NORMAL, "\nHow the FC translates to printed FC is unknown"); - PrintAndLogEx(NORMAL, "How the checksum is calculated is unknown"); - PrintAndLogEx(NORMAL, "Help the community identify this format further\n by sharing your tag on the pm3 forum or with forum members"); + PrintAndLogEx(SUCCESS, "Wiegand: %08X, Parity: %s", (lWiegand<<(bitLen/2)) | rWiegand, parity ? "Passed" : "Failed"); + PrintAndLogEx(INFO, "\nHow the FC translates to printed FC is unknown"); + PrintAndLogEx(INFO, "How the checksum is calculated is unknown"); + PrintAndLogEx(INFO, "Help the community identify this format further\n by sharing your tag on the pm3 forum or with forum members"); return 1; } From a47085a7b4461ff15119596474c69cce48eb5ae1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:30:55 +0100 Subject: [PATCH 268/320] text --- client/cmdlfviking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 5ead8ef03..33a5588d3 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -118,7 +118,7 @@ int CmdVikingClone(const char *Cmd) { rawID = getVikingBits(id); - PrintAndLogEx(INFO, "Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); + PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); UsbCommand c = {CMD_VIKING_CLONE_TAG, {rawID >> 32, rawID & 0xFFFFFFFF, Q5}}; clearCommandBuffer(); From 7b9a5eb7e34ae992052f00e1f2a674d930cb833f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 17:32:01 +0100 Subject: [PATCH 269/320] text --- client/cmdlfvisa2000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 2736934af..02cd5392e 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -165,8 +165,8 @@ int CmdVisa2kClone(const char *Cmd) { uint64_t id = 0; uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_64 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, BL0CK1, 0}; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_visa2k_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_visa2k_clone(); id = param_get32ex(Cmd, 0, 0, 10); @@ -210,7 +210,7 @@ int CmdVisa2kSim(const char *Cmd) { arg1 = clk << 8 | encoding; arg2 = invert << 8 | separator; - PrintAndLogEx(NORMAL, "Simulating Visa2000 - CardId: %u", id); + PrintAndLogEx(SUCCESS, "Simulating Visa2000 - CardId: %u", id); UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; From 6b1ae818a50c96be8109cade083dddcd001eb006 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 18:27:56 +0100 Subject: [PATCH 270/320] fix: bad break.. --- client/mifarehost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mifarehost.c b/client/mifarehost.c index 31ed8e39d..60f3eaa01 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -956,8 +956,8 @@ int detect_classic_nackbug(bool verbose){ if (verbose) { PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial"); PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again."); - return 0; - } +x } + return 2; } case 2 : PrintAndLogEx(SUCCESS, "always leak NACK detected"); return 3; case 1 : PrintAndLogEx(SUCCESS, "NACK bug detected"); return 1; From 8e01c9899f4a12194c99e831cecc31f9c41654a4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 18:31:59 +0100 Subject: [PATCH 271/320] aaaaaa --- client/mifarehost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mifarehost.c b/client/mifarehost.c index 60f3eaa01..927fb7bc0 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -956,7 +956,7 @@ int detect_classic_nackbug(bool verbose){ if (verbose) { PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial"); PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again."); -x } + } return 2; } case 2 : PrintAndLogEx(SUCCESS, "always leak NACK detected"); return 3; From 8512c0ea093976e13b62fe27cb4965c51a3fa8fc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:25:44 +0100 Subject: [PATCH 272/320] fix: mem leak --- uart/uart_posix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/uart/uart_posix.c b/uart/uart_posix.c index e3d7753a9..c3ff7dcca 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -83,6 +83,7 @@ serial_port uart_open(const char* pcPortName) { if (addrstr == NULL) { printf("Error: strdup\n"); + free(sp); return INVALID_SERIAL_PORT; } From 01cf818e48296012f408f9c2f076a2a37c049344 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:32:14 +0100 Subject: [PATCH 273/320] remove a warning --- client/jansson/error.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/client/jansson/error.c b/client/jansson/error.c index b94b3a3a1..96b3b3fac 100644 --- a/client/jansson/error.c +++ b/client/jansson/error.c @@ -3,8 +3,7 @@ void jsonp_error_init(json_error_t *error, const char *source) { - if(error) - { + if (error) { error->text[0] = '\0'; error->line = -1; error->column = -1; @@ -20,13 +19,13 @@ void jsonp_error_set_source(json_error_t *error, const char *source) { size_t length; - if(!error || !source) + if (!error || !source) return; length = strlen(source); - if(length < JSON_ERROR_SOURCE_LENGTH) - strncpy(error->source, source, JSON_ERROR_SOURCE_LENGTH); - else { + if (length < JSON_ERROR_SOURCE_LENGTH) { + strncpy(error->source, source, length); + } else { size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; memcpy(error->source, "...", 3); strncpy(error->source + 3, source + extra, length - extra + 1); @@ -38,7 +37,6 @@ void jsonp_error_set(json_error_t *error, int line, int column, const char *msg, ...) { va_list ap; - va_start(ap, msg); jsonp_error_vset(error, line, column, position, code, msg, ap); va_end(ap); @@ -48,10 +46,10 @@ void jsonp_error_vset(json_error_t *error, int line, int column, size_t position, enum json_error_code code, const char *msg, va_list ap) { - if(!error) + if (!error) return; - if(error->text[0] != '\0') { + if (error->text[0] != '\0') { /* error already set */ return; } From f58c47a7b83989655222ec70069fe5a0039807d2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:38:16 +0100 Subject: [PATCH 274/320] cleanup --- client/cmdhfmf.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 76f0fc2b6..f04105c01 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2239,11 +2239,7 @@ int CmdHF14AMfSniff(const char *Cmd){ bufsize = traceLen; memset(buf, 0x00, traceLen); } - if (bufPtr == NULL) { - PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); - free(buf); - return 2; - } + // what happens if LEN is bigger then TRACELEN --iceman memcpy(bufPtr, resp.d.asBytes, len); bufPtr += len; From aaac99fdee55a49f79e3b90e99146783fb501b0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:46:09 +0100 Subject: [PATCH 275/320] fix: 'hf mf csave' unused code --- client/cmdhfmf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index f04105c01..c59dad769 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2749,8 +2749,11 @@ int CmdHF14AMfCLoad(const char *Cmd) { } } - if ( res ) + if ( res ) { + if ( data ) + free(data); return 1; + } // PrintAndLogEx(INFO, "DATA | %s", sprint_hex(data+1000, 24) ); @@ -2922,7 +2925,6 @@ int CmdHF14AMfCSave(const char *Cmd) { errors = true; break; } - if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; useuid = false; hasname = true; From a49b3763ddace55fee8b21339d1914645cfcddeb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:50:05 +0100 Subject: [PATCH 276/320] fix: bad check --- client/cmdhf14b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 11b0aabb3..4109a999a 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -283,7 +283,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) { } } // retry - if ( !retry ) + if ( retry <= 0 ) PrintAndLogEx(WARNING, "timeout while waiting for reply."); return false; From 47c808fd5cf4f5ce571f8792fbb297521c2a65a9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:50:24 +0100 Subject: [PATCH 277/320] fix: check return value --- client/fido/fidocore.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index f83e64944..49088ec28 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -347,8 +347,10 @@ bool CheckrpIdHash(json_t *json, uint8_t *hash) { uint8_t hash2[32] = {0}; JsonLoadStr(json, "$.RelyingPartyEntity.id", hashval); - sha256hash((uint8_t *)hashval, strlen(hashval), hash2); - + int res = sha256hash((uint8_t *)hashval, strlen(hashval), hash2); + if (res) + return false; + return !memcmp(hash, hash2, 32); } From c650c238569d5419d0484faf34ff3647b5dc7b0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 19:57:57 +0100 Subject: [PATCH 278/320] fix: 'lf flexdemod' - bad types --- client/cmdlf.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index e41f2d6aa..f644fcc84 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -189,12 +189,15 @@ int CmdFlexdemod(const char *Cmd) { #define LONG_WAIT 100 int i, j, start, bit, sum, phase = 0; - uint8_t data[MAX_GRAPH_TRACE_LEN] = {0}; - size_t size = getFromGraphBuf(data); - if (size == 0) + int data[GraphTraceLen]; + memcpy(data, GraphBuffer, GraphTraceLen); + + if ( GraphTraceLen < 0 ) return 0; - for (i = 0; i < size; ++i) + size_t size = GraphTraceLen; + + for (i = 0; i < GraphTraceLen; ++i) data[i] = (data[i] < 0) ? -1 : 1; for (start = 0; start < size - LONG_WAIT; start++) { From 17fcd8c24bbd090760f33dca7c535967d4bf89d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 20:00:41 +0100 Subject: [PATCH 279/320] fix: possible bad null ref --- client/emv/emvjson.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 45eb1f430..fc10f255c 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -242,20 +242,20 @@ int JsonSaveTLVTree(json_t *root, json_t *elm, char *path, struct tlvdb *tlvdbel bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t * buffer, size_t maxbufferlen, size_t *bufferlen) { int buflen = 0; - switch(param_gethex_to_eol(hexvalue, 0, buffer, maxbufferlen, &buflen)) { - case 1: - PrintAndLog("%s Invalid HEX value.", errormsg); - return false; - case 2: - PrintAndLog("%s Hex value too large.", errormsg); - return false; - case 3: - PrintAndLog("%s Hex value must have even number of digits.", errormsg); - return false; + switch (param_gethex_to_eol(hexvalue, 0, buffer, maxbufferlen, &buflen)) { + case 1: + PrintAndLog("%s Invalid HEX value.", errormsg); + return false; + case 2: + PrintAndLog("%s Hex value too large.", errormsg); + return false; + case 3: + PrintAndLog("%s Hex value must have even number of digits.", errormsg); + return false; } if (buflen > maxbufferlen) { - PrintAndLog("%s HEX length (%d) more than %d", errormsg, *bufferlen, maxbufferlen); + PrintAndLog("%s HEX length (%d) more than %d", errormsg, (bufferlen) ? *bufferlen : -1, maxbufferlen); return false; } From a0e061fcd10bd3a7e2d11da32ab2efc127d44b9b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 20:11:05 +0100 Subject: [PATCH 280/320] fix: rearrange it --- client/cmdlf.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index f644fcc84..240a1d402 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -186,15 +186,18 @@ int CmdLFCommandRead(const char *Cmd) { } int CmdFlexdemod(const char *Cmd) { -#define LONG_WAIT 100 + + if ( GraphTraceLen < 0 ) + return 0; + +#ifndef LONG_WAIT +#define LONG_WAIT 100 +#endif int i, j, start, bit, sum, phase = 0; int data[GraphTraceLen]; memcpy(data, GraphBuffer, GraphTraceLen); - if ( GraphTraceLen < 0 ) - return 0; - size_t size = GraphTraceLen; for (i = 0; i < GraphTraceLen; ++i) From 528e8fe3956b5f9863b2468b3ed9bbda37e7897b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 21:21:56 +0100 Subject: [PATCH 281/320] fix: clock can't be zero or negative --- client/graph.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/graph.c b/client/graph.c index 4346a8040..2b2884819 100644 --- a/client/graph.c +++ b/client/graph.c @@ -115,10 +115,13 @@ int GetAskClock(const char *str, bool printAns) { if (st == false) { idx = DetectASKClock(bits, size, &clock, 20); } - setClockGrid(clock, idx); + + if ( clock > 0 ) { + setClockGrid(clock, idx); + } // Only print this message if we're not looping something if (printAns || g_debugMode) - PrintAndLogEx(NORMAL, "Auto-detected clock rate: %d, Best Starting Position: %d", clock, idx); + PrintAndLogEx(DEBUG, "Auto-detected clock rate: %d, Best Starting Position: %d", clock, idx); return clock; } From f59e67c00cc8565b77844463b694728f32ef7e1f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 21:42:30 +0100 Subject: [PATCH 282/320] fix: possible overrun --- client/crypto/asn1dump.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 52814f22b..a0abdf3cf 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -237,10 +237,13 @@ static char *asn1_oid_description(const char *oid, bool with_group_desc) { static char res[300]; memset(res, 0x00, sizeof(res)); - strcpy(fname, get_my_executable_directory()); + size_t len = strlen(get_my_executable_directory()); + if ( len > 300 ) len = 299; + + strncpy(fname, get_my_executable_directory(), len); strcat(fname, "crypto/oids.json"); if (access(fname, F_OK) < 0) { - strcpy(fname, get_my_executable_directory()); + strncpy(fname, get_my_executable_directory(), len); strcat(fname, "oids.json"); if (access(fname, F_OK) < 0) { goto error; // file not found From 99dc51e005b3349a15dc0982619f1616ac943d28 Mon Sep 17 00:00:00 2001 From: vratiskol Date: Fri, 22 Feb 2019 13:21:58 +0100 Subject: [PATCH 283/320] Mem Leak --- armsrc/appmain.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0bf9ccb9d..5002a7138 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1253,11 +1253,11 @@ void UsbPacketReceived(uint8_t *packet, int len) { size_t size = MIN(USB_CMD_DATA_SIZE, len); - uint8_t *mem = BigBuf_malloc(size); - - if (!FlashInit()) { + if (!FlashInit()) { break; } + + uint8_t *mem = BigBuf_malloc(size); for(size_t i = 0; i < len; i += size) { len = MIN((len - i), size); @@ -1271,6 +1271,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { break; } } + BigBuf_free(); FlashStop(); LED_B_OFF(); break; From 898f2bea5b269c9b9d67f20ed5ff1d9c7da9de8c Mon Sep 17 00:00:00 2001 From: vratiskol Date: Fri, 22 Feb 2019 20:22:12 +0100 Subject: [PATCH 284/320] Crapto Clean Up Clean up comment code --- common/crapto1/crapto1.c | 41 +++++++--------------------------------- common/crapto1/crypto1.c | 19 ++----------------- 2 files changed, 9 insertions(+), 51 deletions(-) diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index af1ed8167..f0b37dbae 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -33,21 +33,6 @@ static void __attribute__((constructor)) fill_lut() #define filter(x) (filterlut[(x) & 0xfffff]) #endif -/** binsearch - * Binary search for the first occurence of *stop's MSB in sorted [start,stop] - */ -/* static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop) -{ - uint32_t mid, val = *stop & 0xff000000; - while(start != stop) - if(start[mid = (stop - start) >> 1] > val) - stop = &start[mid]; - else - start += mid + 1; - - return start; -} - */ /** update_contribution * helper, calculates the partial linear feedback contributions and puts in MSB */ @@ -174,7 +159,7 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in) // allocate memory for out of place bucket_sort bucket_array_t bucket; - + for (uint32_t i = 0; i < 2; i++) { for (uint32_t j = 0; j <= 0xff; j++) { bucket[i][j].head = malloc(sizeof(uint32_t) << 14); @@ -311,7 +296,7 @@ uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) int out; uint8_t ret; uint32_t t; - + s->odd &= 0xffffff; t = s->odd, s->odd = s->even, s->even = t; @@ -329,12 +314,6 @@ uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) */ uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) { - /* - int i, ret=0; - for (i = 7; i >= 0; --i) - ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i; -*/ -// unfold loop 20160112 uint8_t ret = 0; ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7; ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6; @@ -351,13 +330,7 @@ uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) */ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) { - /* - int i; - uint32_t ret = 0; - for (i = 31; i >= 0; --i) - ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24); -*/ -// unfold loop 20160112 + uint32_t ret = 0; ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24); @@ -376,7 +349,7 @@ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24); - + ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24); @@ -385,7 +358,7 @@ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24); - + ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24); ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24); @@ -445,7 +418,7 @@ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) { uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); if (!candidates) return 0; - + uint32_t c, entry; int size = 0, i, good; @@ -458,7 +431,7 @@ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) if (good) candidates[size++] = i; } - + candidates[size] = -1; return candidates; diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c index bc0e7337a..034d92215 100644 --- a/common/crapto1/crypto1.c +++ b/common/crapto1/crypto1.c @@ -48,9 +48,8 @@ struct Crypto1State * crypto1_create(uint64_t key) if ( !s ) return NULL; s->odd = s->even = 0; - + int i; - //for(i = 47;s && i > 0; i -= 2) { for(i = 47; i > 0; i -= 2) { s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); s->even = s->even << 1 | BIT(key, i ^ 7); @@ -89,13 +88,6 @@ uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) } uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) { - /* - uint8_t i, ret = 0; - - for (i = 0; i < 8; ++i) - ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i; - */ -// unfold loop 20161012 uint8_t ret = 0; ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0; ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1; @@ -109,13 +101,6 @@ uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) } uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) { - /* - uint32_t i, ret = 0; - - for (i = 0; i < 32; ++i) - ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24); -*/ -//unfold loop 2016012 uint32_t ret = 0; ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24); ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24); @@ -125,7 +110,7 @@ uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24); ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24); ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24); - + ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24); ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24); ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24); From 157e08f51d7980ba208586398ae849aef036a81c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 22:17:36 +0100 Subject: [PATCH 285/320] fix: mem leaks --- client/emv/cmdemv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 94df507de..52033afb4 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -266,9 +266,11 @@ int CmdEMVGPO(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - pdol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x9f38, datalen, data), tlvRoot, 0x83); + struct tlvdb *tmp_ext = tlvdb_external(0x9f38, datalen, data); + pdol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x83); if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); return 4; } @@ -446,9 +448,11 @@ int CmdEMVAC(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - cdol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x8c, datalen, data), tlvRoot, 0x01); // 0x01 - dummy tag + struct tlvdb *tmp_ext = tlvdb_external(0x8c, datalen, data); + cdol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x01); // 0x01 - dummy tag if (!cdol_data_tlv){ PrintAndLogEx(ERR, "Can't create CDOL TLV."); + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); return 4; } @@ -588,9 +592,11 @@ int CmdEMVInternalAuthenticate(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - ddol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x9f49, datalen, data), tlvRoot, 0x01); // 0x01 - dummy tag + struct tlvdb *tmp_ext = tlvdb_external(0x9f49, datalen, data); + ddol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x01); // 0x01 - dummy tag if (!ddol_data_tlv){ PrintAndLogEx(ERR, "Can't create DDOL TLV."); + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); return 4; } From da9c662b23c1da3bf4c9900ece9e2c641988af34 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 22:31:24 +0100 Subject: [PATCH 286/320] text --- client/cmdlffdx.c | 50 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 194bb7f32..647dfe04e 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -159,26 +159,24 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t */ int CmdFDXBdemodBI(const char *Cmd){ - int invert = 1; - int clk = 32; - int errCnt = 0; - int offset = 0, maxErr = 0; - uint8_t BitStream[MAX_DEMOD_BUF_LEN]; - size_t size = getFromGraphBuf(BitStream); + int clk = 32; + int invert = 1, errCnt = 0, offset = 0, maxErr = 0; + uint8_t bs[MAX_DEMOD_BUF_LEN]; + size_t size = getFromGraphBuf(bs); - errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); + errCnt = askdemod(bs, &size, &clk, &invert, maxErr, 0, 0); if ( errCnt < 0 || errCnt > maxErr ) { PrintAndLogEx(DEBUG, "DEBUG: Error - FDXB no data or error found %d, clock: %d", errCnt, clk); return 0; } - errCnt = BiphaseRawDecode(BitStream, &size, &offset, 1); + errCnt = BiphaseRawDecode(bs, &size, &offset, 1); if (errCnt < 0 || errCnt > maxErr ) { PrintAndLogEx(DEBUG, "DEBUG: Error - FDXB BiphaseRawDecode: %d", errCnt); return 0; } - int preambleIndex = detectFDXB(BitStream, &size); + int preambleIndex = detectFDXB(bs, &size); if (preambleIndex < 0){ PrintAndLogEx(DEBUG, "DEBUG: Error - FDXB preamble not found :: %d",preambleIndex); return 0; @@ -188,10 +186,10 @@ int CmdFDXBdemodBI(const char *Cmd){ return 0; } - setDemodBuf(BitStream, 128, preambleIndex); + setDemodBuf(bs, 128, preambleIndex); // remove marker bits (1's every 9th digit after preamble) (pType = 2) - size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117); + size = removeParity(bs, preambleIndex + 11, 9, 2, 117); if ( size != 104 ) { PrintAndLogEx(DEBUG, "DEBUG: Error - FDXB error removeParity:: %d", size); return 0; @@ -199,15 +197,15 @@ int CmdFDXBdemodBI(const char *Cmd){ PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); //got a good demod - uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32); - uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10); - uint8_t dataBlockBit = BitStream[48]; - uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14); - uint8_t animalBit = BitStream[63]; - uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); - uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); + uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(bs+32, 6)) << 32) | bytebits_to_byteLSBF(bs, 32); + uint32_t countryCode = bytebits_to_byteLSBF(bs+38, 10); + uint8_t dataBlockBit = bs[48]; + uint32_t reservedCode = bytebits_to_byteLSBF(bs+49, 14); + uint8_t animalBit = bs[63]; + uint32_t crc16 = bytebits_to_byteLSBF(bs+64, 16); + uint32_t extended = bytebits_to_byteLSBF(bs+80, 24); - uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream,32)<<32) | bytebits_to_byte(BitStream+32,32); + uint64_t rawid = ((uint64_t)bytebits_to_byte(bs, 32) << 32) | bytebits_to_byte(bs+32, 32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); @@ -219,13 +217,13 @@ int CmdFDXBdemodBI(const char *Cmd){ PrintAndLogEx(SUCCESS, "CountryCode: %04u", countryCode); PrintAndLogEx(SUCCESS, "Reserved/RFU: %u", reservedCode); - PrintAndLogEx(SUCCESS, "Animal Tag: %s", animalBit ? "True" : "False"); - PrintAndLogEx(SUCCESS, "Has extended data: %s [0x%X]", dataBlockBit ? "True" : "False", extended); - PrintAndLogEx(SUCCESS, "CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); + PrintAndLogEx(SUCCESS, "Animal Tag: %s", animalBit ? _YELLOW_(True) : "False"); + PrintAndLogEx(SUCCESS, "Has extended data: %s [0x%X]", dataBlockBit ? _YELLOW_(True) : "False", extended); + PrintAndLogEx(SUCCESS, "CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? _GREEN_(Passed) : "Failed"); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); - char *bin = sprint_bin_break(BitStream,size,16); + char *bin = sprint_bin_break(bs, size, 16); PrintAndLogEx(DEBUG, "DEBUG BinStream:\n%s",bin); } return 1; @@ -287,9 +285,9 @@ int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); PrintAndLogEx(SUCCESS, "Country Code %04u", countryCode); PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); - PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? "True" : "False"); - PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? "True" : "False", extended); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? "Ok" : "Failed"); + PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? _YELLOW_(True) : "False"); + PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? _YELLOW_(True) : "False", extended); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? _GREEN_(Ok) : _RED_(Failed); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); From 34a17f842dd90a3726f953ecde95d63c2066f714 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 22:34:14 +0100 Subject: [PATCH 287/320] fix --- client/cmdlffdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 647dfe04e..4f867b038 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -287,7 +287,7 @@ int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? _YELLOW_(True) : "False"); PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? _YELLOW_(True) : "False", extended); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? _GREEN_(Ok) : _RED_(Failed); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? _GREEN_(Ok) : "Failed"); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size); From 2e3694aa3b44cbc311159730a52b7793b684faf8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:40:11 +0100 Subject: [PATCH 288/320] fix: 'trace list' - missing break --- client/cmdtrace.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 56f97ca1d..cf55970b0 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -165,7 +165,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui crcStatus = iso14443B_CRC_check(frame, data_len); break; case PROTO_MIFARE: - crcStatus = mifare_CRC_check(isResponse, frame, data_len); + crcStatus = mifare_CRC_check(isResponse, frame, data_len); + break; case ISO_14443A: case MFDES: crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); @@ -288,6 +289,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui void printFelica(uint16_t traceLen, uint8_t *trace) { + PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); PrintAndLogEx(NORMAL, " Gap | Src | Data | CRC | Annotation |"); PrintAndLogEx(NORMAL, "--------|-----|---------------------------------|----------|-------------------|"); uint16_t tracepos = 0; @@ -511,8 +513,8 @@ int CmdTraceList(const char *Cmd) { } } - PrintAndLogEx(NORMAL, "Recorded Activity (TraceLen = %d bytes)", traceLen); - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %d bytes)", traceLen); + PrintAndLogEx(INFO, ""); if (protocol == FELICA) { printFelica(traceLen, trace); } else { @@ -526,8 +528,6 @@ int CmdTraceList(const char *Cmd) { " Tag Mode: Timings are in sub carrier periods (1/212 kHz == 4.7us)"); if ( protocol == ISO_15693 ) PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate"); - if ( protocol == FELICA ) - PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate"); if ( protocol == ISO_7816_4 ) PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet"); From 3d84e4dc03f96e477bed27b996b502e097eaebd2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:43:35 +0100 Subject: [PATCH 289/320] fix: dead code --- client/cmdlft55xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8d850f5d0..3c7547e34 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1701,7 +1701,7 @@ int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); - while ((!found) || (curr <= end_password)){ + while ( !found || (curr <= end_password)){ printf("."); fflush(stdout); @@ -1713,9 +1713,9 @@ int CmdT55xxBruteForce(const char *Cmd) { PrintAndLogEx(WARNING, "Aquireing data from device failed. Quitting"); return 0; } + found = tryDetectModulation(); - - if (found) break; + ++curr; } From 0803e532ccdaba7c7b2f89abe62f0072cb1abe7e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:51:23 +0100 Subject: [PATCH 290/320] fix: 'hf felica list' - string overflows --- client/cmdhffelica.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index acfc68cf2..42c56d900 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -253,7 +253,7 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { char line[110] = {0}; for (int j = 0; j < 16; j++) { - snprintf(line+( j * 4),110, "%02x ", trace[j+3]); + snprintf(line + (j * 4), sizeof(line) - 1 - (j*4) , "%02x ", trace[j+3]); } PrintAndLogEx(NORMAL, "block number %02x, status: %02x %02x",blocknum,status1, status2); @@ -277,7 +277,7 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { uint32_t regB = trace[7] | trace[8] << 8 | trace[9] << 16 | trace[10] << 24; line[0] = 0; for (int j = 0; j < 8; j++) - snprintf(line+( j * 2),110, "%02x", trace[j+11]); + snprintf(line+( j * 2), sizeof(line)-1-(j*2), "%02x", trace[j+11]); PrintAndLogEx(NORMAL, "REG: regA: %d regB: %d regC: %s ", regA, regB, line); } break; @@ -287,10 +287,10 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { char idd[20]; char idm[20]; for (int j = 0; j < 8; j++) - snprintf(idd+( j * 2),20, "%02x", trace[j+3]); + snprintf(idd + (j * 2), sizeof(idd) - 1 - (j*2), "%02x", trace[j+3]); for (int j = 0; j < 6; j++) - snprintf(idm+( j * 2),20, "%02x", trace[j+13]); + snprintf(idm + (j * 2), sizeof(idm) - 1 - (j*2), "%02x", trace[j+13]); PrintAndLogEx(NORMAL, "ID Block, IDd: 0x%s DFC: 0x%02x%02x Arb: %s ", idd, trace[11], trace [12], idm); } From 142b3d8de52f8c7b38c27d62edfdc22c93c129d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:54:24 +0100 Subject: [PATCH 291/320] fix: assign --- client/loclass/ikeys.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 16b5513b7..c1265dc4d 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -428,8 +428,8 @@ void testPermute() printarr("permuted", res, 8); } -//These testcases are -//{ UID , TEMP_KEY, DIV_KEY} using the specific key +// These testcases are +// { UID , TEMP_KEY, DIV_KEY} using the specific key typedef struct { uint8_t uid[8]; @@ -475,7 +475,7 @@ int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_context return retval; } bool des_getParityBitFromKey(uint8_t key) -{//The top 7 bits is used +{ // The top 7 bits is used bool parity = ((key & 0x80) >> 7) ^ ((key & 0x40) >> 6) ^ ((key & 0x20) >> 5) ^ ((key & 0x10) >> 4) ^ ((key & 0x08) >> 3) @@ -676,7 +676,8 @@ static bool readKeyFile(uint8_t key[8]) { bool retval = false; //Test a few variants - char filename[30]; + char filename[30] = {0}; + if (fileExists("iclass_key.bin")){ sprintf(filename, "%s.bin", "iclass_key"); } else if (fileExists("loclass/iclass_key.bin")){ From 2b9eb401facee8839344c960f2930160779ec806 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:54:36 +0100 Subject: [PATCH 292/320] fix: more checks --- client/loclass/fileutils.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 6ce7c42ea..6f6f1a5a4 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -323,6 +323,7 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ if ( preferredName == NULL ) return 1; if ( suffix == NULL ) return 1; + if ( data == NULL ) return 1; size_t counter = 0; int retval = 0, hexlen = 0; @@ -364,7 +365,9 @@ int loadFileEML(const char *preferredName, const char *suffix, void* data, size_ } fclose(f); PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_(%s), counter, fileName); - *datalen = counter; + + if ( datalen ) + *datalen = counter; out: free(fileName); @@ -372,12 +375,14 @@ out: } int loadFileJSON(const char *preferredName, const char *suffix, void* data, size_t maxdatalen, size_t* datalen) { - *datalen = 0; - json_t *root; - json_error_t error; if ( preferredName == NULL ) return 1; if ( suffix == NULL ) return 1; + if ( data == NULL ) return 1; + + *datalen = 0; + json_t *root; + json_error_t error; int retval = 0; int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); @@ -461,6 +466,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data if ( preferredName == NULL ) return 1; if ( suffix == NULL ) return 1; + if ( data == NULL ) return 1; // t5577 == 4bytes // mifare == 6 bytes @@ -516,8 +522,10 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void* data counter += (keylen >> 1); } fclose(f); - PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file " _YELLOW_(%s), *keycnt, fileName); - *datalen = counter; + PrintAndLogDevice(SUCCESS, "loaded " _GREEN_(%2d) "keys from dictionary file " _YELLOW_(%s), *keycnt, fileName); + + if ( datalen ) + *datalen = counter; out: free(fileName); return retval; From bd26794c208e3504a2e7e92959b5751a0fd86081 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Feb 2019 23:57:04 +0100 Subject: [PATCH 293/320] revert --- client/cmdflashmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index d3aaff19e..34bb89cbc 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -13,6 +13,7 @@ #include "mbedtls/rsa.h" #include "mbedtls/sha1.h" +#include "mbedtls/base64.h" #define MCK 48000000 //#define FLASH_BAUD 24000000 @@ -247,7 +248,6 @@ int CmdFlashMemLoad(const char *Cmd){ res = loadFile(filename, "bin", data, &datalen); //int res = loadFileEML( filename, "eml", data, &datalen); if ( res ) { - free(data); return 1; } From ae4e3b72afe9b58c398fd5349d4c04cb7429b774 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 00:10:02 +0100 Subject: [PATCH 294/320] chg: colors --- client/cmdhf14a.c | 6 +++--- client/cmdhflist.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 9140a3502..27f670fac 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -579,11 +579,11 @@ int CmdHF14AInfo(const char *Cmd) { if (isMifareClassic) { int res = detect_classic_prng(); if ( res == 1 ) - PrintAndLogEx(SUCCESS, "Prng detection: WEAK"); + PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_(WEAK)); else if (res == 0 ) - PrintAndLogEx(SUCCESS, "Prng detection: HARD"); + PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_(HARD)); else - PrintAndLogEx(FAILED, "prng detection: failed"); + PrintAndLogEx(FAILED, "prng detection: " _RED_(failed)); if ( do_nack_test ) detect_classic_nackbug(silent); diff --git a/client/cmdhflist.c b/client/cmdhflist.c index b2e0eeecc..faed275cd 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -686,7 +686,7 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes PrintAndLogEx(NORMAL, " | | * |%49s %012"PRIx64" prng %s | |", "key", mfLastKey, - validate_prng_nonce(AuthData.nt) ? "WEAK": "HARD"); + validate_prng_nonce(AuthData.nt) ? _GREEN_(WEAK): _YELLOW_(HARD)); AuthData.first_auth = false; From 7945b5a805bcb5deeb4285046fd631a0d6722b41 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 00:15:39 +0100 Subject: [PATCH 295/320] colors --- client/mifarehost.c | 12 ++++++------ common/lfdemod.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/mifarehost.c b/client/mifarehost.c index 927fb7bc0..632ff7c71 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -959,8 +959,8 @@ int detect_classic_nackbug(bool verbose){ } return 2; } - case 2 : PrintAndLogEx(SUCCESS, "always leak NACK detected"); return 3; - case 1 : PrintAndLogEx(SUCCESS, "NACK bug detected"); return 1; + case 2 : PrintAndLogEx(SUCCESS, _GREEN_(always leak NACK detected)); return 3; + case 1 : PrintAndLogEx(SUCCESS, _GREEN_(NACK bug detected)); return 1; case 0 : PrintAndLogEx(SUCCESS, "No NACK bug detected"); return 2; default : PrintAndLogEx(WARNING, "errorcode from device [%i]", ok); return 0; } @@ -981,9 +981,9 @@ void detect_classic_magic(void) { isGeneration = resp.arg[0] & 0xff; switch( isGeneration ){ - case 1: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): YES"); break; - case 2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): YES"); break; - //case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2): YES"); break; - default: PrintAndLogEx(INFO, "Answers to magic commands: NO"); break; + case 1: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_(YES)); break; + case 2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_(YES)); break; + //case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2): " _GREEN_(YES)); break; + default: PrintAndLogEx(INFO, "Answers to magic commands: " _YELLOW_(NO)); break; } } \ No newline at end of file diff --git a/common/lfdemod.c b/common/lfdemod.c index 6b755d3dc..1ef5915c9 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -77,7 +77,7 @@ static void resetSignal(void) { signalprop.isnoise = true; } static void printSignal(void) { - prnt("LF Signal properties:"); + prnt("LF signal properties:"); prnt(" high..........%d", signalprop.high); prnt(" low...........%d", signalprop.low); prnt(" mean..........%d", signalprop.mean); @@ -1922,7 +1922,7 @@ int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *s dest[numBits++] = curPhase; } else if (waveLenCnt < fc - 1) { //wave is smaller than field clock (shouldn't happen often) errCnt2++; - if(errCnt2 > 101) return errCnt2; + if (errCnt2 > 101) return errCnt2; avgWaveVal += dest[i+1]; continue; } From e3a0594b98f52d5e40c9519d00b119c2b2ec2f93 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 00:31:00 +0100 Subject: [PATCH 296/320] colors --- client/hardnested/hardnested_bruteforce.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 2a7618a1d..98f2785b2 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -170,7 +170,9 @@ crack_states_thread(void* x){ __atomic_fetch_add(&found_bs_key, key, __ATOMIC_SEQ_CST); char progress_text[80]; - sprintf(progress_text, "Brute force phase completed. Key found: %012" PRIx64, key); + char keystr[18]; + sprintf(keystr, "%012" PRIx64, key); + sprintf(progress_text, "Brute force phase completed. Key found: " _GREEN_(keystr)); hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); break; } else if(keys_found){ From a4ecc6d3ce3cb3a1f6be5f90d4fb43903f061e1f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 00:32:59 +0100 Subject: [PATCH 297/320] colors --- client/hardnested/hardnested_bruteforce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 98f2785b2..4c820cbc1 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -172,7 +172,7 @@ crack_states_thread(void* x){ char progress_text[80]; char keystr[18]; sprintf(keystr, "%012" PRIx64, key); - sprintf(progress_text, "Brute force phase completed. Key found: " _GREEN_(keystr)); + sprintf(progress_text, "Brute force phase completed. Key found: " _GREEN_(%s), keystr); hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); break; } else if(keys_found){ From a8eb0fd05fa2c31a61720206556579f759dc8d44 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 00:38:48 +0100 Subject: [PATCH 298/320] colors --- client/hardnested/hardnested_bruteforce.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 4c820cbc1..1a09d7a49 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -171,8 +171,8 @@ crack_states_thread(void* x){ char progress_text[80]; char keystr[18]; - sprintf(keystr, "%012" PRIx64, key); - sprintf(progress_text, "Brute force phase completed. Key found: " _GREEN_(%s), keystr); + sprintf(keystr, "%012" PRIx64 " ", key); + sprintf(progress_text, "Brute force phase completed. Key found: " _YELLOW_(%s), keystr); hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); break; } else if(keys_found){ From 711d384e7d2f41823467980ad918fcb27507cbde Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 25 Feb 2019 12:44:21 +0100 Subject: [PATCH 299/320] chg: 'data autocorrelate g' - visual with gridclock patter and markup of two tops. Also added a "visual" inspection of peaks with 3% tolerance. This increases usability quite much. --- client/cmddata.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 65fd0d829..62308c39f 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -754,19 +754,53 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph lastmax = i; } } - - if (verbose && ( correlation > 1 ) ) { - PrintAndLogEx(SUCCESS, "possible correlation %4d samples", correlation); - } else { - PrintAndLogEx(FAILED, "no repeating pattern found"); + + // + int hi = 0, idx = 0; + int distance = 0, hi_1 = 0, idx_1 = 0; + for (int i=0; i<=len; ++i){ + if ( CorrelBuffer[i] > hi) { + hi = CorrelBuffer[i]; + idx = i; + } } - if (SaveGrph){ + for (int i=idx+1; i<=window; ++i){ + if ( CorrelBuffer[i] > hi_1 ) { + hi_1 = CorrelBuffer[i]; + idx_1 = i; + } + } + + int foo = ABS(hi-hi_1); + int bar = ((int)(((hi+hi_1) / 2) * 0.03)); + if ( verbose && foo < bar ) { + distance = idx_1 - idx; + PrintAndLogEx(SUCCESS, "possible 3% visible correlation %4d samples", distance); + } else if (verbose && ( correlation > 1 ) ) { + PrintAndLogEx(SUCCESS, "possible correlation %4d samples", correlation); + } else { + PrintAndLogEx(FAILED, "no repeating pattern found, try increasing window size"); + } + + int retval = correlation; + if (SaveGrph) { //GraphTraceLen = GraphTraceLen - window; memcpy(out, CorrelBuffer, len * sizeof(int)); + if ( distance > 0) { + setClockGrid(distance, idx); + retval = distance; + } + else + setClockGrid(correlation, idx); + + CursorCPos = idx_1; + CursorDPos = idx_1+retval; + DemodBufferLen = 0; RepaintGraphWindow(); } - return correlation; + + return retval; } int CmdAutoCorr(const char *Cmd) { From 81f8749caf617734782751b1591e9e27e6972650 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 25 Feb 2019 12:46:06 +0100 Subject: [PATCH 300/320] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9ebb49b2..673b25f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Chg 'data autocorrelate' - better visual representation and added extra peak detection (@iceman) - Fix 'lf search' - false positive indala identification fixed (@iceman) - Add 'lf keri' - basic support for Keri tags (@iceman) - Add 'hf mf list' - re-added it again (@iceman) From 64bae8c8be83810f9e9347d8fd2450fdd834caa5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 15:07:31 +0100 Subject: [PATCH 301/320] fix: 'data detectclock' - now prints clock again... --- client/graph.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/graph.c b/client/graph.c index 2b2884819..42bb79c84 100644 --- a/client/graph.c +++ b/client/graph.c @@ -121,7 +121,7 @@ int GetAskClock(const char *str, bool printAns) { } // Only print this message if we're not looping something if (printAns || g_debugMode) - PrintAndLogEx(DEBUG, "Auto-detected clock rate: %d, Best Starting Position: %d", clock, idx); + PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d, Best Starting Position: %d", clock, idx); return clock; } @@ -140,7 +140,7 @@ uint8_t GetPskCarrier(const char *str, bool printAns) { if (( fc >> 8) == 10 && carrier == 8) return 0; // Only print this message if we're not looping something if (printAns) - PrintAndLogEx(NORMAL, "Auto-detected PSK carrier rate: %d", carrier); + PrintAndLogEx(SUCCESS, "Auto-detected PSK carrier rate: %d", carrier); return carrier; } @@ -162,7 +162,7 @@ int GetPskClock(const char* str, bool printAns) { setClockGrid(clock, firstPhaseShiftLoc); // Only print this message if we're not looping something if (printAns) - PrintAndLogEx(NORMAL, "Auto-detected clock rate: %d", clock); + PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d", clock); return clock; } @@ -184,7 +184,7 @@ int GetNrzClock(const char* str, bool printAns) { setClockGrid(clock, clkStartIdx); // Only print this message if we're not looping something if (printAns) - PrintAndLogEx(NORMAL, "Auto-detected clock rate: %d", clock); + PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d", clock); return clock; } //by marshmellow @@ -203,7 +203,7 @@ int GetFskClock(const char* str, bool printAns) { if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){ if (printAns) - PrintAndLogEx(NORMAL, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); + PrintAndLogEx(SUCCESS, "Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1); setClockGrid(rf1, firstClockEdge); return rf1; } From d929f31eb37d05899012faf4c4846b2413644386 Mon Sep 17 00:00:00 2001 From: 3ldidi94 Date: Mon, 25 Feb 2019 18:52:44 +0100 Subject: [PATCH 302/320] Update default_iclass_keys.dic --- client/default_iclass_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/default_iclass_keys.dic b/client/default_iclass_keys.dic index 0f7ec2d2c..829ba521e 100644 --- a/client/default_iclass_keys.dic +++ b/client/default_iclass_keys.dic @@ -8,3 +8,4 @@ AEA684A6DAB23278 -- AA1 5b7c62c491c11b39 -- from loclass demo file. F0E1D2C3B4A59687 -- Kd from PicoPass 2k documentation 5CBCF1DA45D5FB4F -- PicoPass Default Exchange Key +31ad7ebd2f282168 -- From HID multiclassSE reader From d6bb8d630a6254ceefa7043e330853295cbfc503 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 19:03:14 +0100 Subject: [PATCH 303/320] fix: strings --- client/cmdhffelica.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index 42c56d900..efb6b68d7 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -277,7 +277,8 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { uint32_t regB = trace[7] | trace[8] << 8 | trace[9] << 16 | trace[10] << 24; line[0] = 0; for (int j = 0; j < 8; j++) - snprintf(line+( j * 2), sizeof(line)-1-(j*2), "%02x", trace[j+11]); + snprintf(line + (j*2), sizeof(line)-1-(j*2), "%02x", trace[j+11]); + PrintAndLogEx(NORMAL, "REG: regA: %d regB: %d regC: %s ", regA, regB, line); } break; @@ -287,10 +288,10 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { char idd[20]; char idm[20]; for (int j = 0; j < 8; j++) - snprintf(idd + (j * 2), sizeof(idd) - 1 - (j*2), "%02x", trace[j+3]); + snprintf(idd + (j*2), sizeof(idd)-1-(j*2), "%02x", trace[j+3]); for (int j = 0; j < 6; j++) - snprintf(idm + (j * 2), sizeof(idm) - 1 - (j*2), "%02x", trace[j+13]); + snprintf(idm + (j*2), sizeof(idm)-1-(j*2), "%02x", trace[j+13]); PrintAndLogEx(NORMAL, "ID Block, IDd: 0x%s DFC: 0x%02x%02x Arb: %s ", idd, trace[11], trace [12], idm); } @@ -299,10 +300,10 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { char idm[20]; char pmm[20]; for (int j = 0; j < 8; j++) - snprintf(idm + (j * 2), 20, "%02x", trace[j+3]); + snprintf(idm + (j*2), sizeof(idm)-1-(j*2), "%02x", trace[j+3]); for (int j = 0; j < 8; j++) - snprintf(pmm + (j * 2), 20, "%02x", trace[j+11]); + snprintf(pmm + (j*2), sizeof(pmm)-1-(j*2), "%02x", trace[j+11]); PrintAndLogEx(NORMAL, "DeviceId: IDm: 0x%s PMm: 0x%s ", idm, pmm); } From 56a75fbf0b47c15a96ff621e8d7c274136f7a6b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 19:03:31 +0100 Subject: [PATCH 304/320] fix: bad division --- client/cmddata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 62308c39f..7e037c2e6 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -758,14 +758,14 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph // int hi = 0, idx = 0; int distance = 0, hi_1 = 0, idx_1 = 0; - for (int i=0; i<=len; ++i){ + for (int i = 0; i <= len; ++i){ if ( CorrelBuffer[i] > hi) { hi = CorrelBuffer[i]; idx = i; } } - for (int i=idx+1; i<=window; ++i){ + for (int i = idx+1; i <= window; ++i){ if ( CorrelBuffer[i] > hi_1 ) { hi_1 = CorrelBuffer[i]; idx_1 = i; @@ -773,7 +773,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph } int foo = ABS(hi-hi_1); - int bar = ((int)(((hi+hi_1) / 2) * 0.03)); + int bar = (int)(((hi+hi_1) / 2) * 0.03); if ( verbose && foo < bar ) { distance = idx_1 - idx; PrintAndLogEx(SUCCESS, "possible 3% visible correlation %4d samples", distance); From 972f8590e0bfa25a78b3ed19cb623a3c670102f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 19:10:00 +0100 Subject: [PATCH 305/320] fix dereference --- client/emv/emvjson.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index fc10f255c..dc409a2a5 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -259,7 +259,8 @@ bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t * buffer, s return false; } - *bufferlen = buflen; + if ( bufferlen ) + *bufferlen = buflen; return true; } From 8c6312e2097aa804ef4e9ef5dc9ce1ffeba2e603 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Feb 2019 19:10:37 +0100 Subject: [PATCH 306/320] fix mem leaks --- client/emv/cmdemv.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 52033afb4..f14d23f2d 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -253,6 +253,7 @@ int CmdEMVGPO(const char *cmd) { // calc PDOL struct tlv *pdol_data_tlv = NULL; + struct tlvdb *tmp_ext = NULL; struct tlv data_tlv = { .tag = 0x83, .len = datalen, @@ -266,7 +267,7 @@ int CmdEMVGPO(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - struct tlvdb *tmp_ext = tlvdb_external(0x9f38, datalen, data); + tmp_ext = tlvdb_external(0x9f38, datalen, data); pdol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x83); if (!pdol_data_tlv){ PrintAndLogEx(ERR, "Can't create PDOL TLV."); @@ -285,8 +286,8 @@ int CmdEMVGPO(const char *cmd) { unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len); if (!pdol_data_tlv_data) { PrintAndLogEx(ERR, "Can't create PDOL data."); + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); - free(pdol_data_tlv); return 4; } PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -299,7 +300,8 @@ int CmdEMVGPO(const char *cmd) { if (pdol_data_tlv != &data_tlv) free(pdol_data_tlv); - + + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); if (sw) @@ -434,6 +436,7 @@ int CmdEMVAC(const char *cmd) { // calc CDOL struct tlv *cdol_data_tlv = NULL; + struct tlvdb *tmp_ext = NULL; struct tlv data_tlv = { .tag = 0x01, .len = datalen, @@ -448,7 +451,7 @@ int CmdEMVAC(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - struct tlvdb *tmp_ext = tlvdb_external(0x8c, datalen, data); + tmp_ext = tlvdb_external(0x8c, datalen, data); cdol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x01); // 0x01 - dummy tag if (!cdol_data_tlv){ PrintAndLogEx(ERR, "Can't create CDOL TLV."); @@ -473,6 +476,8 @@ int CmdEMVAC(const char *cmd) { if (cdol_data_tlv != &data_tlv) free(cdol_data_tlv); + + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); if (sw) @@ -578,6 +583,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) { // calc DDOL struct tlv *ddol_data_tlv = NULL; + struct tlvdb *tmp_ext = NULL; struct tlv data_tlv = { .tag = 0x01, .len = datalen, @@ -592,7 +598,7 @@ int CmdEMVInternalAuthenticate(const char *cmd) { ParamLoadFromJson(tlvRoot); }; - struct tlvdb *tmp_ext = tlvdb_external(0x9f49, datalen, data); + tmp_ext = tlvdb_external(0x9f49, datalen, data); ddol_data_tlv = dol_process((const struct tlv *)tmp_ext, tlvRoot, 0x01); // 0x01 - dummy tag if (!ddol_data_tlv){ PrintAndLogEx(ERR, "Can't create DDOL TLV."); @@ -617,6 +623,8 @@ int CmdEMVInternalAuthenticate(const char *cmd) { if (ddol_data_tlv != &data_tlv) free(ddol_data_tlv); + + tlvdb_free(tmp_ext); tlvdb_free(tlvRoot); if (sw) From c2046f2e65bf293ea6697793dbf9f33723b63830 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 25 Feb 2019 22:33:49 +0100 Subject: [PATCH 307/320] CHG: 'hf mf dump' - now saves in BIN/EML/JSON default CHG: 'hf mf esave' - now saves in BIN/EML/JSON default --- client/cmdhfmf.c | 69 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c59dad769..00d5c3176 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -11,6 +11,9 @@ #include "cmdhfmf.h" #include "mifare4.h" + +#define MFBLOCK_SIZE 16 + #define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 #define MIFARE_1K_MAXBLOCK 64 @@ -697,10 +700,13 @@ int CmdHF14AMfDump(const char *Cmd) { uint8_t cmdp = 0; char keyFilename[FILE_PATH_SIZE] = {0}; - char dataFilename[FILE_PATH_SIZE] = {0}; + char dataFilename[FILE_PATH_SIZE]; char * fptr; - FILE *fin, *fout; + memset(keyFilename, 0, sizeof(keyFilename)); + memset(dataFilename, 0, sizeof(dataFilename)); + + FILE *f; UsbCommand resp; while(param_getchar(Cmd, cmdp) != 0x00) { @@ -734,7 +740,7 @@ int CmdHF14AMfDump(const char *Cmd) { strcpy(keyFilename, fptr); } - if ((fin = fopen(keyFilename, "rb")) == NULL) { + if ((f = fopen(keyFilename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file " _YELLOW_(%s), keyFilename); return 1; } @@ -742,29 +748,29 @@ int CmdHF14AMfDump(const char *Cmd) { // Read keys A from file size_t bytes_read; for (sectorNo=0; sectorNo Date: Tue, 26 Feb 2019 22:27:33 +0100 Subject: [PATCH 308/320] another --- client/default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/default_keys.dic b/client/default_keys.dic index ffbdb3cbd..cd23d9a0d 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -98,6 +98,7 @@ fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA 314B49474956,--VIGIK1KeyA 564c505f4d41,--VIGIK1KeyB ba5b895da162,--VIGIK1KeyB +4143414F5250, # # Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ f4a9ef2afc6d,--BCARD KeyB From ef2fc5b66c37cbc6661cfdbb1f58d2346be5ace9 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 1 Mar 2019 12:09:35 +0100 Subject: [PATCH 309/320] fix: 'hw tune' - reset demodplot line and grid clock --- client/cmddata.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/cmddata.c b/client/cmddata.c index 7e037c2e6..ba3d61156 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1495,6 +1495,13 @@ int CmdTuneSamples(const char *Cmd) { #define HF_UNUSABLE_V 3000 #define HF_MARGINAL_V 5000 #define ANTENNA_ERROR 1.03 // current algo has 3% error margin. + + // hide demod plot line + DemodBufferLen = 0; + setClockGrid(0, 0); + RepaintGraphWindow(); + + int timeout = 0; PrintAndLogEx(INFO, "\nmeasuring antenna characteristics, please wait..."); @@ -1575,6 +1582,7 @@ int CmdTuneSamples(const char *Cmd) { PrintAndLogEx(FAILED, "\nNot showing LF tuning graph since all values is zero.\n\n"); } + return 0; } From 4d79ced1a9bbeb282664efa622089243be144410 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 18:49:53 +0200 Subject: [PATCH 310/320] =?UTF-8?q?=D0=B0=D1=88=D1=87=D1=83=D1=8B=20=D1=88?= =?UTF-8?q?=D1=82=20=D1=8C=D1=84=D0=B2=D1=8E=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/mifare/mad.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 9f28de394..3973116b4 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -101,7 +101,7 @@ static const char *GetAIDDescription(uint16_t AID) { return madKnownAIDs[i].Description; for(int i = 0; i < ARRAYLEN(madKnownClusterCodes); i++) - if (madKnownClusterCodes[i].AID == AID) + if (madKnownClusterCodes[i].AID == (AID >> 8)) // high byte - cluster code return madKnownClusterCodes[i].Description; return unknownAID; @@ -175,6 +175,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { if (InfoByte == 0x10 || InfoByte >= 0x28) PrintAndLogEx(WARNING, "Info byte error"); + PrintAndLogEx(NORMAL, "00 MAD1"); for(int i = 1; i < 16; i++) { uint16_t AID = madGetAID(sector, 1, i); PrintAndLogEx(NORMAL, "%02d [%04X] %s", i, AID, GetAIDDescription(AID)); @@ -184,15 +185,19 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { }; int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { + PrintAndLogEx(NORMAL, "16 MAD2"); + int res = madCRCCheck(sector, true, 2); if (res) return res; - for(int i = 1; i < 8 + 8 + 7; i++) { + uint8_t InfoByte = sector[1] & 0x3f; + PrintAndLogEx(NORMAL, "MAD2 Card publisher sector: 0x%02x", InfoByte); + + for(int i = 1; i < 8 + 8 + 7 + 1; i++) { uint16_t AID = madGetAID(sector, 2, i); - PrintAndLogEx(NORMAL, "%02d [%04X] %s", i + 15, AID, GetAIDDescription(AID)); - }; - + PrintAndLogEx(NORMAL, "%02d [%04X] %s", i + 16, AID, GetAIDDescription(AID)); + }; return 0; }; From 6208a6869cdb21b9b4d7330d4b1e0179a72389b8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 18:50:25 +0200 Subject: [PATCH 311/320] added mad decode for mfp --- client/cmdhfmfp.c | 108 ++++++++++++++++++++++++++++++++++ client/mifare/mifaredefault.h | 1 + 2 files changed, 109 insertions(+) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 0917728be..bcbe323a9 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -23,6 +23,7 @@ #include "cmdhf14a.h" #include "mifare.h" #include "mifare/mifare4.h" +#include "mifare/mad.h" #include "cliparser/cliparser.h" #include "crypto/libpcrypto.h" @@ -733,6 +734,112 @@ int CmdHFMFPWrbl(const char *cmd) { return 0; } +int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose){ + uint8_t keyn[2] = {0}; + bool plain = false; + + uint16_t uKeyNum = 0x4000 + sectorNo * 2 + (keyType ? 1 : 0); + keyn[0] = uKeyNum >> 8; + keyn[1] = uKeyNum & 0xff; + if (verbose) + PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); + + mf4Session session; + int res = MifareAuth4(&session, keyn, key, true, true, verbose); + if (res) { + PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); + return res; + } + + uint8_t data[250] = {0}; + int datalen = 0; + uint8_t mac[8] = {0}; + uint8_t firstBlockNo = mfFirstBlockOfSector(sectorNo); + for(int n = firstBlockNo; n < firstBlockNo + mfNumBlocksPerSector(sectorNo); n++) { + res = MFPReadBlock(&session, plain, n & 0xff, 1, false, true, data, sizeof(data), &datalen, mac); + if (res) { + PrintAndLogEx(ERR, "Sector %d read error: %d", sectorNo, res); + DropField(); + return res; + } + + if (datalen && data[0] != 0x90) { + PrintAndLogEx(ERR, "Sector %d card read error: %02x %s", sectorNo, data[0], GetErrorDescription(data[0])); + DropField(); + return 5; + } + if (datalen != 1 + 16 + 8 + 2) { + PrintAndLogEx(ERR, "Sector %d error returned data length:%d", sectorNo, datalen); + DropField(); + return 6; + } + + memcpy(&dataout[(n - firstBlockNo) * 16], &data[1], 16); + + if (verbose) + PrintAndLogEx(INFO, "data[%03d]: %s", n, sprint_hex(&data[1], 16)); + + if (memcmp(&data[1 + 16], mac, 8)) { + PrintAndLogEx(WARNING, "WARNING: mac on block %d not equal...", n); + PrintAndLogEx(WARNING, "MAC card: %s", sprint_hex(&data[1 + 16], 8)); + PrintAndLogEx(WARNING, "MAC reader: %s", sprint_hex(mac, 8)); + + if (!verbose) + return 7; + } else { + if(verbose) + PrintAndLogEx(INFO, "MAC: %s", sprint_hex(&data[1 + 16], 8)); + } + } + DropField(); + + return 0; +} + +int CmdHFMFPMAD(const char *cmd) { + + CLIParserInit("hf mfp mad", + "Checks and prints Mifare Application Directory (MAD)", + "Usage:\n\thf mfp mad -> shows MAD if exists\n"); + + void* argtable[] = { + arg_param_begin, + arg_lit0("vV", "verbose", "show technical data"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + bool verbose = arg_get_lit(1); + + CLIParserFree(); + + uint8_t sector[16 * 4] = {0}; + if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector, verbose)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + return 2; + } + + if (verbose) { + for(int i = 0; i < 4; i ++) + PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or[i * 16], 16)); + } + + bool haveMAD2 = false; + MAD1DecodeAndPrint(sector, verbose, &haveMAD2); + + if (haveMAD2) { + if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector, verbose)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); + return 2; + } + + MAD2DecodeAndPrint(sector, verbose); + } + + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, @@ -744,6 +851,7 @@ static command_t CommandTable[] = {"rdbl", CmdHFMFPRdbl, 0, "Read blocks"}, {"rdsc", CmdHFMFPRdsc, 0, "Read sectors"}, {"wrbl", CmdHFMFPWrbl, 0, "Write blocks"}, + {"mad", CmdHFMFPMAD, 0, "Checks and prints MAD"}, {NULL, NULL, 0, NULL} }; diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index db9c0329d..e7218cbe7 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -44,5 +44,6 @@ static const uint64_t g_mifare_default_keys[] = static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; +static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; #endif From 5cc4bea4e3f44a322902ab4f3553a8490508804b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 19:05:51 +0200 Subject: [PATCH 312/320] mfp refactoring --- client/cmdhfmfp.c | 181 +++------------------------------------- client/mifare/mifare4.c | 157 ++++++++++++++++++++++++++++++++++ client/mifare/mifare4.h | 9 ++ 3 files changed, 178 insertions(+), 169 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index bcbe323a9..43c8d645d 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -29,103 +29,8 @@ static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -typedef struct { - uint8_t Code; - const char *Description; -} PlusErrorsElm; - -static const PlusErrorsElm PlusErrors[] = { - {0xFF, ""}, - {0x00, "Transfer cannot be granted within the current authentication."}, - {0x06, "Access Conditions not fulfilled. Block does not exist, block is not a value block."}, - {0x07, "Too many read or write commands in the session or in the transaction."}, - {0x08, "Invalid MAC in command or response"}, - {0x09, "Block Number is not valid"}, - {0x0a, "Invalid block number, not existing block number"}, - {0x0b, "The current command code not available at the current card state."}, - {0x0c, "Length error"}, - {0x0f, "General Manipulation Error. Failure in the operation of the PICC (cannot write to the data block), etc."}, - {0x90, "OK"}, -}; -int PlusErrorsLen = sizeof(PlusErrors) / sizeof(PlusErrorsElm); - -const char * GetErrorDescription(uint8_t errorCode) { - for(int i = 0; i < PlusErrorsLen; i++) - if (errorCode == PlusErrors[i].Code) - return PlusErrors[i].Description; - - return PlusErrors[0].Description; -} - static int CmdHelp(const char *Cmd); -static bool VerboseMode = false; -void SetVerboseMode(bool verbose) { - VerboseMode = verbose; -} - -int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { - if(VerboseMode) - PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen)); - - int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); - - if(VerboseMode) - PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen)); - - return res; -} - -int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { - uint8_t rcmd[3 + 16] = {0xa8, keyNum[1], keyNum[0], 0x00}; - memmove(&rcmd[3], key, 16); - - return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); -} - -int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { - uint8_t rcmd[1] = {0xaa}; - - return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); -} - -int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { - uint8_t rcmd[4 + 8] = {(plain?(0x37):(0x33)), blockNum, 0x00, blockCount}; - if (!plain && session) - CalculateMAC(session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); - - int res = intExchangeRAW14aPlus(rcmd, plain?4:sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); - if(res) - return res; - - if (session) - session->R_Ctr++; - - if(session && mac && *dataoutlen > 11) - CalculateMAC(session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, VerboseMode); - - return 0; -} - -int MFPWriteBlock(mf4Session *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { - uint8_t rcmd[1 + 2 + 16 + 8] = {0xA3, blockNum, 0x00}; - memmove(&rcmd[3], data, 16); - if (session) - CalculateMAC(session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], VerboseMode); - - int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); - if(res) - return res; - - if (session) - session->W_Ctr++; - - if(session && mac && *dataoutlen > 3) - CalculateMAC(session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, VerboseMode); - - return 0; -} - int CmdHFMFPInfo(const char *cmd) { if (cmd && strlen(cmd) > 0) @@ -230,7 +135,7 @@ int CmdHFMFPWritePerso(const char *cmd) { CLIGetHexWithReturn(3, key, &keyLen); CLIParserFree(); - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); if (!keyLen) { memmove(key, DefaultKey, 16); @@ -261,7 +166,7 @@ int CmdHFMFPWritePerso(const char *cmd) { } if (data[0] != 0x90) { - PrintAndLogEx(ERR, "Command error: %02x %s", data[0], GetErrorDescription(data[0])); + PrintAndLogEx(ERR, "Command error: %02x %s", data[0], mfpGetErrorDescription(data[0])); return 1; } PrintAndLogEx(INFO, "Write OK."); @@ -305,7 +210,7 @@ int CmdHFMFPInitPerso(const char *cmd) { if (!keyLen) memmove(key, DefaultKey, 16); - SetVerboseMode(verbose2); + mfpSetVerboseMode(verbose2); for (uint16_t sn = 0x4000; sn < 0x4050; sn++) { keyNum[0] = sn >> 8; keyNum[1] = sn & 0xff; @@ -320,7 +225,7 @@ int CmdHFMFPInitPerso(const char *cmd) { } } - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); for (int i = 0; i < sizeof(CardAddresses) / 2; i++) { keyNum[0] = CardAddresses[i] >> 8; keyNum[1] = CardAddresses[i] & 0xff; @@ -361,7 +266,7 @@ int CmdHFMFPCommitPerso(const char *cmd) { bool verbose = arg_get_lit(1); CLIParserFree(); - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); uint8_t data[250] = {0}; int datalen = 0; @@ -378,7 +283,7 @@ int CmdHFMFPCommitPerso(const char *cmd) { } if (data[0] != 0x90) { - PrintAndLogEx(ERR, "Command error: %02x %s", data[0], GetErrorDescription(data[0])); + PrintAndLogEx(ERR, "Command error: %02x %s", data[0], mfpGetErrorDescription(data[0])); return 1; } PrintAndLogEx(INFO, "Switch level OK."); @@ -454,7 +359,7 @@ int CmdHFMFPRdbl(const char *cmd) { CLIGetHexWithReturn(6, key, &keylen); CLIParserFree(); - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); if (!keylen) { memmove(key, DefaultKey, 16); @@ -505,7 +410,7 @@ int CmdHFMFPRdbl(const char *cmd) { } if (datalen && data[0] != 0x90) { - PrintAndLogEx(ERR, "Card read error: %02x %s", data[0], GetErrorDescription(data[0])); + PrintAndLogEx(ERR, "Card read error: %02x %s", data[0], mfpGetErrorDescription(data[0])); return 6; } @@ -564,7 +469,7 @@ int CmdHFMFPRdsc(const char *cmd) { CLIGetHexWithReturn(5, key, &keylen); CLIParserFree(); - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); if (!keylen) { memmove(key, DefaultKey, 16); @@ -606,7 +511,7 @@ int CmdHFMFPRdsc(const char *cmd) { } if (datalen && data[0] != 0x90) { - PrintAndLogEx(ERR, "Card read error: %02x %s", data[0], GetErrorDescription(data[0])); + PrintAndLogEx(ERR, "Card read error: %02x %s", data[0], mfpGetErrorDescription(data[0])); DropField(); return 6; } @@ -662,7 +567,7 @@ int CmdHFMFPWrbl(const char *cmd) { CLIGetHexWithReturn(5, key, &keylen); CLIParserFree(); - SetVerboseMode(verbose); + mfpSetVerboseMode(verbose); if (!keylen) { memmove(key, DefaultKey, 16); @@ -715,7 +620,7 @@ int CmdHFMFPWrbl(const char *cmd) { } if (datalen && data[0] != 0x90) { - PrintAndLogEx(ERR, "Card write error: %02x %s", data[0], GetErrorDescription(data[0])); + PrintAndLogEx(ERR, "Card write error: %02x %s", data[0], mfpGetErrorDescription(data[0])); DropField(); return 6; } @@ -734,68 +639,6 @@ int CmdHFMFPWrbl(const char *cmd) { return 0; } -int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose){ - uint8_t keyn[2] = {0}; - bool plain = false; - - uint16_t uKeyNum = 0x4000 + sectorNo * 2 + (keyType ? 1 : 0); - keyn[0] = uKeyNum >> 8; - keyn[1] = uKeyNum & 0xff; - if (verbose) - PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); - - mf4Session session; - int res = MifareAuth4(&session, keyn, key, true, true, verbose); - if (res) { - PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); - return res; - } - - uint8_t data[250] = {0}; - int datalen = 0; - uint8_t mac[8] = {0}; - uint8_t firstBlockNo = mfFirstBlockOfSector(sectorNo); - for(int n = firstBlockNo; n < firstBlockNo + mfNumBlocksPerSector(sectorNo); n++) { - res = MFPReadBlock(&session, plain, n & 0xff, 1, false, true, data, sizeof(data), &datalen, mac); - if (res) { - PrintAndLogEx(ERR, "Sector %d read error: %d", sectorNo, res); - DropField(); - return res; - } - - if (datalen && data[0] != 0x90) { - PrintAndLogEx(ERR, "Sector %d card read error: %02x %s", sectorNo, data[0], GetErrorDescription(data[0])); - DropField(); - return 5; - } - if (datalen != 1 + 16 + 8 + 2) { - PrintAndLogEx(ERR, "Sector %d error returned data length:%d", sectorNo, datalen); - DropField(); - return 6; - } - - memcpy(&dataout[(n - firstBlockNo) * 16], &data[1], 16); - - if (verbose) - PrintAndLogEx(INFO, "data[%03d]: %s", n, sprint_hex(&data[1], 16)); - - if (memcmp(&data[1 + 16], mac, 8)) { - PrintAndLogEx(WARNING, "WARNING: mac on block %d not equal...", n); - PrintAndLogEx(WARNING, "MAC card: %s", sprint_hex(&data[1 + 16], 8)); - PrintAndLogEx(WARNING, "MAC reader: %s", sprint_hex(mac, 8)); - - if (!verbose) - return 7; - } else { - if(verbose) - PrintAndLogEx(INFO, "MAC: %s", sprint_hex(&data[1 + 16], 8)); - } - } - DropField(); - - return 0; -} - int CmdHFMFPMAD(const char *cmd) { CLIParserInit("hf mfp mad", diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 0c53a1f9b..3fe67077f 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -17,6 +17,39 @@ #include "ui.h" #include "crypto/libpcrypto.h" +static bool VerboseMode = false; +void mfpSetVerboseMode(bool verbose) { + VerboseMode = verbose; +} + +typedef struct { + uint8_t Code; + const char *Description; +} PlusErrorsElm; + +static const PlusErrorsElm PlusErrors[] = { + {0xFF, ""}, + {0x00, "Transfer cannot be granted within the current authentication."}, + {0x06, "Access Conditions not fulfilled. Block does not exist, block is not a value block."}, + {0x07, "Too many read or write commands in the session or in the transaction."}, + {0x08, "Invalid MAC in command or response"}, + {0x09, "Block Number is not valid"}, + {0x0a, "Invalid block number, not existing block number"}, + {0x0b, "The current command code not available at the current card state."}, + {0x0c, "Length error"}, + {0x0f, "General Manipulation Error. Failure in the operation of the PICC (cannot write to the data block), etc."}, + {0x90, "OK"}, +}; +int PlusErrorsLen = sizeof(PlusErrors) / sizeof(PlusErrorsElm); + +const char * mfpGetErrorDescription(uint8_t errorCode) { + for(int i = 0; i < PlusErrorsLen; i++) + if (errorCode == PlusErrors[i].Code) + return PlusErrors[i].Description; + + return PlusErrors[0].Description; +} + AccessConditions_t MFAccessConditions[] = { {0x00, "rdAB wrAB incAB dectrAB"}, {0x01, "rdAB dectrAB"}, @@ -274,6 +307,130 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF return 0; } +int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + if(VerboseMode) + PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen)); + + int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); + + if(VerboseMode) + PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen)); + + return res; +} + +int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + uint8_t rcmd[3 + 16] = {0xa8, keyNum[1], keyNum[0], 0x00}; + memmove(&rcmd[3], key, 16); + + return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); +} + +int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + uint8_t rcmd[1] = {0xaa}; + + return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); +} + +int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { + uint8_t rcmd[4 + 8] = {(plain?(0x37):(0x33)), blockNum, 0x00, blockCount}; + if (!plain && session) + CalculateMAC(session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); + + int res = intExchangeRAW14aPlus(rcmd, plain?4:sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); + if(res) + return res; + + if (session) + session->R_Ctr++; + + if(session && mac && *dataoutlen > 11) + CalculateMAC(session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, VerboseMode); + + return 0; +} + +int MFPWriteBlock(mf4Session *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { + uint8_t rcmd[1 + 2 + 16 + 8] = {0xA3, blockNum, 0x00}; + memmove(&rcmd[3], data, 16); + if (session) + CalculateMAC(session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], VerboseMode); + + int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); + if(res) + return res; + + if (session) + session->W_Ctr++; + + if(session && mac && *dataoutlen > 3) + CalculateMAC(session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, VerboseMode); + + return 0; +} + +int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose){ + uint8_t keyn[2] = {0}; + bool plain = false; + + uint16_t uKeyNum = 0x4000 + sectorNo * 2 + (keyType ? 1 : 0); + keyn[0] = uKeyNum >> 8; + keyn[1] = uKeyNum & 0xff; + if (verbose) + PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); + + mf4Session session; + int res = MifareAuth4(&session, keyn, key, true, true, verbose); + if (res) { + PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); + return res; + } + + uint8_t data[250] = {0}; + int datalen = 0; + uint8_t mac[8] = {0}; + uint8_t firstBlockNo = mfFirstBlockOfSector(sectorNo); + for(int n = firstBlockNo; n < firstBlockNo + mfNumBlocksPerSector(sectorNo); n++) { + res = MFPReadBlock(&session, plain, n & 0xff, 1, false, true, data, sizeof(data), &datalen, mac); + if (res) { + PrintAndLogEx(ERR, "Sector %d read error: %d", sectorNo, res); + DropField(); + return res; + } + + if (datalen && data[0] != 0x90) { + PrintAndLogEx(ERR, "Sector %d card read error: %02x %s", sectorNo, data[0], mfpGetErrorDescription(data[0])); + DropField(); + return 5; + } + if (datalen != 1 + 16 + 8 + 2) { + PrintAndLogEx(ERR, "Sector %d error returned data length:%d", sectorNo, datalen); + DropField(); + return 6; + } + + memcpy(&dataout[(n - firstBlockNo) * 16], &data[1], 16); + + if (verbose) + PrintAndLogEx(INFO, "data[%03d]: %s", n, sprint_hex(&data[1], 16)); + + if (memcmp(&data[1 + 16], mac, 8)) { + PrintAndLogEx(WARNING, "WARNING: mac on block %d not equal...", n); + PrintAndLogEx(WARNING, "MAC card: %s", sprint_hex(&data[1 + 16], 8)); + PrintAndLogEx(WARNING, "MAC reader: %s", sprint_hex(mac, 8)); + + if (!verbose) + return 7; + } else { + if(verbose) + PrintAndLogEx(INFO, "MAC: %s", sprint_hex(&data[1 + 16], 8)); + } + } + DropField(); + + return 0; +} + // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), // plus evtl. 8 sectors with 16 blocks each (4k cards) uint8_t mfNumBlocksPerSector(uint8_t sectorNo) { diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 011567a1e..e4bf6e386 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -43,9 +43,18 @@ typedef struct { char *description; } AccessConditions_t; +extern void mfpSetVerboseMode(bool verbose); +extern const char * mfpGetErrorDescription(uint8_t errorCode); + extern int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); extern int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose); +extern int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +extern int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +extern int MFPReadBlock(mf4Session *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +extern int MFPWriteBlock(mf4Session *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +extern int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); + extern char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data); extern uint8_t mfNumBlocksPerSector(uint8_t sectorNo); From 979aa678ad7c70ea62541bf2019e060f359f23ae Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 19:07:34 +0200 Subject: [PATCH 313/320] small fix --- client/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a7966bee8..eea26f170 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3230,8 +3230,8 @@ int CmdHF14AMfMAD(const char *cmd) { bool haveMAD2 = false; MAD1DecodeAndPrint(sector, verbose, &haveMAD2); - if (haveMAD2) { // MF_MAD2_SECTOR - if (mfReadSector(1, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { + if (haveMAD2) { + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); return 2; } From 3a98c9fcd32cf9b4c6c10705d25df46fe7b57061 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 19:13:59 +0200 Subject: [PATCH 314/320] fix mad2 crc8 check --- client/mifare/mad.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/mifare/mad.c b/client/mifare/mad.c index 3973116b4..ff6991f22 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -109,13 +109,19 @@ static const char *GetAIDDescription(uint16_t AID) { int madCRCCheck(uint8_t *sector, bool verbose, int MADver) { if (MADver == 1) { - uint8_t crc = CRC8Mad(§or[16 + 1], 31); + uint8_t crc = CRC8Mad(§or[16 + 1], 15 + 16); if (crc != sector[16]) { if (verbose) PrintAndLogEx(ERR, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); return 3; }; } else { + uint8_t crc = CRC8Mad(§or[1], 15 + 16 + 16); + if (crc != sector[0]) { + if (verbose) + PrintAndLogEx(ERR, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); + return 3; + }; } return 0; @@ -191,6 +197,9 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { if (res) return res; + if (verbose) + PrintAndLogEx(NORMAL, "CRC8-MAD OK."); + uint8_t InfoByte = sector[1] & 0x3f; PrintAndLogEx(NORMAL, "MAD2 Card publisher sector: 0x%02x", InfoByte); From e8c0a49d076519b37f05cbe0f0c1d0a3dd91ceb2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 1 Mar 2019 19:39:17 +0200 Subject: [PATCH 315/320] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 673b25f8b..a99c8c522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf emv` `gpo`, `readrec`, `genac`, `challenge`, `intauth` - separate commands from `hf emc exec` (@merlokk) - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (@merlokk) - Added trailer block decoding to `hf mf rdbl` and `hf mf cgetbl` (@merlokk) + - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) ### Fixed - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (piwi) From dcdb2ee2182325a9f9652acc30a19853d24d53d8 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 1 Mar 2019 19:24:02 +0100 Subject: [PATCH 316/320] fix: 'script run ndef_dump.lua' - move function --- client/scripts/ndef_dump.lua | 37 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index a0eda5b7f..f1bf70ddd 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -66,8 +66,6 @@ local utils = { end, } - - --- -- Usage help local function help() @@ -83,6 +81,24 @@ local function debug(...) end +--- This function is a lua-implementation of +-- cmdhf14a.c:waitCmd(uint8_t iSelect) +local function waitCmd(iSelect) + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) + if response then + local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) + + local iLen = arg0 + if iSelect then iLen = arg1 end + debug(("Received %i octets (arg0:%d, arg1:%d)"):format(iLen, arg0, arg1)) + if iLen == 0 then return nil, "No response from tag" end + local recv = string.sub(response,count, iLen+count-1) + return recv + end + return nil, "No response from device" +end + + local function show(data) if DEBUG then local formatString = ("H%d"):format(string.len(data)) @@ -156,23 +172,6 @@ local function getBlock(block) end ---- This function is a lua-implementation of --- cmdhf14a.c:waitCmd(uint8_t iSelect) -local function waitCmd(iSelect) - local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) - if response then - local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) - - local iLen = arg0 - if iSelect then iLen = arg1 end - debug(("Received %i octets (arg0:%d, arg1:%d)"):format(iLen, arg0, arg1)) - if iLen == 0 then return nil, "No response from tag" end - local recv = string.sub(response,count, iLen+count-1) - return recv - end - return nil, "No response from device" -end - local function main( args) From 2c07bb790c2469cdc9a9577d21c4194717877e04 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Mar 2019 19:18:44 +0200 Subject: [PATCH 317/320] `hf mfp mad` read contents by aid --- client/cmdhfmfp.c | 64 ++++++++++++++++++++++++++---- client/mifare/mad.c | 73 ++++++++++++++++++++++++++++++----- client/mifare/mad.h | 6 ++- client/mifare/mifaredefault.h | 5 ++- 4 files changed, 128 insertions(+), 20 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 43c8d645d..e6363d64c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -643,20 +643,38 @@ int CmdHFMFPMAD(const char *cmd) { CLIParserInit("hf mfp mad", "Checks and prints Mifare Application Directory (MAD)", - "Usage:\n\thf mfp mad -> shows MAD if exists\n"); + "Usage:\n\thf mfp mad -> shows MAD if exists\n" + "\thf mfp mad -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n"); void* argtable[] = { arg_param_begin, arg_lit0("vV", "verbose", "show technical data"), + arg_str0("aA", "aid", "print all sectors with aid", NULL), + arg_str0("kK", "key", "key for printing sectors", NULL), + arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); + bool verbose = arg_get_lit(1); + uint8_t aid[2] = {0}; + int aidlen; + CLIGetHexWithReturn(2, aid, &aidlen); + uint8_t key[16] = {0}; + int keylen; + CLIGetHexWithReturn(3, key, &keylen); + bool keyB = arg_get_lit(4); CLIParserFree(); + + if (aidlen != 2 && keylen > 0) { + PrintAndLogEx(WARNING, "do not need a key without aid."); + } - uint8_t sector[16 * 4] = {0}; - if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector, verbose)) { + uint8_t sector0[16 * 4] = {0}; + uint8_t sector10[16 * 4] = {0}; + + if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); return 2; @@ -664,20 +682,52 @@ int CmdHFMFPMAD(const char *cmd) { if (verbose) { for(int i = 0; i < 4; i ++) - PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or[i * 16], 16)); + PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); } bool haveMAD2 = false; - MAD1DecodeAndPrint(sector, verbose, &haveMAD2); + MAD1DecodeAndPrint(sector0, verbose, &haveMAD2); if (haveMAD2) { - if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector, verbose)) { + if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); return 2; } - MAD2DecodeAndPrint(sector, verbose); + MAD2DecodeAndPrint(sector10, verbose); + } + + if (aidlen == 2) { + uint16_t aaid = (aid[0] << 8) + aid[1]; + PrintAndLogEx(NORMAL, "\n-------------- AID 0x%04x ---------------", aaid); + + uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; + size_t madlen = 0; + if (MADDecode(sector0, sector10, mad, &madlen)) { + PrintAndLogEx(ERR, "can't decode mad."); + return 10; + } + + uint8_t akey[16] = {0}; + memcpy(akey, g_mifarep_ndef_key, 16); + if (keylen == 16) { + memcpy(akey, key, 16); + } + + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + uint8_t vsector[16 * 4] = {0}; + if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector, false)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "read sector %d error.", i + 1); + return 2; + } + + for(int j = 0; j < (verbose ? 4 : 3); j ++) + PrintAndLogEx(NORMAL, "---[%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + } + } } return 0; diff --git a/client/mifare/mad.c b/client/mifare/mad.c index ff6991f22..34ea50cfc 100644 --- a/client/mifare/mad.c +++ b/client/mifare/mad.c @@ -134,10 +134,13 @@ uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) { return (sector[2 + (sectorNo - 1) * 2] << 8) + (sector[2 + (sectorNo - 1) * 2 + 1]); } -int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { +int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) { + if (!sector0) + return 1; - uint8_t GPB = sector[3 * 16 + 9]; - PrintAndLogEx(NORMAL, "GPB: 0x%02x", GPB); + uint8_t GPB = sector0[3 * 16 + 9]; + if (verbose) + PrintAndLogEx(NORMAL, "GPB: 0x%02x", GPB); // DA (MAD available) if (!(GPB & 0x80)) { @@ -146,13 +149,16 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { } // MA (multi-application card) - if (GPB & 0x40) - PrintAndLogEx(NORMAL, "Multi application card."); - else - PrintAndLogEx(NORMAL, "Single application card."); + if (verbose) { + if (GPB & 0x40) + PrintAndLogEx(NORMAL, "Multi application card."); + else + PrintAndLogEx(NORMAL, "Single application card."); + } uint8_t MADVer = GPB & 0x03; - PrintAndLogEx(NORMAL, "MAD version: %d", MADVer); + if (verbose) + PrintAndLogEx(NORMAL, "MAD version: %d", MADVer); // MAD version if ((MADVer != 0x01) && (MADVer != 0x02)) { @@ -163,7 +169,56 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { if (haveMAD2) *haveMAD2 = (MADVer == 2); - int res = madCRCCheck(sector, true, 1); + int res = madCRCCheck(sector0, true, 1); + if (res) + return res; + + if (verbose) + PrintAndLogEx(NORMAL, "CRC8-MAD1 OK."); + + if (MADVer == 2 && sector10) { + int res = madCRCCheck(sector10, true, 2); + if (res) + return res; + + if (verbose) + PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); + } + + return 0; +} + +int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen) { + *madlen = 0; + bool haveMAD2 = false; + int res = MADCheck(sector0, sector10, false, &haveMAD2); + if (res) + return res; + + for (int i = 1; i < 16; i++) { + mad[*madlen] = madGetAID(sector0, 1, i); + (*madlen)++; + } + + if (haveMAD2) { + // mad2 sector (0x10 == 16dec) here + mad[*madlen] = 0x0005; + (*madlen)++; + + for (int i = 1; i < 24; i++) { + mad[*madlen] = madGetAID(sector10, 2, i); + (*madlen)++; + } + } + + return 0; +} + + +int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { + + // check MAD1 only + int res = MADCheck(sector, NULL, verbose, haveMAD2); if (res) return res; diff --git a/client/mifare/mad.h b/client/mifare/mad.h index dc2b2e3c0..ee362adb6 100644 --- a/client/mifare/mad.h +++ b/client/mifare/mad.h @@ -19,8 +19,10 @@ typedef struct { const char *Description; } madAIDDescr; -int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2); -int MAD2DecodeAndPrint(uint8_t *sector, bool verbose); +extern int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2); +extern int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen); +extern int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2); +extern int MAD2DecodeAndPrint(uint8_t *sector, bool verbose); #endif // _MAD_H_ diff --git a/client/mifare/mifaredefault.h b/client/mifare/mifaredefault.h index e7218cbe7..b12a57c03 100644 --- a/client/mifare/mifaredefault.h +++ b/client/mifare/mifaredefault.h @@ -42,8 +42,9 @@ static const uint64_t g_mifare_default_keys[] = 0x96a301bce267 }; -static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; +static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; -static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; +static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; +static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; #endif From f45c330843546a271f3b089368771f7bb54ed47e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Mar 2019 19:25:13 +0200 Subject: [PATCH 318/320] small visual fixes --- client/cmdhfmfp.c | 2 +- client/mifare/mifare4.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index e6363d64c..725dbca04 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -725,7 +725,7 @@ int CmdHFMFPMAD(const char *cmd) { } for(int j = 0; j < (verbose ? 4 : 3); j ++) - PrintAndLogEx(NORMAL, "---[%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); } } } diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 3fe67077f..c95529a84 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -302,7 +302,8 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF memmove(session->Kmac, kmac, 16); } - PrintAndLogEx(INFO, "Authentication OK"); + if (verbose) + PrintAndLogEx(INFO, "Authentication OK"); return 0; } From 9c8e60cf0338e0a07885b2830fd26052eaff32f2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Mar 2019 19:44:19 +0200 Subject: [PATCH 319/320] added to `hf mf mad` --- client/cmdhfmf.c | 62 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 6c6bc48e0..8823ea2d9 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3219,39 +3219,87 @@ int CmdHF14AMfMAD(const char *cmd) { CLIParserInit("hf mf mad", "Checks and prints Mifare Application Directory (MAD)", - "Usage:\n\thf mf mad -> shows MAD if exists\n"); + "Usage:\n\thf mf mad -> shows MAD if exists\n" + "\thf mf mad -a 03e1 -k d3f7d3f7d3f7 -> shows NDEF data if exists\n"); void* argtable[] = { arg_param_begin, arg_lit0("vV", "verbose", "show technical data"), + arg_str0("aA", "aid", "print all sectors with aid", NULL), + arg_str0("kK", "key", "key for printing sectors", NULL), + arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); bool verbose = arg_get_lit(1); + uint8_t aid[2] = {0}; + int aidlen; + CLIGetHexWithReturn(2, aid, &aidlen); + uint8_t key[6] = {0}; + int keylen; + CLIGetHexWithReturn(3, key, &keylen); + bool keyB = arg_get_lit(4); CLIParserFree(); - uint8_t sector[16 * 4] = {0}; - if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { + if (aidlen != 2 && keylen > 0) { + PrintAndLogEx(WARNING, "do not need a key without aid."); + } + + uint8_t sector0[16 * 4] = {0}; + uint8_t sector10[16 * 4] = {0}; + if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) { PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); return 2; } if (verbose) { for(int i = 0; i < 4; i ++) - PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or[i * 16], 16)); + PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); } bool haveMAD2 = false; - MAD1DecodeAndPrint(sector, verbose, &haveMAD2); + MAD1DecodeAndPrint(sector0, verbose, &haveMAD2); if (haveMAD2) { - if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector)) { + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); return 2; } - MAD2DecodeAndPrint(sector, verbose); + MAD2DecodeAndPrint(sector10, verbose); + } + + if (aidlen == 2) { + uint16_t aaid = (aid[0] << 8) + aid[1]; + PrintAndLogEx(NORMAL, "\n-------------- AID 0x%04x ---------------", aaid); + + uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; + size_t madlen = 0; + if (MADDecode(sector0, sector10, mad, &madlen)) { + PrintAndLogEx(ERR, "can't decode mad."); + return 10; + } + + uint8_t akey[6] = {0}; + memcpy(akey, g_mifare_ndef_key, 6); + if (keylen == 6) { + memcpy(akey, key, 6); + } + + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + uint8_t vsector[16 * 4] = {0}; + if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "read sector %d error.", i + 1); + return 2; + } + + for(int j = 0; j < (verbose ? 4 : 3); j ++) + PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + } + } } return 0; From 0944a12744e3e0d30aa5e38b3f4fa4bbe8b03c6e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 4 Mar 2019 20:27:52 +0100 Subject: [PATCH 320/320] Add missing header --- client/mifare/mad.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/mifare/mad.h b/client/mifare/mad.h index ee362adb6..6289982d9 100644 --- a/client/mifare/mad.h +++ b/client/mifare/mad.h @@ -13,6 +13,7 @@ #include #include +#include typedef struct { uint16_t AID;