Merge pull request #2202 from merlokk/mf_info

mf info command
This commit is contained in:
Oleg Moiseenko 2023-12-11 23:17:26 +02:00 committed by GitHub
commit d1a3e8bf56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 374 additions and 23 deletions

View file

@ -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]
- Added `hf mf info` command and static encrypted nonce detection (@merlokk)
- Added Saflok KDF - generate MFC keys (@h1kari)
- Changed `lf fdx demod` - now raw bytes shows all data (@iceman1001)
- Changed `data num` - now can print reversed and inverse (@iceman1001)

View file

@ -799,7 +799,8 @@ static void PacketReceived(PacketCommandNG *packet) {
// emulator
case CMD_SET_DBGMODE: {
g_dbglevel = packet->data.asBytes[0];
print_debug_level();
if (packet->length == 1 || packet->data.asBytes[1] != 0)
print_debug_level();
reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0);
break;
}
@ -1865,6 +1866,17 @@ static void PacketReceived(PacketCommandNG *packet) {
MifareHasStaticNonce();
break;
}
case CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE: {
struct p {
uint8_t block_no;
uint8_t key_type;
uint8_t key[6];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
MifareHasStaticEncryptedNonce(payload->block_no, payload->key_type, payload->key);
break;
}
#endif
#ifdef WITH_NFCBARCODE

View file

@ -90,7 +90,7 @@ int16_t mifare_cmd_readblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t read_c
goto OUT;
}
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL)) {
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL, NULL)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
@ -158,7 +158,7 @@ int16_t mifare_cmd_writeblocks(uint8_t key_auth_cmd, uint8_t *key, uint8_t write
goto OUT;
};
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL)) {
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL, NULL)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
@ -2681,6 +2681,73 @@ OUT:
// 2B F9 1C 1B D5 08 48 48 03 A4 B1 B1 75 FF 2D 90
// ^^ ^^
void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *key) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
clear_trace();
set_tracing(true);
int retval = PM3_SUCCESS;
uint8_t *uid = BigBuf_malloc(10);
memset(uid, 0x00, 10);
uint8_t data[1] = { NONCE_FAIL };
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
uint64_t ui64key = bytes_to_num(key, 6);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
iso14a_card_select_t card_info;
uint32_t cuid = 0;
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
retval = PM3_ESOFT;
goto OUT;
}
uint8_t key_auth_cmd = MIFARE_AUTH_KEYA + (key_type & 1);
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, NULL, NULL, NULL)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
};
uint32_t nt = 0;
uint8_t enc_counter = 0;
uint32_t ntenc = 0;
uint32_t oldntenc = 0;
for (uint8_t i = 0; i < 3; i++) {
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_NESTED, &nt, &ntenc, NULL)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
};
if (g_dbglevel >= DBG_INFO)
Dbprintf("nt: %x, nt encoded: %x", nt, ntenc);
if (oldntenc == 0)
oldntenc = ntenc;
else if (ntenc == oldntenc)
enc_counter++;
}
if (enc_counter) {
data[0] = NONCE_STATIC_ENC;
} else {
data[0] = NONCE_NORMAL;
}
OUT:
crypto1_deinit(pcs);
reply_ng(CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE, retval, data, sizeof(data));
// turns off
OnSuccessMagic();
BigBuf_free();
}
void OnSuccessMagic(void) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();

View file

@ -49,6 +49,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work wi
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
void MifareCIdent(bool is_mfc); // is "magic chinese" card?
void MifareHasStaticNonce(void); // Has the tag a static nonce?
void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *key); // Has the tag a static encrypted nonce?
// MFC GEN3
int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len);

View file

@ -142,9 +142,9 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo,
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
}
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) {
return mifare_classic_authex_cmd(pcs, uid, blockNo, (keyType & 1) ? MIFARE_AUTH_KEYB : MIFARE_AUTH_KEYA, ui64Key, isNested, ntptr, timing);
return mifare_classic_authex_cmd(pcs, uid, blockNo, (keyType & 1) ? MIFARE_AUTH_KEYB : MIFARE_AUTH_KEYA, ui64Key, isNested, ntptr, NULL, timing);
}
int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) {
int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *ntencptr, uint32_t *timing) {
// "random" reader nonce:
uint8_t nr[4];
@ -159,6 +159,8 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
// Save the tag nonce (nt)
uint32_t nt = bytes_to_num(receivedAnswer, 4);
if (ntencptr)
*ntencptr = nt;
// ----------------------------- crypto1 create
if (isNested)

View file

@ -72,7 +72,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
// mifare classic
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing);
int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing);
int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *ntencptr, uint32_t *timing);
int mifare_classic_readblock(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData);
int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte);

