Merge branch 'master' into sha

This commit is contained in:
Iceman 2022-02-25 11:42:20 +01:00 committed by GitHub
commit 1c6abece54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 726 additions and 278 deletions

View file

@ -4,15 +4,17 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
- Added detection of a possible mismatch between client and Proxmark3 image (@doegox)
- Changed `hf mf nested`: removed option `--single` redundant with usage of `--tblk` (@doegox)
- Fixed `hf mf chk` single block mode (@doegox)
- Fixed `hf mf fchk/chk` internal logic to load keys (@doegox)
- Changed `hf mf *` printKeyTable: now display sector trailer info too (@doegox)
- Changed `hf mf chk` option `--blk` into `--tblk` (as for nested) (@doegox)
- Changed `hf 14a info` - added a ATR historical compact TLV decoder (@iceman1001)
- Added `hf mf value` - decode a value block (@iceman1001)
- Changed `hf mf nested` - removed option `--single` redundant with usage of `--tblk` (@doegox)
- Fixed `hf mf chk` - single block mode (@doegox)
- Fixed `hf mf fchk/chk` - internal logic to load keys (@doegox)
- Changed `hf mf *` - printKeyTable: now display sector trailer info too (@doegox)
- Changed `hf mf chk` - option `--blk` into `--tblk` (as for nested) (@doegox)
- Added new tool `mfd_multi_brute` - MIFARE DESfire / UL-C key recovery (@iceman1001)
- Fixed `hf emrtd info` segfault on some platforms (@doegox)
- Fixed `hf emrtd info` when offline (@doegox)
- Fixed `commands.json` generation (@doegox)
- Fixed `hf emrtd info` - segfault on some platforms (@doegox)
- Fixed `hf emrtd info` - when offline (@doegox)
- Fixed `commands.json` - generation (@doegox)
- Added new standalone mode `hf_legicsim` (@uhei)
- Changed `hf legic *` - now uses NG instead (@iceman1001)
- Added `hf legic view` - view contents of LEGIC Prime dump files (@iceman1001)
@ -34,8 +36,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added `nfc decode` - now NDEF vCard messages with a PHOTO in base64 format is shown (@iceman1001)
- Changed - AID limitations when using Gallagher key diversification (@DarkMatterMatt)
- Added new standalone mode `lf_em4100rsww` (@zabszk)
- Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz)
## [Frostbit.4.14831] [2022-01-11]
## [Frostbit.4.14831][2022-01-11]
- Changed Wiegand format lookup - now case-insensitive (@iceman1001)
- Added new standalone mode `hf_15SNIFF` - Same as `hf_14ASNIFF` standalone mode for RDV4 - flashmem (@startrk1995)
- Added `hf gallagher` commands for read/writing DESFire cards (@DarkMatterMatt)

View file

@ -252,7 +252,7 @@ static int reader_attack_mode(void) {
bool success = (mac_response_len == MAC_RESPONSES_SIZE);
uint8_t num_mac = (mac_response_len >> 4);
Dbprintf("%u out of %d MAC obtained [%s]", num_mac, NUM_CSNS, (success) ? _GREEN_("ok") : _RED_("fail"));
Dbprintf("%u out of %d MAC obtained ( %s )", num_mac, NUM_CSNS, (success) ? _GREEN_("ok") : _RED_("fail"));
size_t dumplen = NUM_CSNS * 24;

View file

@ -1272,6 +1272,14 @@ static void PacketReceived(PacketCommandNG *packet) {
DisablePrivacySlixLIso15693(payload->pwd);
break;
}
case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: {
struct p {
uint8_t pwd[4];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
DisableEAS_AFISlixLIso15693(payload->pwd);
break;
}
#endif

View file

@ -864,7 +864,7 @@ void SimulateIso14443bTag(uint8_t *pupi) {
}
} else {
if (g_dbglevel >= DBG_DEBUG) {
DbpString("CRC passed");
DbpString("CRC ok");
}
}
cardSTATE = SIM_IDLE;
@ -1064,7 +1064,7 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
}
} else {
if (g_dbglevel >= DBG_DEBUG) {
DbpString("CRC passed");
DbpString("CRC ok");
}
}
cardSTATE = SIM_IDLE;

View file

@ -1589,9 +1589,9 @@ static void DbdecodeIso15693Answer(int len, uint8_t *d) {
}
if (CheckCrc15(d, len))
strncat(status, "[+] crc (" _GREEN_("OK") ")", DBD15STATLEN - strlen(status));
strncat(status, "[+] crc ( " _GREEN_("ok") " )", DBD15STATLEN - strlen(status));
else
strncat(status, "[!] crc (" _RED_("fail") ")", DBD15STATLEN - strlen(status));
strncat(status, "[!] crc ( " _RED_("fail") " )", DBD15STATLEN - strlen(status));
if (g_dbglevel >= DBG_ERROR) Dbprintf("%s", status);
}
@ -2248,15 +2248,36 @@ static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uin
}
*/
// Sets a PRIVACY password to all ZEROS
void DisablePrivacySlixLIso15693(uint8_t *password) {
LED_D_ON();
Iso15693InitReader();
StartCountSspClk();
uint32_t start_time = 0, eof_time = 0;
// 4 == pass id.
int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password);
// Password identifier Password byte
// 0x04 Privacy
// 0x08 Destroy SLIX-L
// 0x10 EAS/AFI
int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password);
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0);
switch_off();
}
// Sets a EAS/AFI password to all ZEROS
void DisableEAS_AFISlixLIso15693(uint8_t *password) {
LED_D_ON();
Iso15693InitReader();
StartCountSspClk();
uint32_t start_time = 0, eof_time = 0;
// Password identifier Password byte
// 0x04 Privacy
// 0x08 Destroy SLIX-L
// 0x10 EAS/AFI
int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password);
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0);
switch_off();
}

View file

@ -60,4 +60,5 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
void SetTag15693Uid(const uint8_t *uid);
void DisablePrivacySlixLIso15693(uint8_t *password);
void DisableEAS_AFISlixLIso15693(uint8_t *password);
#endif

View file

@ -17,16 +17,15 @@
//-----------------------------------------------------------------------------
#include "cipursecore.h"
#include <string.h> // memcpy memset
#include "commonutil.h" // ARRAYLEN
#include "comms.h" // DropField
#include "util_posix.h" // msleep
#include <string.h> // memcpy memset
#include "cmdhf14a.h"
#include "emv/emvcore.h"
#include "emv/emvjson.h"
#include "iso7816/apduinfo.h"
#include "../emv/emvcore.h"
#include "../emv/emvjson.h"
#include "../iso7816/apduinfo.h" // sAPDU_t
#include "ui.h"
#include "util.h"
@ -299,21 +298,24 @@ void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, Cipurs
static void CIPURSEPrintPersoMode(uint8_t data) {
if ((data & 0x01) == 0x01)
PrintAndLogEx(INFO, "Perso... " _YELLOW_("filesystem"));
PrintAndLogEx(INFO, "Perso.......... " _YELLOW_("filesystem"));
if ((data & 0x02) == 0x02)
PrintAndLogEx(INFO, "Perso... " _YELLOW_("EMV"));
PrintAndLogEx(INFO, "Perso.......... " _YELLOW_("EMV"));
if ((data & 0x04) == 0x04)
PrintAndLogEx(INFO, "Perso... " _YELLOW_("transaction supported"));
PrintAndLogEx(INFO, "Perso.......... " _YELLOW_("transaction supported"));
}
// 2021 iceman: what is the description text of profile L,S,T ?
static void CIPURSEPrintProfileInfo(uint8_t data) {
PrintAndLogEx(INFO, "Profile........" NOLF);
if ((data & 0x01) == 0x01)
PrintAndLogEx(INFO, "Profile... L");
PrintAndLogEx(NORMAL, " L" NOLF);
if ((data & 0x02) == 0x02)
PrintAndLogEx(INFO, "Profile... S");
PrintAndLogEx(NORMAL, ", S" NOLF);
if ((data & 0x04) == 0x04)
PrintAndLogEx(INFO, "Profile... T");
PrintAndLogEx(NORMAL, ", T" NOLF);
PrintAndLogEx(NORMAL, "");
}
static void CIPURSEPrintManufacturerInfo(uint8_t data) {
@ -330,8 +332,7 @@ void CIPURSEPrintInfoFile(uint8_t *data, size_t len) {
}
PrintAndLogEx(INFO, "--- " _CYAN_("CIPURSE Information") "---------------------");
PrintAndLogEx(INFO, "version.... " _YELLOW_("%d"), data[0]);
PrintAndLogEx(INFO, "revision... " _YELLOW_("%d"), data[1]);
PrintAndLogEx(INFO, "Version........ " _YELLOW_("v%d.%d"), data[0], data[1]);
if (len >= 3)
CIPURSEPrintPersoMode(data[2]);

View file

@ -22,7 +22,7 @@
#include <jansson.h>
#include <stdbool.h>
#include "common.h"
#include "iso7816/apduinfo.h" // sAPDU_t
#include "../iso7816/apduinfo.h" // sAPDU_t
#include "cipurse/cipursecrypto.h"

View file

@ -362,7 +362,7 @@ static bool TestAPDU(void) {
bool CIPURSETest(bool verbose) {
bool res = true;
PrintAndLogEx(INFO, "------ " _CYAN_("CIPURSE Tests") " ------");
PrintAndLogEx(INFO, "------ " _CYAN_("CIPURSE tests") " ------");
res = res && TestKVV();
res = res && TestISO9797M2();

View file

@ -1638,6 +1638,78 @@ static void getTagLabel(uint8_t uid0, uint8_t uid1) {
}
}
static void get_compact_tlv(uint8_t *d, uint8_t n) {
d++;
n--;
while (n > 0) {
uint8_t tag = NIBBLE_HIGH(d[0]);
uint8_t len = NIBBLE_LOW(d[0]);
switch (tag) {
case 1:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Country code in (ISO 3166-1)", tag, len, sprint_hex_inrow(d + 1, len));
// iso3166 script in cmdlffdb.c is buggy, Åland, Australia not showing. getline issues
break;
case 2:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Issuer identification number (ISO 7812-1)", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 3:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card service data byte", tag, len, sprint_hex_inrow(d + 1, len));
PrintAndLogEx(INFO, " %c....... Application selection: by full DF name", (d[1] & 0x80) ? '1' : '0');
PrintAndLogEx(INFO, " .%c...... Application selection: by partial DF name", (d[1] & 0x40) ? '1' : '0');
PrintAndLogEx(INFO, " ..%c..... BER-TLV data objects available in EF.DIR", (d[1] & 0x20) ? '1' : '0');
PrintAndLogEx(INFO, " ...%c.... BER-TLV data objects available in EF.ATR", (d[1] & 0x10) ? '1' : '0');
PrintAndLogEx(INFO, " ....%c... EF.DIR and EF.ATR access services: by READ BINARY command", (d[1] & 0x08) ? '1' : '0');
PrintAndLogEx(INFO, " .....%c.. EF.DIR and EF.ATR access services: by GET DATA command", (d[1] & 0x04) ? '1' : '0');
PrintAndLogEx(INFO, " ......%c. EF.DIR and EF.ATR access services: by GET RECORD(s) command", (d[1] & 0x02) ? '1' : '0');
PrintAndLogEx(INFO, " .......%c EF.DIR and EF.ATR access services: RFU", (d[1] & 0x01) ? '1' : '0');
break;
case 4:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Initial access data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 5:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card issuer data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 6:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Pre-issuing data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 7:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card capabilities", tag, len, sprint_hex_inrow(d + 1, len));
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Selection methods", d[1]);
PrintAndLogEx(INFO, " %c....... DF selection by full DF name", (d[1] & 0x80) ? '1' : '0');
PrintAndLogEx(INFO, " .%c...... DF selection by partial DF name", (d[1] & 0x40) ? '1' : '0');
PrintAndLogEx(INFO, " ..%c..... DF selection by path", (d[1] & 0x20) ? '1' : '0');
PrintAndLogEx(INFO, " ...%c.... DF selection by file identifier", (d[1] & 0x10) ? '1' : '0');
PrintAndLogEx(INFO, " ....%c... Implicit DF selection", (d[1] & 0x08) ? '1' : '0');
PrintAndLogEx(INFO, " .....%c.. Short EF identifier supported", (d[1] & 0x04) ? '1' : '0');
PrintAndLogEx(INFO, " ......%c. Record number supported", (d[1] & 0x02) ? '1' : '0');
PrintAndLogEx(INFO, " .......%c Record identifier supported", (d[1] & 0x01) ? '1' : '0');
if (len > 1) {
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Data coding byte", d[2]);
}
if (len > 2) {
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Command chaining, length fields and logical channels", d[3]);
}
break;
case 8:
PrintAndLogEx(INFO, " %1x%1x ... " _YELLOW_("%s") " Status indicator", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 0xE:
PrintAndLogEx(INFO, " %1x%1x ... " _YELLOW_("%s") " Application identifier", tag, len, sprint_hex_inrow(d + 1, len));
break;
}
if (len > n)
break;
n -= (1 + len);
d += (1 + len);
}
}
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
@ -2034,10 +2106,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
}
} else {
if (card.ats[pos] == 0x80)
PrintAndLogEx(SUCCESS, " %s (compact TLV data object)", sprint_hex_inrow(card.ats + pos, calen));
else
if (card.ats[pos] == 0x80 || card.ats[pos] == 0x00) {
PrintAndLogEx(SUCCESS, " %s (compact TLV data object)", sprint_hex_inrow(&card.ats[pos], calen));
get_compact_tlv(card.ats + pos, calen);
} else {
PrintAndLogEx(SUCCESS, " %s", sprint_hex_inrow(card.ats + pos, calen));
}
PrintAndLogEx(NORMAL, "");
}