View file

@ -39,6 +39,7 @@
#include "cmdhw.h" // set_fpga_mode
#include "loclass/cipherutils.h" // BitstreamOut_t
#include "proxendian.h"
#include "preferences.h"
#include "mifare/gen4.h"
static int CmdHelp(const char *Cmd);
@ -8795,10 +8796,209 @@ static int CmdHFMFHidEncode(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdHF14AMfInfo(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf info",
"Information and check vulnerabilities in the mfc card\n"
"To check some of them need to specify key and/or specific keys in the copmmand line",
"hf mf info -k ffffffff -nv\n"
);
void *argtable[] = {
arg_param_begin,
arg_int0(NULL, "blk", "<dec>", "block number"),
arg_lit0("a", NULL, "input key type is key A (def)"),
arg_lit0("b", NULL, "input key type is key B"),
arg_str0("k", "key", "<hex>", "key, 6 hex bytes"),
arg_lit0("n", "nack", "do nack test"),
arg_lit0("v", "verbose", "verbose output"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int blockn = arg_get_int_def(ctx, 1, 0);
uint8_t keytype = MF_KEY_A;
if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) {
CLIParserFree(ctx);
PrintAndLogEx(WARNING, "Input key type must be A or B");
return PM3_EINVARG;
} else if (arg_get_lit(ctx, 3)) {
keytype = MF_KEY_B;
}
int keylen = 0;
uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
CLIGetHexWithReturn(ctx, 4, key, &keylen);
bool do_nack_test = arg_get_lit(ctx, 5);
bool verbose = arg_get_lit(ctx, 6);
CLIParserFree(ctx);
uint8_t dbg_curr = DBG_NONE;
if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS)
return PM3_EFAILED;
if (keylen != 0 && keylen != 6) {
PrintAndLogEx(ERR, "Key length must be 6 bytes");
return PM3_EINVARG;
}
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
PrintAndLogEx(DEBUG, "iso14443a card select timeout");
return 0;
}
iso14a_card_select_t card;
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
/*
0: couldn't read
1: OK, with ATS
2: OK, no ATS
3: proprietary Anticollision
*/
uint64_t select_status = resp.oldarg[0];
if (select_status == 0) {
PrintAndLogEx(DEBUG, "iso14443a card select failed");
return select_status;
}
if (select_status == 3) {
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
if (verbose) {
PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]);
}
return select_status;
}
PrintAndLogEx(INFO, "--- " _CYAN_("ISO14443-a Information") "---------------------");
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen));
PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02X %02X"), card.atqa[1], card.atqa[0]);
PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02X [%" PRIu64 "]"), card.sak, resp.oldarg[0]);
if (setDeviceDebugLevel(verbose ? DBG_INFO : DBG_NONE, false) != PM3_SUCCESS)
return PM3_EFAILED;
PrintAndLogEx(INFO, "--- " _CYAN_("Backdoors Information") "---------------------");
if (detect_mf_magic(true) == 0)
PrintAndLogEx(INFO, "<none>");
PrintAndLogEx(INFO, "--- " _CYAN_("Keys Information") "---------------------");
uint8_t fkey[MIFARE_KEY_SIZE] = {0};
uint8_t fKeyType = 0xff;
int sectorsCnt = 1;
uint8_t *keyBlock = NULL;
uint32_t keycnt = 0;
int res = mfLoadKeys(&keyBlock, &keycnt, NULL, 0, NULL, 0);
if (res != PM3_SUCCESS) {
return res;
}
// create/initialize key storage structure
sector_t *e_sector = NULL;
if (initSectorTable(&e_sector, sectorsCnt) != PM3_SUCCESS) {
free(keyBlock);
return PM3_EMALLOC;
}
res = mfCheckKeys_fast(sectorsCnt, true, true, 1, keycnt, keyBlock, e_sector, false);
if (res == PM3_SUCCESS) {
uint8_t blockdata[MFBLOCK_SIZE] = {0};
if (e_sector[0].foundKey[0]) {
PrintAndLogEx(SUCCESS, "Sector 0 key A... %12llx", e_sector[0].Key[0]);
num_to_bytes(e_sector[0].Key[0], MIFARE_KEY_SIZE, fkey);
if (mfReadBlock(0, MF_KEY_A, key, blockdata) == PM3_SUCCESS)
fKeyType = MF_KEY_A;
}
if (e_sector[0].foundKey[1]) {
PrintAndLogEx(SUCCESS, "Sector 0 key B... %12llx", e_sector[0].Key[1]);
if (fKeyType == 0xff) {
num_to_bytes(e_sector[0].Key[1], MIFARE_KEY_SIZE, fkey);
if (mfReadBlock(0, MF_KEY_B, key, blockdata) == PM3_SUCCESS)
fKeyType = MF_KEY_B;
}
}
if (fKeyType != 0xff)
PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex(blockdata, MFBLOCK_SIZE));
}
free(keyBlock);
free(e_sector);
PrintAndLogEx(INFO, "--- " _CYAN_("RNG Information") "---------------------");
res = detect_classic_static_nonce();
if (res == NONCE_STATIC)
PrintAndLogEx(SUCCESS, "Static nonce: " _YELLOW_("yes"));
if (res == NONCE_FAIL && verbose)
PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("read failed"));
if (res == NONCE_NORMAL) {
// not static
res = detect_classic_prng();
if (res == 1)
PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("weak"));
else if (res == 0)
PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("hard"));
else
PrintAndLogEx(FAILED, "Prng detection: " _RED_("fail"));
// detect static encrypted nonce
if (keylen == 6) {
res = detect_classic_static_encrypted_nonce(blockn, keytype, key);
if (res == NONCE_STATIC) {
PrintAndLogEx(SUCCESS, "Static nested nonce: " _YELLOW_("yes"));
fKeyType = 0xff; // dont detect twice
}
if (res == NONCE_STATIC_ENC) {
PrintAndLogEx(SUCCESS, "Static encrypted nonce: " _YELLOW_("yes"));
fKeyType = 0xff; // dont detect twice
}
}
if (fKeyType != 0xff) {
res = detect_classic_static_encrypted_nonce(0, fKeyType, fkey);
if (res == NONCE_STATIC)
PrintAndLogEx(SUCCESS, "Static nested nonce: " _YELLOW_("yes"));
if (res == NONCE_STATIC_ENC)
PrintAndLogEx(SUCCESS, "Static encrypted nonce: " _YELLOW_("yes"));
}
if (do_nack_test)
detect_classic_nackbug(verbose);
}
uint8_t signature[32] = {0};
res = read_mfc_ev1_signature(signature);
if (res == PM3_SUCCESS) {
PrintAndLogEx(INFO, "--- " _CYAN_("Signature Information") "---------------------");
mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature));
}
if (setDeviceDebugLevel(dbg_curr, false) != PM3_SUCCESS)
return PM3_EFAILED;
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -----------------------"},
{"info", CmdHF14AMfInfo, IfPm3Iso14443a, "mfc card Info"},
{"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"},
{"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"},
{"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"},

View file

@ -31,6 +31,7 @@
#include "cmdhw.h"
#include "cmddata.h"
#include "commonutil.h"
#include "preferences.h"
#include "pm3_cmd.h"
#include "pmflash.h" // rdv40validation_t
#include "cmdflashmem.h" // get_signature..
@ -476,14 +477,9 @@ static int CmdDbg(const char *Cmd) {
return PM3_EINVARG;
}
clearCommandBuffer();
SendCommandNG(CMD_GET_DBGMODE, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_GET_DBGMODE, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "Failed to get current device debug level");
return PM3_ETIMEOUT;
}
uint8_t curr = resp.data.asBytes[0];
uint8_t curr = DBG_NONE;
if (getDeviceDebugLevel(&curr) != PM3_SUCCESS)
return PM3_EFAILED;
const char *dbglvlstr;
switch (curr) {
@ -522,8 +518,8 @@ static int CmdDbg(const char *Cmd) {
else if (lv4)
dbg = 4;
clearCommandBuffer();
SendCommandNG(CMD_SET_DBGMODE, &dbg, sizeof(dbg));
if (setDeviceDebugLevel(dbg, true) != PM3_SUCCESS)
return PM3_EFAILED;
}
return PM3_SUCCESS;
}

View file

@ -55,7 +55,9 @@
static const uint64_t g_mifare_default_keys[] = {
0xffffffffffff, // Default key (first key used by program if no user defined key)
0xa0a1a2a3a4a5, // NFCForum MAD key
0xa0a1a2a3a4a5, // NFCForum MAD key A
0xb0b1b2b3b4b5, // NFCForum MAD key B
0x89ECA97F8C2A, // NFCForum MAD key B
0xd3f7d3f7d3f7, // NDEF public key
0x4b791bea7bcc, // MFC EV1 Signature 17 B
0x5C8FF9990DA2, // MFC EV1 Signature 16 A
@ -95,13 +97,12 @@ static const uint64_t g_mifare_default_keys[] = {
0x11496F97752A, // HID
0x3E65E4FB65B3, // Gym
0x000000000000, // Blank key
0xb0b1b2b3b4b5,
0xaabbccddeeff,
0x010203040506,
0x1a2b3c4d5e6f,
0x123456789abc,
0x010203040506,
0x123456abcdef,
0xabcdef123456,
0xaabbccddeeff,
0x4d3a99c351dd,
0x1a982c7e459a,
0x714c5c886e97,

View file

@ -1349,6 +1349,33 @@ int detect_classic_static_nonce(void) {
return NONCE_FAIL;
}
/* Detect Mifare Classic static encrypted nonce
detects special magic cards that has a static / fixed nonce
returns:
0 = nonce ok
1 = has static/fixed nonce
2 = cmd failed
3 = has encrypted nonce
*/
int detect_classic_static_encrypted_nonce(uint8_t block_no, uint8_t key_type, uint8_t *key) {
clearCommandBuffer();
uint8_t cdata[1 + 1 + MIFARE_KEY_SIZE] = {0};
cdata[0] = block_no;
cdata[1] = key_type;
memcpy(&cdata[2], key, MIFARE_KEY_SIZE);
SendCommandNG(CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE, cdata, sizeof(cdata));
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE, &resp, 1000)) {
if (resp.status == PM3_ESOFT)
return NONCE_FAIL;
return resp.data.asBytes[0];
}
return NONCE_FAIL;
}
/* try to see if card responses to "Chinese magic backdoor" commands. */
int detect_mf_magic(bool is_mfc) {

View file

@ -102,6 +102,7 @@ int detect_classic_prng(void);
int detect_classic_nackbug(bool verbose);
int detect_mf_magic(bool is_mfc);
int detect_classic_static_nonce(void);
int detect_classic_static_encrypted_nonce(uint8_t block_no, uint8_t key_type, uint8_t *key);
bool detect_mfc_ev1_signature(void);
int read_mfc_ev1_signature(uint8_t *signature);

View file

@ -762,6 +762,44 @@ static int setCmdDeviceDebug (const char *Cmd)
}
*/
int getDeviceDebugLevel (uint8_t *debug_level) {
if (!g_session.pm3_present)
return PM3_EFAILED;
clearCommandBuffer();
SendCommandNG(CMD_GET_DBGMODE, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_GET_DBGMODE, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "Failed to get current device debug level");
return PM3_ETIMEOUT;
}
if (debug_level)
*debug_level = resp.data.asBytes[0];
return PM3_SUCCESS;
}
int setDeviceDebugLevel (uint8_t debug_level, bool verbose) {
if (!g_session.pm3_present)
return PM3_EFAILED;
if (verbose)
PrintAndLogEx (INFO,"setting device debug loglevel to %u", debug_level);
uint8_t cdata[] = {debug_level, verbose};
clearCommandBuffer();
SendCommandNG(CMD_SET_DBGMODE, cdata, sizeof(cdata));
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_SET_DBGMODE, &resp, 2000) == false) {
PrintAndLogEx (WARNING,"failed to set device debug loglevel");
return PM3_EFAILED;
}
return PM3_SUCCESS;
}
static int setCmdOutput(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "prefs set output",

View file

@ -31,4 +31,7 @@ int preferences_save(void);
void preferences_save_callback(json_t *root);
void preferences_load_callback(json_t *root);
int getDeviceDebugLevel (uint8_t *debug_level);
int setDeviceDebugLevel (uint8_t debug_level, bool verbose);
#endif

View file

@ -675,6 +675,7 @@ typedef struct {
#define CMD_HF_MIFARE_NACK_DETECT 0x0730
#define CMD_HF_MIFARE_STATIC_NONCE 0x0731
#define CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE 0x0732
// MFU OTP TearOff
#define CMD_HF_MFU_OTP_TEAROFF 0x0740
@ -740,9 +741,10 @@ typedef struct {
#define MODE_FULLSIM 2
// Static Nonce detection
#define NONCE_FAIL 0x01
#define NONCE_NORMAL 0x02
#define NONCE_STATIC 0x03
#define NONCE_FAIL 0x01
#define NONCE_NORMAL 0x02
#define NONCE_STATIC 0x03
#define NONCE_STATIC_ENC 0x04
// Dbprintf flags
#define FLAG_RAWPRINT 0x00