View file

@ -191,7 +191,7 @@ static bool wait_cmd_14b(bool verbose, bool is_select, uint32_t timeout) {
bool crc = check_crc(CRC_14443_B, data, len);
PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len);
PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s",
PrintAndLogEx(SUCCESS, "%s[%02X %02X] ( %s )",
sprint_hex(data, len - 2),
data[len - 2],
data[len - 1],

View file

@ -83,9 +83,9 @@ static const APDUSpcCodeDescription_t UAPDpdateKeyAttrCodeDescriptions[] = {
static const APDUSpcCodeDescription_t UAPDpdateKeyCodeDescriptions[] = {
{0x6982, "Key is frozen or only the key itself has the rights to update" },
{0x6984, "key enc key is blocked or invalid" },
{0x6984, "Enc key is blocked or invalid" },
{0x6985, "Deactivated file" },
{0x6A80, "invalid algo, key length or kvv" },
{0x6A80, "Invalid algo, key length or kvv" },
{0x6A88, "Invalid key number (outside the range supported by the current DF)" }
};
@ -113,7 +113,11 @@ static int SelectAndPrintInfoFile(void) {
if (len > 0) {
PrintAndLogEx(INFO, "Info file ( " _GREEN_("ok") " )");
PrintAndLogEx(INFO, "[%zu]: %s", len, sprint_hex(buf, len));
PrintAndLogEx(INFO, " # | bytes | ascii");
PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(buf, len, 16);
PrintAndLogEx(NORMAL, "");
CIPURSEPrintInfoFile(buf, len);
PrintAndLogEx(INFO, "");
}
@ -149,7 +153,7 @@ static int CmdHFCipurseInfo(const char *Cmd) {
int res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw);
if (res == PM3_SUCCESS && sw == 0x9000) {
mfExist = true;
PrintAndLogEx(INFO, _CYAN_("MasterFile") " exist and can be selected.");
PrintAndLogEx(INFO, _YELLOW_("MasterFile") " exist and can be selected.");
res = SelectAndPrintInfoFile();
infoPrinted = (res == PM3_SUCCESS);
@ -173,7 +177,7 @@ static int CmdHFCipurseInfo(const char *Cmd) {
DropField();
return res;
}
PrintAndLogEx(INFO, "Application `AF F1` selected " _GREEN_("successfully"));
PrintAndLogEx(INFO, "Application `" _YELLOW_("AF F1") "` selected " _GREEN_("successfully"));
if (sw != 0x9000) {
if (sw == 0x0000) {
@ -365,7 +369,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s ") _GREEN_("OK"), sprint_hex_inrow(aid, aidLen));
PrintAndLogEx(INFO, "Cipurse select application " _YELLOW_("%s ") " ( %s )", sprint_hex_inrow(aid, aidLen), _GREEN_("ok"));
}
} else if (useFID) {
@ -373,12 +377,13 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
res = CIPURSESelectFileEx(true, true, fileId, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose) {
PrintAndLogEx(ERR, "Cipurse select file 0x%04x " _RED_("error") ". Card returns 0x%04x", fileId, *sw);
PrintAndLogEx(ERR, "Cipurse select file 0x%04x ( %s )", _RED_("fail"));
PrintAndLogEx(ERR, "Card returns 0x%04x", fileId, *sw);
}
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select file " _CYAN_("0x%04x ") _GREEN_("OK"), fileId);
PrintAndLogEx(INFO, "Cipurse select file " _YELLOW_("0x%04X ") " ( " _GREEN_("ok") " )", fileId);
}
} else if (selectDefaultFile) {
@ -391,7 +396,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select default file " _GREEN_("OK"));
PrintAndLogEx(INFO, "Cipurse select default file ( " _GREEN_("ok") " )");
}
} else {
@ -404,7 +409,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select default application " _GREEN_("OK"));
PrintAndLogEx(INFO, "Cipurse select default application ( " _GREEN_("ok") " )");
}
}
@ -421,7 +426,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Select child file " _CYAN_("0x%04x ") _GREEN_("OK"), childFileId);
PrintAndLogEx(INFO, "Select child file " _CYAN_("0x%04x ") " ( " _GREEN_("ok") " )", childFileId);
}
}
@ -566,10 +571,7 @@ static int CmdHFCipurseAuth(const char *Cmd) {
bool bres = CIPURSEChannelAuthenticate(keyId, key, verbose);
if (verbose == false) {
if (bres)
PrintAndLogEx(INFO, "Authentication ( " _GREEN_("ok") " )");
else
PrintAndLogEx(ERR, "Authentication ( " _RED_("fail") " )");
PrintAndLogEx(INFO, "Authentication ( %s ) ", (bres) ? _GREEN_("ok") : _RED_("fail"));
}
DropField();
@ -640,7 +642,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) {
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s") " ( " _GREEN_("ok") " )", sprint_hex_inrow(aid, aidLen));
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s") " ( %s )", sprint_hex_inrow(aid, aidLen), _GREEN_("ok"));
PrintAndLogEx(INFO, "File id " _YELLOW_("%x") " offset " _YELLOW_("%zu") " key id " _YELLOW_("%d") " key " _YELLOW_("%s"), fileId, offset, keyId, sprint_hex(key, CIPURSE_AES_KEY_LENGTH));
}
@ -666,7 +668,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) {
}
if (verbose)
PrintAndLogEx(INFO, "Select file 0x%x ( " _GREEN_("ok") " )", fileId);
PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok"));
res = CIPURSEReadBinary(offset, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
@ -704,8 +706,8 @@ static int CmdHFCipurseWriteFile(const char *Cmd) {
arg_str0(NULL, "fid", "<hex>", "File ID"),
arg_int0("o", "offset", "<dec>", "Offset for reading data from file"),
arg_lit0(NULL, "noauth", "Read file without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "communication PICC-reader security level (def: mac)"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_str0("d", "data", "<hex>", "Data to write to new file"),
arg_lit0(NULL, "commit", "Commit after write"),
arg_param_end
@ -763,14 +765,14 @@ static int CmdHFCipurseWriteFile(const char *Cmd) {
}
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s") " ( " _GREEN_("ok") " )", sprint_hex_inrow(aid, aidLen));
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s") " ( %s )", sprint_hex_inrow(aid, aidLen), _GREEN_("ok"));
PrintAndLogEx(INFO, "File id " _YELLOW_("%x") " offset " _YELLOW_("%zu") " key id " _YELLOW_("%d") " key " _YELLOW_("%s")
, fileId
, offset
, keyId
, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)
);
PrintAndLogEx(INFO, "data[%d]: %s", hdatalen, sprint_hex(hdata, hdatalen));
PrintAndLogEx(INFO, "Data [%d]: %s", hdatalen, sprint_hex(hdata, hdatalen));
}
if (noAuth == false) {
@ -795,7 +797,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) {
}
if (verbose)
PrintAndLogEx(INFO, "Select file 0x%x ( " _GREEN_("ok") " )", fileId);
PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok"));
res = CIPURSEUpdateBinary(offset, hdata, hdatalen, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
@ -811,7 +813,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
@ -1009,7 +1011,7 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) {
SetAPDULogging(APDULogging);
if (verbose) {
PrintAndLogEx(INFO, "attribtes data[%d]: %s", hdatalen, sprint_hex(hdata, hdatalen));
PrintAndLogEx(INFO, "Attribtes data[%d]: %s", hdatalen, sprint_hex(hdata, hdatalen));
CIPURSEPrintFileUpdateAttr(hdata, hdatalen);
}
@ -1069,7 +1071,7 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
@ -1180,7 +1182,7 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) {
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "file ID (FID) ( 2 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID (FID) ( 2 bytes )"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_str0("d", "data", "<hex>", "Data with DGI for create"),
@ -1255,7 +1257,7 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) {
if (verbose) {
if (!noauth)
PrintAndLogEx(INFO, "key id " _YELLOW_("%d") " key " _YELLOW_("%s")
PrintAndLogEx(INFO, "Key id " _YELLOW_("%d") " key " _YELLOW_("%s")
, keyId
, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)
);
@ -1276,7 +1278,8 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) {
res = CIPURSECreateFile(hdata, hdatalen, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Create file command " _RED_("ERROR") ". Card returns:\n 0x%04x - %s", sw,
PrintAndLogEx(ERR, "Create file command " _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s", sw,
GetSpecificAPDUCodeDesc(SelectAPDUCodeDescriptions, ARRAYLEN(SelectAPDUCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
@ -1287,10 +1290,10 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
}
DropField();
@ -1361,7 +1364,7 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) {
PrintAndLogEx(INFO, "Child file id " _CYAN_("%x"), childFileId);
if (!noauth)
PrintAndLogEx(INFO, "key id " _YELLOW_("%d") " key " _YELLOW_("%s")
PrintAndLogEx(INFO, "Key id " _YELLOW_("%d") " key " _YELLOW_("%s")
, keyId
, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)
);
@ -1403,7 +1406,8 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) {
if (useChildFID) {
res = CIPURSEDeleteFile(childFileId, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Delete child file " _CYAN_("%04x ") _RED_("ERROR") ". Card returns:\n 0x%04x - %s", childFileId, sw,
PrintAndLogEx(ERR, "Delete child file " _CYAN_("%04x ") _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s", childFileId, sw,
GetSpecificAPDUCodeDesc(DeleteAPDUCodeDescriptions, ARRAYLEN(DeleteAPDUCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
@ -1412,7 +1416,8 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) {
} else if (useFID) {
res = CIPURSEDeleteFile(fileId, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Delete file " _CYAN_("%04x ") _RED_("ERROR") ". Card returns:\n 0x%04x - %s", fileId, sw,
PrintAndLogEx(ERR, "Delete file " _CYAN_("%04x ") _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s", fileId, sw,
GetSpecificAPDUCodeDesc(DeleteAPDUCodeDescriptions, ARRAYLEN(DeleteAPDUCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
@ -1421,24 +1426,25 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) {
} else {
res = CIPURSEDeleteFileAID(aid, aidLen, buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Delete application " _CYAN_("%s ") _RED_("ERROR") ". Card returns:\n 0x%04x - %s",
PrintAndLogEx(ERR, "Delete application " _CYAN_("%s ") _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s",
sprint_hex_inrow(aid, aidLen),
sw,
GetSpecificAPDUCodeDesc(DeleteAPDUCodeDescriptions, ARRAYLEN(DeleteAPDUCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
}
PrintAndLogEx(INFO, "Delete application " _CYAN_("%s ") _GREEN_("OK"), sprint_hex_inrow(aid, aidLen));
PrintAndLogEx(INFO, "Delete application " _CYAN_("%s") " ( %s )", sprint_hex_inrow(aid, aidLen), _GREEN_("ok"));
}
if (needCommit) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
}
DropField();
@ -1454,26 +1460,26 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID for authentication"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Show technical data"),
arg_int0("n", NULL, "<dec>", "Key ID for authentication"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "file ID (FID)"),
arg_lit0(NULL, "mfd", "select masterfile by empty id"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "Application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "File ID (FID)"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_int0(NULL, "newkeyn", "<dec>", "target key ID"),
arg_str0(NULL, "newkey", "<hex 16 byte>", "new key"),
arg_str0(NULL, "newkeya", "<hex 1 byte>", "new key additional info. 0x00 by default"),
arg_int0(NULL, "newkeyn", "<dec>", "Target key ID"),
arg_str0(NULL, "newkey", "<hex 16 byte>", "New key"),
arg_str0(NULL, "newkeya", "<hex 1 byte>", "New key additional info (def: 0x00)"),
arg_int0(NULL, "enckeyn", "<dec>", "encrypt key ID (must be equal to the key on the card)"),
arg_str0(NULL, "enckey", "<hex 16 byte>", "encrypt key (must be equal to the key on the card)"),
arg_int0(NULL, "enckeyn", "<dec>", "Encrypt key ID (must be equal to the key on the card)"),
arg_str0(NULL, "enckey", "<hex 16 byte>", "Encrypt key (must be equal to the key on the card)"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_lit0(NULL, "commit", "commit "),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "Communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "Communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "Execute without authentication"),
arg_lit0(NULL, "commit", "Commit "),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1596,7 +1602,7 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
if (verbose) {
if (!noauth)
PrintAndLogEx(INFO, "key id " _YELLOW_("%d") " key " _YELLOW_("%s")
PrintAndLogEx(INFO, "Key id " _YELLOW_("%d") " key " _YELLOW_("%s")
, keyId
, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)
);
@ -1617,7 +1623,8 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
res = CIPURSEUpdateKey(encKeyId, newKeyId, keydata, sizeof(keydata), buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Update key command " _RED_("ERROR") ". Card returns:\n 0x%04x - %s", sw,
PrintAndLogEx(ERR, "Update key command " _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s", sw,
GetSpecificAPDUCodeDesc(UAPDpdateKeyCodeDescriptions, ARRAYLEN(UAPDpdateKeyCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
@ -1628,10 +1635,10 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
}
DropField();
@ -1651,21 +1658,21 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID for authentication"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Show technical data"),
arg_int0("n", NULL, "<dec>", "Key ID for authentication"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "file ID (FID)"),
arg_lit0(NULL, "mfd", "select masterfile by empty id"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "Application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "File ID (FID)"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_int0(NULL, "trgkeyn", "<dec>", "target key ID"),
arg_str0(NULL, "attr", "<hex 1 byte>", "key attributes 1 byte"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_lit0(NULL, "commit", "commit "),
arg_int0(NULL, "trgkeyn", "<dec>", "Target key ID"),
arg_str0(NULL, "attr", "<hex 1 byte>", "Key attributes 1 byte"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "Communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "Communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "Execute without authentication"),
arg_lit0(NULL, "commit", "Commit "),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1743,7 +1750,7 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) {
if (verbose) {
if (!noauth)
PrintAndLogEx(INFO, "key id " _YELLOW_("%d") " key " _YELLOW_("%s")
PrintAndLogEx(INFO, "Key id " _YELLOW_("%d") " key " _YELLOW_("%s")
, keyId
, sprint_hex(key, CIPURSE_AES_KEY_LENGTH)
);
@ -1764,7 +1771,8 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) {
res = CIPURSEUpdateKeyAttrib(trgKeyId, hdata[0], buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000) {
PrintAndLogEx(ERR, "Update key attributes command " _RED_("ERROR") ". Card returns:\n 0x%04x - %s", sw,
PrintAndLogEx(ERR, "Update key attributes command " _RED_("ERROR"));
PrintAndLogEx(ERR, "0x%04x - %s", sw,
GetSpecificAPDUCodeDesc(UAPDpdateKeyAttrCodeDescriptions, ARRAYLEN(UAPDpdateKeyAttrCodeDescriptions), sw));
DropField();
return PM3_ESOFT;
@ -1775,10 +1783,10 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) {
sw = 0;
res = CIPURSECommitTransaction(&sw);
if (res != 0 || sw != 0x9000)
PrintAndLogEx(WARNING, "Commit " _YELLOW_("ERROR") ". Card returns 0x%04x", sw);
PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw);
if (verbose)
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
}
DropField();
@ -1795,6 +1803,17 @@ bool CheckCardCipurse(void) {
}
static int CmdHFCipurseTest(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf cipurse test",
"Regression tests",
"hf cipurse test");
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
CIPURSETest(true);
return PM3_SUCCESS;
}
@ -1877,7 +1896,7 @@ static command_t CommandTable[] = {
{"updkey", CmdHFCipurseUpdateKey, IfPm3Iso14443a, "Update key"},
{"updakey", CmdHFCipurseUpdateKeyAttr, IfPm3Iso14443a, "Update key attributes"},
{"default", CmdHFCipurseDefault, IfPm3Iso14443a, "Set default key and file id for all the other commands"},
{"test", CmdHFCipurseTest, AlwaysAvailable, "Tests"},
{"test", CmdHFCipurseTest, AlwaysAvailable, "Regression tests"},
{NULL, NULL, 0, NULL}
};

View file

@ -1817,7 +1817,7 @@ static int emrtd_parse_ef_sod_hashes(uint8_t *data, size_t datalen, uint8_t *has
return PM3_SUCCESS;
}
static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_sod, int hash_algo) {
static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_sod, int hash_algo, bool fastdump) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "-------------------- " _CYAN_("EF_SOD") " --------------------");
@ -1835,7 +1835,11 @@ static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_s
if (calc_all_zero == true && sod_all_zero == true) {
continue;
} else if (calc_all_zero == true) {
if (fastdump && !dg_table[i].fastdump && !dg_table[i].pace && !dg_table[i].eac) {
PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File was skipped, but is in EF_SOD."), i);
} else {
PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File couldn't be read, but is in EF_SOD."), i);
}
} else if (sod_all_zero == true) {
PrintAndLogEx(SUCCESS, "EF_DG%i: " _YELLOW_("File is not in EF_SOD."), i);
} else if (hash_matches == false) {
@ -2010,7 +2014,7 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab
}
DropField();
emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo);
emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo, true);
return PM3_SUCCESS;
}
@ -2110,7 +2114,7 @@ int infoHF_EMRTD_offline(const char *path) {
}
free(filepath);
emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo);
emrtd_print_ef_sod_info(*dg_hashes_calc, *dg_hashes_sod, hash_algo, false);
return PM3_SUCCESS;
}

View file

@ -110,11 +110,11 @@ static int CmdLegicInfo(const char *Cmd) {
PrintAndLogEx(SUCCESS, " " _CYAN_("CDF: System Area"));
PrintAndLogEx(NORMAL, "------------------------------------------------------");
PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " (%s)",
PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " ( %s )",
data[0],
sprint_hex(data + 1, 3),
data[4],
(calc_crc == crc) ? _GREEN_("OK") : _RED_("Fail")
(calc_crc == crc) ? _GREEN_("ok") : _RED_("fail")
);
// MCD = Manufacturer ID (should be list meaning something?)
@ -265,12 +265,12 @@ static int CmdLegicInfo(const char *Cmd) {
(segment_flag & 0x4) >> 2,
(segment_flag & 0x8) >> 3
);
PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)",
PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X ( %s )",
wrp,
wrc,
((data[i + 3] ^ crc) & 0x80) >> 7,
segCRC,
(segCRC == segCalcCRC) ? _GREEN_("OK") : _RED_("Fail")
(segCRC == segCalcCRC) ? _GREEN_("ok") : _RED_("fail")
);
i += 5;

View file

@ -48,11 +48,6 @@
#define MIFARE_2K_MAXSECTOR 32
#define MIFARE_4K_MAXSECTOR 40
/* On some platforms, max() may already be defined */
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
static int CmdHelp(const char *Cmd);
/*
@ -1243,7 +1238,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't
if (singleSector) {
uint8_t MinSectorsCnt = 0;
// find a MIFARE type that can accommodate the provided block number
uint8_t s = max(mfSectorNum(trgBlockNo), mfSectorNum(blockNo));
uint8_t s = MAX(mfSectorNum(trgBlockNo), mfSectorNum(blockNo));
if (s < MIFARE_MINI_MAXSECTOR) {
MinSectorsCnt = MIFARE_MINI_MAXSECTOR;
} else if (s < MIFARE_1K_MAXSECTOR) {
@ -5286,7 +5281,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
PrintAndLogEx(WARNING, "error, read sector 0. card doesn't have MAD or doesn't have MAD on default keys");
got_first = false;
} else {
PrintAndLogEx(INFO, "Authentication ( " _GREEN_("OK") " )");
PrintAndLogEx(INFO, "Authentication ( " _GREEN_("ok") " )");
}
// User supplied key
@ -5295,7 +5290,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, userkey, sector0) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "error, read sector 0. card doesn't have MAD or the custom key is wrong");
} else {
PrintAndLogEx(INFO, "Authentication ( " _GREEN_("OK") " )");
PrintAndLogEx(INFO, "Authentication ( " _GREEN_("ok") " )");
got_first = true;
}
}
@ -5770,7 +5765,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) {
DropField();
return res;
}
PrintAndLogEx(SUCCESS, "Super card reset [ " _GREEN_("ok") " ]");
PrintAndLogEx(SUCCESS, "Super card reset ( " _GREEN_("ok") " )");
return PM3_SUCCESS;
}
@ -6206,6 +6201,54 @@ static int CmdHF14AGen4View(const char *Cmd) {
return PM3_SUCCESS;
}
static bool mfc_value(const uint8_t *d, uint32_t *val) {
// values
uint32_t a = MemLeToUint4byte(d);
uint32_t a_inv = MemLeToUint4byte(d + 4);
uint32_t b = MemLeToUint4byte(d + 8);
int val_checks = (
(a == b) && (a == ~a_inv) &&
(d[12] == (~d[13] & 0xFF)) &&
(d[14] == (~d[15] & 0xFF))
);
if (val) {
*val = a;
}
return (val_checks);
}
static int CmdHF14AMfValue(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf value",
"Decode of a MIFARE value block",
"hf mf value -d 87D612007829EDFF87D6120011EE11EE\n"
);
void *argtable[] = {
arg_param_begin,
arg_str1("d", "data", "<hex>", "16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int dlen = 0;
uint8_t data[16] = {0};
CLIGetHexWithReturn(ctx, 1, data, &dlen);
CLIParserFree(ctx);
uint32_t value = 0;
if (mfc_value(data, &value)) {
PrintAndLogEx(SUCCESS, "Dec... " _YELLOW_("%" PRIu32), value);
PrintAndLogEx(SUCCESS, "Hex... " _YELLOW_("0x%" PRIX32), value);
} else {
PrintAndLogEx(FAILED, "No value block detected");
}
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"},
@ -6232,6 +6275,7 @@ static command_t CommandTable[] = {
{"rdsc", CmdHF14AMfRdSc, IfPm3Iso14443a, "Read MIFARE Classic sector"},
{"restore", CmdHF14AMfRestore, IfPm3Iso14443a, "Restore MIFARE Classic binary file to BLANK tag"},
{"setmod", CmdHf14AMfSetMod, IfPm3Iso14443a, "Set MIFARE Classic EV1 load modulation strength"},
{"value", CmdHF14AMfValue, AlwaysAvailable, "Decode a value block"},
{"view", CmdHF14AMfView, AlwaysAvailable, "Display content from tag dump file"},
{"wipe", CmdHF14AMfWipe, IfPm3Iso14443a, "Wipe card to zeros and default keys/acc"},
{"wrbl", CmdHF14AMfWrBl, IfPm3Iso14443a, "Write MIFARE Classic block"},

View file

@ -247,6 +247,8 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV1") " )", major, minor);
else if (major == 0x12 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
else if (major == 0x22 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
else if (major == 0x42 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
else if (major == 0x33 && minor == 0x00)
@ -280,6 +282,10 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) {
return DESFIRE_EV1;
if (major == 0x12 && minor == 0x00)
return DESFIRE_EV2;
if (major == 0x22 && minor == 0x00)
return DESFIRE_EV2;
if (major == 0x42 && minor == 0x00)
return DESFIRE_EV2;
if (major == 0x33 && minor == 0x00)
return DESFIRE_EV3;
if (major == 0x30 && minor == 0x00)
@ -2182,15 +2188,15 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
PrintAndLogEx(FAILED, "Select or authentication ( %s )" _RED_("failed") " Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
return res;
}
res = DesfireSetConfiguration(&dctx, paramid, param, paramlen);
if (res == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Set configuration 0x%02x " _GREEN_("ok") " ", paramid);
PrintAndLogEx(SUCCESS, "Set configuration 0x%02x ( %s )", _GREEN_("ok"), paramid);
} else {
PrintAndLogEx(FAILED, "Set configuration 0x%02x " _RED_("failed") " ", paramid);
PrintAndLogEx(FAILED, "Set configuration 0x%02x ( %s )", _RED_("failed"), paramid);
}
DropField();
@ -2326,9 +2332,9 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
DesfireSetCommMode(&dctx, DCMEncryptedPlain);
res = DesfireChangeKey(&dctx, (DesfireMFSelected(selectway, id)) && (newkeynum == 0) && (dctx.keyNum == 0), newkeynum, newkeytype, newkeyver, newkey, oldkeytype, oldkey, true);
if (res == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Change key " _GREEN_("ok") " ");
PrintAndLogEx(SUCCESS, "Change key ( " _GREEN_("ok") " )");
} else {
PrintAndLogEx(FAILED, "Change key " _RED_("failed") " ");
PrintAndLogEx(FAILED, "Change key ( " _RED_("failed") " )");
}
DesfireSetCommMode(&dctx, DCMEncrypted);
@ -4298,7 +4304,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, noauth, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
PrintAndLogEx(FAILED, "Select or authentication ( %s )" _RED_("failed") " Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
return res;
}
@ -4308,12 +4314,12 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
if (op != 0xff) {
res = DesfireValueFileOperations(&dctx, fileid, op, &value);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire ValueFileOperations (0x%02x) command " _RED_("error") ". Result: %d", op, res);
PrintAndLogEx(ERR, "Desfire ValueFileOperations (0x%02x) command ( " _RED_("error") " ) Result: %d", op, res);
DropField();
return PM3_ESOFT;
}
if (verbose)
PrintAndLogEx(INFO, "Operation %s " _GREEN_("OK"), CLIGetOptionListStr(DesfireValueFileOperOpts, op));
PrintAndLogEx(INFO, "Operation ( %s )" _GREEN_("ok"), CLIGetOptionListStr(DesfireValueFileOperOpts, op));
if (op == MFDES_GET_VALUE) {
PrintAndLogEx(SUCCESS, "Value: " _GREEN_("%d (0x%08x)"), value, value);
@ -4321,19 +4327,19 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
DesfireSetCommMode(&dctx, DCMMACed);
res = DesfireCommitTransaction(&dctx, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire CommitTransaction command " _RED_("error") ". Result: %d", res);
PrintAndLogEx(ERR, "Desfire CommitTransaction command ( " _RED_("error") ") Result: %d", res);
DropField();
return PM3_ESOFT;
}
if (verbose)
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
PrintAndLogEx(SUCCESS, "Value changed " _GREEN_("successfully"));
}
} else {
res = DesfireValueFileOperations(&dctx, fileid, MFDES_GET_VALUE, &value);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire GetValue command " _RED_("error") ". Result: %d", res);
PrintAndLogEx(ERR, "Desfire GetValue command ( " _RED_("error") ") Result: %d", res);
DropField();
return PM3_ESOFT;
}
@ -4345,7 +4351,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
res = DesfireGetFileSettings(&dctx, fileid, buf, &buflen);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire GetFileSettings command " _RED_("error") ". Result: %d", res);
PrintAndLogEx(ERR, "Desfire GetFileSettings command ( " _RED_("error") " ) Result: %d", res);
DropField();
return PM3_ESOFT;
}
@ -4369,7 +4375,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
if (delta > 0) {
res = DesfireValueFileOperations(&dctx, fileid, MFDES_DEBIT, &delta);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire Debit operation " _RED_("error") ". Result: %d", res);
PrintAndLogEx(ERR, "Desfire Debit operation ( " _RED_("error") " ) Result: %d", res);
DropField();
return PM3_ESOFT;
}
@ -4380,7 +4386,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
DesfireSetCommMode(&dctx, DCMMACed);
res = DesfireCommitTransaction(&dctx, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire CommitTransaction command " _RED_("error") ". Result: %d", res);
PrintAndLogEx(ERR, "Desfire CommitTransaction command ( " _RED_("error") " ) Result: %d", res);
DropField();
return PM3_ESOFT;
}
@ -5194,7 +5200,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
readeridpushed = true;
if (verbose)
PrintAndLogEx(INFO, "CommitReaderID " _GREEN_("OK"));
PrintAndLogEx(INFO, "CommitReaderID ( " _GREEN_("ok") " )");
} else
PrintAndLogEx(WARNING, "Desfire CommitReaderID command " _RED_("error") ". Result: %d", res);
}
@ -5281,7 +5287,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
if (verbose) {
if (readeridpushed)
PrintAndLogEx(INFO, "TMC and TMV[%zu]: %s", resplen, sprint_hex(resp, resplen));
PrintAndLogEx(INFO, "Commit " _GREEN_("OK"));
PrintAndLogEx(INFO, "Commit ( " _GREEN_("ok") " )");
}
if (resplen == 4 + 8) {
@ -5555,6 +5561,17 @@ static int CmdHF14ADesDump(const char *Cmd) {
}
static int CmdHF14ADesTest(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes test",
"Regression crypto tests",
"hf mfdes test");
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
DesfireTest(true);
return PM3_SUCCESS;
}
@ -5603,7 +5620,7 @@ static command_t CommandTable[] = {
{"value", CmdHF14ADesValueOperations, IfPm3Iso14443a, "Operations with value file (get/credit/limited credit/debit/clear)"},
{"clearrecfile", CmdHF14ADesClearRecordFile, IfPm3Iso14443a, "Clear record File"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("System") " -----------------------"},
{"test", CmdHF14ADesTest, AlwaysAvailable, "Test crypto"},
{"test", CmdHF14ADesTest, AlwaysAvailable, "Regression crypto tests"},
{NULL, NULL, NULL, NULL}
};

View file

@ -3815,7 +3815,7 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
, poststr
, pre_tear
, post_tear
, post_tear_check ? _GREEN_("OK") : _RED_("DETECTED")
, post_tear_check ? _GREEN_("ok") : _RED_("DETECTED")
);
break;
}
@ -3826,7 +3826,7 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
, poststr
, pre_tear
, post_tear
, post_tear_check ? _GREEN_("OK") : _RED_("DETECTED")
, post_tear_check ? _GREEN_("ok") : _RED_("DETECTED")
);
@ -3860,7 +3860,7 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
, poststr
, pre_tear
, post_tear
, post_tear_check ? _GREEN_("OK") : _RED_("DETECTED")
, post_tear_check ? _GREEN_("ok") : _RED_("DETECTED")
);
if ( post_tear_check && b == initial_value) {
@ -3908,7 +3908,7 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
, poststr
, pre_tear
, post_tear
, post_tear_check ? _GREEN_("OK") : _RED_("DETECTED")
, post_tear_check ? _GREEN_("ok") : _RED_("DETECTED")
);
if ( post_tear_check ) {

View file

@ -47,11 +47,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")" - %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")" ( %s )", b2, b1, (isok) ? _GREEN_("ok") : _RED_("fail"));
} else {
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")" - " _RED_("fail"));
}
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%zu")" - %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning"));
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%zu")" ( %s )", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("ok") : _YELLOW_("warning"));
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
if (barcode_len < 4) // too few to go to next decoding stages
return PM3_ESOFT;

View file

@ -804,7 +804,7 @@ static int CmdPing(const char *Cmd) {
if (WaitForResponseTimeout(CMD_PING, &resp, 1000)) {
if (len) {
bool error = (memcmp(data, resp.data.asBytes, len) != 0);
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") " and content is %s", error ? _RED_("NOT ok") : _GREEN_("OK"));
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") " and content () %s )", error ? _RED_("fail") : _GREEN_("ok"));
} else {
PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received"));
}

View file

@ -871,7 +871,7 @@ int CmdEM4x05Wipe(const char *Cmd) {
arg_lit0(NULL, "4205", "target chip type EM 4205"),
arg_lit0(NULL, "4305", "target chip type EM 4305 (default)"),
arg_lit0(NULL, "4369", "target chip type EM 4369"),
arg_lit0(NULL, "4369", "target chip type EM 4469"),
arg_lit0(NULL, "4469", "target chip type EM 4469"),
arg_str0("p", "pwd", "<hex>", "optional - password, 4 bytes hex"),
arg_param_end
};

View file

@ -359,9 +359,9 @@ int CmdEM4x50Login(const char *Cmd) {
// print response
if (resp.status == PM3_SUCCESS)
PrintAndLogEx(SUCCESS, "Login " _GREEN_("ok"));
PrintAndLogEx(SUCCESS, "Login ( " _GREEN_("ok") " )");
else
PrintAndLogEx(FAILED, "Login " _RED_("failed"));
PrintAndLogEx(FAILED, "Login ( " _RED_("failed") " )");
return resp.status;
}
@ -966,7 +966,7 @@ int CmdEM4x50WritePwd(const char *Cmd) {
return PM3_EFAILED;
}
PrintAndLogEx(SUCCESS, "Writing new password %s (%s)"
PrintAndLogEx(SUCCESS, "Writing new password %s ( %s )"
, sprint_hex_inrow(npwd, sizeof(npwd))
, _GREEN_("ok")
);
@ -1015,9 +1015,9 @@ int CmdEM4x50Wipe(const char *Cmd) {
}
if (resp.status == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Resetting password to 00000000 (" _GREEN_("ok") ")");
PrintAndLogEx(SUCCESS, "Resetting password to 00000000 ( " _GREEN_("ok") " )");
} else {
PrintAndLogEx(FAILED, "Resetting password " _RED_("failed"));
PrintAndLogEx(FAILED, "Resetting password ( " _RED_("failed") " )");
return PM3_ESOFT;
}

View file

@ -208,7 +208,7 @@ static int CmdFDXBdemodBI(const char *Cmd) {
PrintAndLogEx(SUCCESS, "Reserved/RFU: %u", 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: 0x%04X - [%04X] - %s", crc_16, calcCrc, (calcCrc == crc_16) ? _GREEN_("Passed") : _RED_("Fail") );
PrintAndLogEx(SUCCESS, "CRC: 0x%04X - [%04X] - %s", crc_16, calcCrc, (calcCrc == crc_16) ? _GREEN_("ok") : _RED_("fail") );
if (g_debugMode) {
PrintAndLogEx(DEBUG, "Start marker %d; Size %d", preambleIndex, size);
@ -581,7 +581,7 @@ int demodFDXB(bool verbose) {
uint8_t c[] = {0, 0};
compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]);
PrintAndLogEx(SUCCESS, "CRC-16 0x%04X (%s)", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("ok") : _RED_("fail"));
PrintAndLogEx(SUCCESS, "CRC-16 0x%04X ( %s )", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("ok") : _RED_("fail"));
// iceman: crc doesn't protect the extended data?
PrintAndLogEx(SUCCESS, "Raw " _GREEN_("%s"), sprint_hex(raw, 8));

View file

@ -140,9 +140,9 @@ int demodIOProx(bool verbose) {
char crc_str[36] = {0};
if (crc == calccrc) {
snprintf(crc_str, sizeof(crc_str), "(" _GREEN_("ok") ")");
snprintf(crc_str, sizeof(crc_str), "( " _GREEN_("ok") " )");
} else {
snprintf(crc_str, sizeof(crc_str), "(" _RED_("fail") ") 0x%02X != 0x%02X", crc, calccrc);
snprintf(crc_str, sizeof(crc_str), "( " _RED_("fail") " ) 0x%02X != 0x%02X", crc, calccrc);
retval = PM3_ESOFT;
}

View file

@ -100,7 +100,7 @@ int demodJablotron(bool verbose) {
uint8_t chksum = raw2 & 0xFF;
bool isok = (chksum == jablontron_chksum(g_DemodBuffer));
PrintAndLogEx(DEBUG, "Checksum: %02X (%s)", chksum, isok ? _GREEN_("ok") : _RED_("Fail"));
PrintAndLogEx(DEBUG, "Checksum: %02X ( %s )", chksum, isok ? _GREEN_("ok") : _RED_("Fail"));
id = DEC2BCD(id);
// Printed format: 1410-nn-nnnn-nnnn

View file

@ -151,7 +151,7 @@ int demodNedap(bool verbose) {
, customerCode
, sprint_hex_inrow(data, size / 8)
);
PrintAndLogEx(DEBUG, "Checksum (%s) 0x%04X", _GREEN_("ok"), checksum);
PrintAndLogEx(DEBUG, "Checksum ( %s ) 0x%04X", _GREEN_("ok"), checksum);
} else {
PrintAndLogEx(ERR, "Invalid idx (1:%02x - 2:%02x - 3:%02x - 4:%02x - 5:%02x)", idxC1, idxC2, idxC3, idxC4, idxC5);

View file

@ -237,12 +237,12 @@ int demodNexWatch(bool verbose) {
if (parity == calc_parity) {
PrintAndLogEx(DEBUG, " parity : %s (0x%X)", _GREEN_("ok"), parity);
PrintAndLogEx(DEBUG, " parity : ( %s ) 0x%X", _GREEN_("ok"), parity);
} else {
PrintAndLogEx(DEBUG, " parity : %s (0x%X != 0x%X)", _RED_("fail"), parity, calc_parity);
PrintAndLogEx(DEBUG, " parity : ( %s ) 0x%X != 0x%X", _RED_("fail"), parity, calc_parity);
}
PrintAndLogEx(DEBUG, " checksum : %s (0x%02X)", (m_idx < ARRAYLEN(items)) ? _GREEN_("ok") : _RED_("fail"), chk);
PrintAndLogEx(DEBUG, " checksum : ( %s ) 0x%02X", (m_idx < ARRAYLEN(items)) ? _GREEN_("ok") : _RED_("fail"), chk);
PrintAndLogEx(INFO, " Raw : " _YELLOW_("%08"PRIX32"%08"PRIX32"%08"PRIX32), raw1, raw2, raw3);
return PM3_SUCCESS;

View file

@ -170,7 +170,7 @@ int demodPyramid(bool verbose) {
PrintAndLogEx(SUCCESS, "Pyramid - len: " _GREEN_("%d") " -unknown- Card: " _GREEN_("%d") ", Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
}
PrintAndLogEx(DEBUG, "DEBUG: Pyramid: checksum : 0x%02X - 0x%02X - %s"
PrintAndLogEx(DEBUG, "DEBUG: Pyramid: checksum : 0x%02X - 0x%02X ( %s )"
, checksum
, checkCS
, (checksum == checkCS) ? _GREEN_("ok") : _RED_("fail")

View file

@ -112,7 +112,7 @@ int demodSecurakey(bool verbose) {
PrintAndLogEx(SUCCESS, "Securakey - len: " _GREEN_("%u") " FC: " _GREEN_("0x%X")" Card: " _GREEN_("%u") ", Raw: %08X%08X%08X", bitLen, fc, cardid, raw1, raw2, raw3);
if (bitLen <= 32)
PrintAndLogEx(SUCCESS, "Wiegand: " _GREEN_("%08X") " parity (%s)", (lWiegand << (bitLen / 2)) | rWiegand, parity ? _GREEN_("ok") : _RED_("fail"));
PrintAndLogEx(SUCCESS, "Wiegand: " _GREEN_("%08X") " parity ( %s )", (lWiegand << (bitLen / 2)) | rWiegand, parity ? _GREEN_("ok") : _RED_("fail"));
if (verbose) {
PrintAndLogEx(INFO, "\nHow the FC translates to printed FC is unknown");

View file

@ -264,7 +264,7 @@ int demodTI(bool verbose) {
init_table(CRC_KERMIT);
uint16_t calccrc = crc16_kermit(raw, sizeof(raw));
const char *crc_str = (calccrc == (shift2 & 0xFFFF)) ? _GREEN_("ok") : _RED_("fail");
PrintAndLogEx(INFO, "Tag data = %08X%08X [%04X] (%s)", shift1, shift0, calccrc, crc_str);
PrintAndLogEx(INFO, "Tag data = %08X%08X [%04X] ( %s )", shift1, shift0, calccrc, crc_str);
if (calccrc != (shift2 & 0xFFFF))
PrintAndLogEx(WARNING, "Warning: CRC mismatch, calculated %04X, got %04X", calccrc, shift2 & 0xFFFF);

View file

@ -652,7 +652,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(INFO, "SDA verified (%s) (Data Authentication Code: %02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
PrintAndLogEx(INFO, "SDA verified ( %s ) (Data Authentication Code: %02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
tlvdb_add(tlv, dac_db);
} else {
emv_pk_free(issuer_pk);
@ -771,7 +771,7 @@ int trDDA(Iso7816CommandChannel 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(INFO, "SDAD verified (%s) (Data Authentication Code: %02hhx:%02hhx)\n", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
PrintAndLogEx(INFO, "SDAD verified ( %s ) (Data Authentication Code: %02hhx:%02hhx)\n", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
tlvdb_add(tlv, dac_db);
} else {
PrintAndLogEx(ERR, "Error: SSAD verify error");
@ -930,7 +930,7 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st
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(SUCCESS, "Signed Static Application Data (SSAD) verified (%s) (%02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
PrintAndLogEx(SUCCESS, "Signed Static Application Data (SSAD) verified ( %s ) (%02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]);
tlvdb_add(tlv, dac_db);
} else {
PrintAndLogEx(ERR, "Error: Signed Static Application Data (SSAD) verify error");
@ -950,7 +950,7 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st
if (idn_db) {
const struct tlv *idn_tlv = tlvdb_get(idn_db, 0x9f4c, NULL);
PrintAndLogEx(INFO, "IDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len));
PrintAndLogEx(SUCCESS, "CDA verified (%s)", _GREEN_("ok"));
PrintAndLogEx(SUCCESS, "CDA verified ( %s )", _GREEN_("ok"));
tlvdb_add(tlv, idn_db);
} else {
PrintAndLogEx(ERR, "ERROR: CDA verify error");

View file

@ -331,7 +331,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
return false;
}
PrintAndLogEx(SUCCESS, "Load params: json(%zu) (%s)", json_array_size(root), _GREEN_("OK"));
PrintAndLogEx(SUCCESS, "Load params: json(%zu) ( %s )", json_array_size(root), _GREEN_("ok"));
for (int i = 0; i < json_array_size(root); i++) {
json_t *data, *jtag, *jlength, *jvalue;

View file

@ -665,7 +665,7 @@ int flash_write(flash_file_t *ctx) {
}
fflush(stdout);
}
PrintAndLogEx(NORMAL, " " _GREEN_("OK"));
PrintAndLogEx(NORMAL, " " _GREEN_("ok"));
fflush(stdout);
}
return PM3_SUCCESS;

View file

@ -133,14 +133,18 @@ size_t DesfireGetMACLength(DesfireContext_t *ctx) {
size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen) {
size_t crcpos = datalen - 1;
while (crcpos > 0)
if (data[crcpos] == 0)
while (crcpos > 0) {
if (data[crcpos] == 0) {
crcpos--;
else
} else {
break;
}
}
crcpos++; // crc may be 0x00000000 or 0x0000
if (crcpos < crclen) {
PrintAndLogEx(WARNING, "No space for crc. pos: %zu", crcpos);
PrintAndLogEx(WARNING, "No space for crc. pos %zu", crcpos);
return 0;
}

View file

@ -54,9 +54,9 @@ static bool TestCRC16(void) {
res = res && (len == 0);
if (res)
PrintAndLogEx(INFO, "crc16............. " _GREEN_("passed"));
PrintAndLogEx(INFO, "CRC16............. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "crc16............. " _RED_("fail"));
PrintAndLogEx(ERR, "CRC16............. " _RED_("fail"));
return res;
}
@ -81,9 +81,9 @@ static bool TestCRC32(void) {
res = res && (len == 0);
if (res)
PrintAndLogEx(INFO, "crc32............. " _GREEN_("passed"));
PrintAndLogEx(INFO, "CRC32............. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "crc32............. " _RED_("fail"));
PrintAndLogEx(ERR, "CRC32............. " _RED_("fail"));
return res;
}
@ -132,7 +132,7 @@ static bool TestCMACSubkeys(void) {
res = res && (memcmp(sk2, sk2_3tdea, sizeof(sk2_3tdea)) == 0);
if (res)
PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("passed"));
PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "CMAC subkeys...... " _RED_("fail"));
@ -156,7 +156,7 @@ static bool TestAn10922KDFAES(void) {
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
if (res)
PrintAndLogEx(INFO, "An10922 AES....... " _GREEN_("passed"));
PrintAndLogEx(INFO, "An10922 AES....... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "An10922 AES....... " _RED_("fail"));
@ -178,7 +178,7 @@ static bool TestAn10922KDF2TDEA(void) {
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
if (res)
PrintAndLogEx(INFO, "An10922 2TDEA..... " _GREEN_("passed"));
PrintAndLogEx(INFO, "An10922 2TDEA..... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "An10922 2TDEA..... " _RED_("fail"));
@ -202,7 +202,7 @@ static bool TestAn10922KDF3TDEA(void) {
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
if (res)
PrintAndLogEx(INFO, "An10922 3TDEA..... " _GREEN_("passed"));
PrintAndLogEx(INFO, "An10922 3TDEA..... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "An10922 3TDEA..... " _RED_("fail"));
@ -246,7 +246,7 @@ static bool TestCMAC3TDEA(void) {
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
if (res)
PrintAndLogEx(INFO, "CMAC 3TDEA........ " _GREEN_("passed"));
PrintAndLogEx(INFO, "CMAC 3TDEA........ " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "CMAC 3TDEA........ " _RED_("fail"));
@ -290,7 +290,7 @@ static bool TestCMAC2TDEA(void) {
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
if (res)
PrintAndLogEx(INFO, "CMAC 2TDEA........ " _GREEN_("passed"));
PrintAndLogEx(INFO, "CMAC 2TDEA........ " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "CMAC 2TDEA........ " _RED_("fail"));
@ -330,7 +330,7 @@ static bool TestCMACDES(void) {
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
if (res)
PrintAndLogEx(INFO, "CMAC DES.......... " _GREEN_("passed"));
PrintAndLogEx(INFO, "CMAC DES.......... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "CMAC DES.......... " _RED_("fail"));
@ -357,7 +357,7 @@ static bool TestEV2SessionKeys(void) {
res = res && (memcmp(sessionkey, sessionkeymac, sizeof(sessionkeymac)) == 0);
if (res)
PrintAndLogEx(INFO, "EV2 session keys.. " _GREEN_("passed"));
PrintAndLogEx(INFO, "EV2 session keys.. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "EV2 session keys.. " _RED_("fail"));
@ -393,7 +393,7 @@ static bool TestEV2IVEncode(void) {
res = res && (memcmp(iv, ivres2, sizeof(ivres2)) == 0);
if (res)
PrintAndLogEx(INFO, "EV2 IV calc....... " _GREEN_("passed"));
PrintAndLogEx(INFO, "EV2 IV calc....... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "EV2 IV calc....... " _RED_("fail"));
@ -453,7 +453,7 @@ static bool TestEV2MAC(void) {
res = res && (memcmp(mac, macres4, sizeof(macres4)) == 0);
if (res)
PrintAndLogEx(INFO, "EV2 MAC calc...... " _GREEN_("passed"));
PrintAndLogEx(INFO, "EV2 MAC calc...... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "EV2 MAC calc...... " _RED_("fail"));
@ -477,7 +477,7 @@ static bool TestTransSessionKeys(void) {
res = res && (memcmp(sessionkey, keyenc, sizeof(keyenc)) == 0);
if (res)
PrintAndLogEx(INFO, "Trans session key. " _GREEN_("passed"));
PrintAndLogEx(INFO, "Trans session key. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "Trans session key. " _RED_("fail"));
@ -506,7 +506,7 @@ static bool TestLRPPlaintexts(void) {
res = res && (memcmp(ctx.plaintexts[15], pt15, sizeof(pt15)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP plaintexts.... " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP plaintexts.... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP plaintexts.... " _RED_("fail"));
@ -532,7 +532,7 @@ static bool TestLRPUpdatedKeys(void) {
res = res && (memcmp(ctx.updatedKeys[2], key2, sizeof(key2)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP updated keys.. " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP updated keys.. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP updated keys.. " _RED_("fail"));
@ -588,7 +588,7 @@ static bool TestLRPEval(void) {
res = res && (memcmp(y, y5, sizeof(y5)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP eval.......... " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP eval.......... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP eval.......... " _RED_("fail"));
@ -619,7 +619,7 @@ static bool TestLRPIncCounter(void) {
res = res && (memcmp(ctr4, ctrr4, sizeof(ctrr4)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP inc counter... " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP inc counter... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP inc counter... " _RED_("fail"));
@ -687,7 +687,7 @@ static bool TestLRPEncode(void) {
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP encode........ " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP encode........ " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP encode........ " _RED_("fail"));
@ -754,7 +754,7 @@ static bool TestLRPDecode(void) {
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP decode........ " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP decode........ " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP decode........ " _RED_("fail"));
@ -794,7 +794,7 @@ static bool TestLRPSubkeys(void) {
res = res && (memcmp(sk2, sk2r3, sizeof(sk2r3)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP subkeys....... " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP subkeys....... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP subkeys....... " _RED_("fail"));
@ -856,7 +856,7 @@ static bool TestLRPCMAC(void) {
res = res && (memcmp(cmac, cmacres6, sizeof(cmacres6)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP CMAC.......... " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP CMAC.......... " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP CMAC.......... " _RED_("fail"));
@ -878,7 +878,7 @@ static bool TestLRPSessionKeys(void) {
res = res && (memcmp(sessionkey, sessionkeyres, sizeof(sessionkeyres)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP session keys.. " _GREEN_("passed"));
PrintAndLogEx(INFO, "LRP session keys.. " _GREEN_("ok"));
else
PrintAndLogEx(ERR, "LRP session keys.. " _RED_("fail"));
@ -888,7 +888,7 @@ static bool TestLRPSessionKeys(void) {
bool DesfireTest(bool verbose) {
bool res = true;
PrintAndLogEx(INFO, "------ " _CYAN_("Desfire Tests") " ------");
PrintAndLogEx(INFO, "------ " _CYAN_("MIFARE DESFire tests") " ------");
res = res && TestCRC16();
res = res && TestCRC32();

View file

@ -32,7 +32,8 @@
#define STRBOOL(p) ((p) ? "1" : "0")
#define NDEF_WIFIAPPL "application/vnd.wfa"
#define NDEF_WIFIAPPL_WSC "application/vnd.wfa.wsc"
#define NDEF_WIFIAPPL_P2P "application/vnd.wfa.p2p"
#define NDEF_BLUEAPPL "application/vnd.bluetooth"
#define NDEF_JSONAPPL "application/json"
#define NDEF_VCARDTEXT "text/vcard"
@ -512,11 +513,221 @@ static int ndefDecodePayloadSmartPoster(uint8_t *ndef, size_t ndeflen, bool prin
return PM3_SUCCESS;
}
static int ndefDecodeMime_wifi(NDEFHeader_t *ndef) {
PrintAndLogEx(INFO, _CYAN_("WiFi details"));
if (ndef->PayloadLen > 1) {
PrintAndLogEx(INFO, ">>> decorder, to be implemented <<<");
typedef struct ndef_wifi_type_s {
const char *description;
uint8_t bytes[2];
} ndef_wifi_type_t;
static const ndef_wifi_type_t wifi_crypt_types[] = {
{"NONE", {0x00, 0x01}},
{"WEP", {0x00, 0x02}},
{"TKIP", {0x00, 0x04}},
{"AES", {0x00, 0x08}},
{"AES/TKIP", {0x00, 0x0C}}
};
static const char *ndef_wifi_crypt_lookup(uint8_t *d) {
for (int i = 0; i < ARRAYLEN(wifi_crypt_types); ++i) {
if (memcmp(d, wifi_crypt_types[i].bytes, 2) == 0) {
return wifi_crypt_types[i].description;
}
}
return "";
}
static const ndef_wifi_type_t wifi_auth_types[] = {
{"OPEN", {0x00, 0x01}},
{"WPA PERSONAL", {0x00, 0x02}},
{"SHARED", {0x00, 0x04}},
{"WPA ENTERPRISE", {0x00, 0x08}},
{"WPA2 ENTERPRISE", {0x00, 0x10}},
{"WPA2 PERSONAL", {0x00, 0x20}},
{"WPA/WPA2 PERSONAL", {0x00, 0x22}}
};
static const char *ndef_wifi_auth_lookup(uint8_t *d) {
for (int i = 0; i < ARRAYLEN(wifi_auth_types); ++i) {
if (memcmp(d, wifi_auth_types[i].bytes, 2) == 0) {
return wifi_auth_types[i].description;
}
}
return "";
}
static int ndefDecodeMime_wifi_wsc(NDEFHeader_t *ndef) {
if (ndef->PayloadLen == 0) {
PrintAndLogEx(INFO, "no payload");
return PM3_SUCCESS;
}
PrintAndLogEx(INFO, _CYAN_("NDEF Wifi Simple Config Record"));
PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type);
size_t n = ndef->PayloadLen;
size_t pos = 0;
while (n) {
if (ndef->Payload[pos] != 0x10) {
n -= 1;
pos -= 1;
continue;
}
// VERSION
if (memcmp(&ndef->Payload[pos], "\x10\x4A", 2) == 0) {
uint8_t len = 1;
PrintAndLogEx(INFO, "Version......... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// CREDENTIAL
if (memcmp(&ndef->Payload[pos], "\x10\x0E", 2) == 0) {
// 10 0E 00 39
uint8_t len = 2;
PrintAndLogEx(INFO, "Credential...... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// AUTH_TYPE
if (memcmp(&ndef->Payload[pos], "\x10\x03", 2) == 0) {
// 10 03 00 02 00 20
uint8_t len = 4;
PrintAndLogEx(INFO, "Auth type....... %s ( " _YELLOW_("%s")" )",
sprint_hex(&ndef->Payload[pos + 2], len),
ndef_wifi_auth_lookup(&ndef->Payload[pos + 2])
);
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// CRYPT_TYPE
if (memcmp(&ndef->Payload[pos], "\x10\x0F", 2) == 0) {
// 10 0F 00 02 00 04
uint8_t len = 4;
PrintAndLogEx(INFO, "Crypt type...... %s ( " _YELLOW_("%s")" )",
sprint_hex(&ndef->Payload[pos + 2], len),
ndef_wifi_crypt_lookup(&ndef->Payload[pos + 2])
);
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// MAC_ADDRESS
if (memcmp(&ndef->Payload[pos], "\x10\x20", 2) == 0) {
// 10 20 00 06 FF FF FF FF FF FF
uint8_t len = ndef->Payload[pos + 3];
PrintAndLogEx(INFO, "MAC Address..... %s", sprint_hex_ascii(&ndef->Payload[pos + 4], len));
n -= 4;
n -= len;
pos += 4;
pos += len;
}
// NETWORK_IDX
if (memcmp(&ndef->Payload[pos], "\x10\x26", 2) == 0) {
// 10 26 00 01 01
uint8_t len = 3;
PrintAndLogEx(INFO, "Network Index... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// NETWORK_KEY
if (memcmp(&ndef->Payload[pos], "\x10\x27", 2) == 0) {
// 10 27 00 10 74 72 69 73 74 61 6E 2D 73 70 72 69 6E 67 65 72
uint8_t len = ndef->Payload[pos + 3];
PrintAndLogEx(INFO, "Network key..... %s", sprint_hex_ascii(&ndef->Payload[pos + 4], len));
n -= 4;
n -= len;
pos += 4;
pos += len;
}
// NETWORK_NAME
if (memcmp(&ndef->Payload[pos], "\x10\x45", 2) == 0) {
// 10 45 00 06 69 63 65 73 71 6C
uint8_t len = ndef->Payload[pos + 3];
PrintAndLogEx(INFO, "Network Name.... %s", sprint_hex_ascii(&ndef->Payload[pos + 4], len));
n -= 4;
n -= len;
pos += 4;
pos += len;
}
// OOB_PASSWORD
// unknown the length.
if (memcmp(&ndef->Payload[pos], "\x10\x2C", 2) == 0) {
uint8_t len = 1;
PrintAndLogEx(INFO, "OOB Password......... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// VENDOR_EXT
// unknown the length.
if (memcmp(&ndef->Payload[pos], "\x10\x49", 2) == 0) {
uint8_t len = 1;
PrintAndLogEx(INFO, "Vendor Ext......... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
// VENDOR_WFA
// unknown the length.
if (memcmp(&ndef->Payload[pos], "\x10\x30\x2A", 3) == 0) {
uint8_t len = 1;
PrintAndLogEx(INFO, "Vendor WFA......... %s", sprint_hex(&ndef->Payload[pos + 2], len));
n -= 2;
n -= len;
pos += 2;
pos += len;
}
}
/*
ap-channel 0, 6
+ credential
device-name
mac-address
manufacturer
model-name
model-number
+ oob-password
primary-device-type
rf-bands
secondary-device-type-list
serial-number
ssid
uuid-enrollee
uuid-registrar
+ vendor-extension
version-1
*/
return PM3_SUCCESS;
}
static int ndefDecodeMime_wifi_p2p(NDEFHeader_t *ndef) {
if (ndef->PayloadLen == 0) {
PrintAndLogEx(INFO, "no payload");
return PM3_SUCCESS;
}
PrintAndLogEx(INFO, _CYAN_("NDEF Wifi Peer To Peer Record"));
PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type);
return PM3_SUCCESS;
}
@ -554,18 +765,26 @@ static int ndefDecodeMime_vcard(NDEFHeader_t *ndef) {
}
return PM3_SUCCESS;
}
static int ndefDecodeMime_json(NDEFHeader_t *ndef) {
if (ndef->PayloadLen == 0) {
PrintAndLogEx(INFO, "no payload");
return PM3_SUCCESS;
}
PrintAndLogEx(INFO, _CYAN_("JSON details"));
if (ndef->PayloadLen > 1) {
PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type);
PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, _GREEN_("%.*s"), (int)ndef->PayloadLen, ndef->Payload);
}
return PM3_SUCCESS;
}
static int ndefDecodeMime_bt(NDEFHeader_t *ndef) {
if (ndef->PayloadLen == 0) {
PrintAndLogEx(INFO, "no payload");
return PM3_SUCCESS;
}
PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type);
if (ndef->PayloadLen > 1) {
uint16_t ooblen = (ndef->Payload[1] << 8 | ndef->Payload[0]);
PrintAndLogEx(INFO, "OOB data len.... %u", ooblen);
PrintAndLogEx(INFO, "BT MAC.......... " _YELLOW_("%s"), sprint_hex(ndef->Payload + 2, 6));
@ -602,7 +821,6 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) {
PrintAndLogEx(INFO, "[ %02x ]", ndef->Payload[9]);
}
PrintAndLogEx(NORMAL, "");
}
return PM3_SUCCESS;
}
@ -687,8 +905,11 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) {
memcpy(begin, ndef->Type, ndef->TypeLen);
str_lower(begin);
if (str_startswith(begin, NDEF_WIFIAPPL)) {
ndefDecodeMime_wifi(ndef);
if (str_startswith(begin, NDEF_WIFIAPPL_WSC)) {
ndefDecodeMime_wifi_wsc(ndef);
}
if (str_startswith(begin, NDEF_WIFIAPPL_P2P)) {
ndefDecodeMime_wifi_p2p(ndef);
}
if (str_startswith(begin, NDEF_VCARDTEXT) || str_startswith(begin, NDEF_XVCARDTEXT)) {
ndefDecodeMime_vcard(ndef);

View file

@ -305,6 +305,7 @@ const static vocabulory_t vocabulory[] = {
{ 0, "hf mf rdsc" },
{ 0, "hf mf restore" },
{ 0, "hf mf setmod" },
{ 1, "hf mf value" },
{ 1, "hf mf view" },
{ 0, "hf mf wipe" },
{ 0, "hf mf wrbl" },

View file

@ -1899,7 +1899,7 @@
},
"hf cipurse help": {
"command": "hf cipurse help",
"description": "help this help. test tests",
"description": "help this help. test regression tests",
"notes": [],
"offline": true,
"options": [],
@ -1965,11 +1965,15 @@
},
"hf cipurse test": {
"command": "hf cipurse test",
"description": "[=] ------ cipurse tests ------ [=] kvv.............. passed [=] iso9797m2........ passed [=] smi.............. passed [=] mic.............. passed [=] auth............. passed [=] channel mac...... passed [=] channel encdec... passed [=] apdu............. passed [=] --------------------------- [+] tests [ ok ]",
"notes": [],
"description": "regression tests",
"notes": [
"hf cipurse test"
],
"offline": true,
"options": [],
"usage": ""
"options": [
"-h, --help this help"
],
"usage": "hf cipurse test [-h]"
},
"hf cipurse updakey": {
"command": "hf cipurse updakey",
@ -2016,7 +2020,7 @@
"--mfd select masterfile by empty id",
"--newkeyn <dec> target key id",
"--newkey <hex 16 byte> new key",
"--newkeya <hex 1 byte> new key additional info. 0x00 by default",
"--newkeya <hex 1 byte> new key additional info (def: 0x00)",
"--enckeyn <dec> encrypt key id (must be equal to the key on the card)",
"--enckey <hex 16 byte> encrypt key (must be equal to the key on the card)",
"--sreq <plain|mac(default)|encode> communication reader-picc security level",
@ -4098,7 +4102,7 @@
},
"hf mf help": {
"command": "hf mf help",
"description": "help this help list list mifare history hardnested nested attack for hardened mifare classic cards decrypt [nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace acl decode and print mifare classic access rights bytes view display content from tag dump file",
"description": "help this help list list mifare history hardnested nested attack for hardened mifare classic cards decrypt [nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace acl decode and print mifare classic access rights bytes value decode a value block view display content from tag dump file",
"notes": [],
"offline": true,
"options": [],
@ -4358,6 +4362,19 @@
],
"usage": "hf mf supercard [-hr]"
},
"hf mf value": {
"command": "hf mf value",
"description": "decode of a mifare value block",
"notes": [
"hf mf value -d 87d612007829edff87d6120011ee11ee"
],
"offline": true,
"options": [
"-h, --help this help",
"-d, --data <hex> 16 hex bytes"
],
"usage": "hf mf value [-h] -d <hex>"
},
"hf mf view": {
"command": "hf mf view",
"description": "print a mifare classic dump file (bin/eml/json)",
@ -5207,7 +5224,7 @@
},
"hf mfdes help": {
"command": "hf mfdes help",
"description": "help this help list list desfire (iso 14443a) history test test crypto",
"description": "help this help list list desfire (iso 14443a) history test regression crypto tests",
"notes": [],
"offline": true,
"options": [],
@ -5446,11 +5463,15 @@
},
"hf mfdes test": {
"command": "hf mfdes test",
"description": "[=] ------ desfire tests ------ [!] no space for crc. pos: 1 [=] crc16............. passed [!] no space for crc. pos: 2 [=] crc32............. passed [=] cmac subkeys...... passed [=] an10922 aes....... passed [=] an10922 2tdea..... passed [=] an10922 3tdea..... passed [=] cmac 3tdea........ passed [=] cmac 2tdea........ passed [=] cmac des.......... passed [=] ev2 session keys.. passed [=] ev2 iv calc....... passed [=] ev2 mac calc...... passed [=] trans session key. passed [=] lrp plaintexts.... passed [=] lrp updated keys.. passed [=] lrp eval.......... passed [=] lrp inc counter... passed [=] lrp encode........ passed [=] lrp decode........ passed [=] lrp subkeys....... passed [=] lrp cmac.......... passed [=] lrp session keys.. passed [=] --------------------------- [+] tests [ ok ]",
"notes": [],
"description": "regression crypto tests",
"notes": [
"hf mfdes test"
],
"offline": true,
"options": [],
"usage": ""
"options": [
"-h, --help this help"
],
"usage": "hf mfdes test [-h]"
},
"hf mfdes value": {
"command": "hf mfdes value",
@ -7162,10 +7183,10 @@
"--4205 target chip type em 4205",
"--4305 target chip type em 4305 (default)",
"--4369 target chip type em 4369",
"--4369 target chip type em 4469",
"--4469 target chip type em 4469",
"-p, --pwd <hex> optional - password, 4 bytes hex"
],
"usage": "lf em 4x05 wipe [-h] [--4205] [--4305] [--4369] [--4369] [-p <hex>]"
"usage": "lf em 4x05 wipe [-h] [--4205] [--4305] [--4369] [--4469] [-p <hex>]"
},
"lf em 4x05 write": {
"command": "lf em 4x05 write",
@ -10887,8 +10908,8 @@
}
},
"metadata": {
"commands_extracted": 687,
"commands_extracted": 688,
"extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2022-02-17T00:41:11"
"extracted_on": "2022-02-24T18:33:33"
}
}

View file

@ -255,7 +255,7 @@ Check column "offline" for their availability.
|`hf cipurse updkey `|N |`Update key`
|`hf cipurse updakey `|N |`Update key attributes`
|`hf cipurse default `|N |`Set default key and file id for all the other commands`
|`hf cipurse test `|Y |`Tests`
|`hf cipurse test `|Y |`Regression tests`
### hf epa
@ -460,6 +460,7 @@ Check column "offline" for their availability.
|`hf mf rdsc `|N |`Read MIFARE Classic sector`
|`hf mf restore `|N |`Restore MIFARE Classic binary file to BLANK tag`
|`hf mf setmod `|N |`Set MIFARE Classic EV1 load modulation strength`
|`hf mf value `|Y |`Decode a value block`
|`hf mf view `|Y |`Display content from tag dump file`
|`hf mf wipe `|N |`Wipe card to zeros and default keys/acc`
|`hf mf wrbl `|N |`Write MIFARE Classic block`
@ -576,7 +577,7 @@ Check column "offline" for their availability.
|`hf mfdes write `|N |`Write data to standard/backup/record/value file`
|`hf mfdes value `|N |`Operations with value file (get/credit/limited credit/debit/clear)`
|`hf mfdes clearrecfile `|N |`Clear record File`
|`hf mfdes test `|Y |`Test crypto`
|`hf mfdes test `|Y |`Regression crypto tests`
### hf seos

View file

@ -159,11 +159,11 @@ extern bool g_tearoff_enabled;
// Nibble logic
#ifndef NIBBLE_HIGH
# define NIBBLE_HIGH(b) ( (b & 0xF0) >> 4 )
# define NIBBLE_HIGH(b) ( ((b) & 0xF0) >> 4 )
#endif
#ifndef NIBBLE_LOW
# define NIBBLE_LOW(b) ( b & 0x0F )
# define NIBBLE_LOW(b) ((b) & 0x0F )
#endif
#ifndef CRUMB

View file

@ -519,6 +519,7 @@ typedef struct {
#define CMD_HF_ISO15693_FINDAFI 0x0315
#define CMD_HF_ISO15693_CSETUID 0x0316
#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317
#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318
#define CMD_LF_SNIFF_RAW_ADC 0x0360

View file

@ -365,6 +365,13 @@ int main(int argc, char *argv[]) {
}
uint8_t g_idx = atoi(argv[2]);
// -2 (zero index and last item is NULL);
if (g_idx > ARRAYLEN(generators) - 2) {
printf("generator index is out-of-range\n");
return 1;
}
uint64_t start_time = atoi(argv[3]);
const bool support_aesni = platform_aes_hw_available();

View file

@ -445,7 +445,7 @@ while true; do
"Indala (len 224) Raw: 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"; then break; fi
if ! CheckExecute slow "lf T55 io test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf search -1'" "IO Prox ID found"; then break; fi
if ! CheckExecute slow "lf T55 io test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf io demod'" \
"IO Prox - XSF(01)01:01337, Raw: 007840603059cf3f (ok)"; then break; fi
"IO Prox - XSF(01)01:01337, Raw: 007840603059cf3f ( ok )"; then break; fi
if ! CheckExecute slow "lf T55 jablotron test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf search -1'" "Jablotron ID found"; then break; fi
if ! CheckExecute slow "lf T55 jablotron test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_jablotron.pm3; lf jablotron demod'" \
"Printed: 1410-00-0011-2233"; then break; fi