diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0b569f4ae..a50fa7a56 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1981,7 +1981,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t key_type_nested; uint8_t key_nested[6]; uint8_t nr_nonces; - uint8_t reset; + uint8_t resets; uint8_t addread; uint8_t addauth; uint8_t incblk2; @@ -1990,7 +1990,7 @@ static void PacketReceived(PacketCommandNG *packet) { } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareHasStaticEncryptedNonce(payload->block_no, payload->key_type, payload->key, payload->block_no_nested, payload->key_type_nested, payload->key_nested, payload->nr_nonces, payload->reset, payload->addread, payload->addauth, payload->incblk2, payload->corruptnrar, payload->corruptnrarparity); + MifareHasStaticEncryptedNonce(payload->block_no, payload->key_type, payload->key, payload->block_no_nested, payload->key_type_nested, payload->key_nested, payload->nr_nonces, payload->resets & 1, (payload->resets >> 1) & 1, payload->addread, payload->addauth, payload->incblk2, payload->corruptnrar, payload->corruptnrarparity); break; } #endif diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0e9f915b7..b11498492 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2805,7 +2805,7 @@ 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, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity) { +void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool hardreset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -2851,6 +2851,12 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t * if (need_first_auth) { cuid = 0; + if (hardreset) { + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("RF reset"); + } + mf_reset_card(); + } if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("select"); } @@ -2863,7 +2869,7 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t * retval = PM3_ESOFT; goto OUT; }; - if (!reset) { + if (!reset && !hardreset) { need_first_auth = false; } if (addread) { diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 510fb2bdd..874cae341 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -52,7 +52,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, uint8_t keytype, uint8_t *key); // 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, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity); // Has the tag a static encrypted nonce? +void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool hardreset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity); // Has the tag a static encrypted nonce? // MFC GEN3 int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 40f4d7708..5e812ad29 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -9643,6 +9643,7 @@ static int CmdHF14AMfISEN(const char *Cmd) { arg_str0(NULL, "key2", "", "nested key, 6 hex bytes (default=same)"), arg_int0("n", NULL, "", "number of nonces (default=2)"), arg_lit0(NULL, "reset", "reset between attempts, even if auth was successful"), + arg_lit0(NULL, "hardreset", "hard reset (RF off/on) between attempts, even if auth was successful"), arg_lit0(NULL, "addread", "auth(blk)-read(blk)-auth(blk2)"), arg_lit0(NULL, "addauth", "auth(blk)-auth(blk)-auth(blk2)"), arg_lit0(NULL, "incblk2", "auth(blk)-auth(blk2)-auth(blk2+4)-..."), @@ -9702,11 +9703,17 @@ static int CmdHF14AMfISEN(const char *Cmd) { int nr_nested = arg_get_int_def(ctx, 11, 2); bool reset = arg_get_lit(ctx, 12); - bool addread = arg_get_lit(ctx, 13); - bool addauth = arg_get_lit(ctx, 14); - bool incblk2 = arg_get_lit(ctx, 15); - bool corruptnrar = arg_get_lit(ctx, 16); - bool corruptnrarparity = arg_get_lit(ctx, 17); + bool hardreset = arg_get_lit(ctx, 13); + if (reset && hardreset) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single type of reset"); + return PM3_EINVARG; + } + bool addread = arg_get_lit(ctx, 14); + bool addauth = arg_get_lit(ctx, 15); + bool incblk2 = arg_get_lit(ctx, 16); + bool corruptnrar = arg_get_lit(ctx, 17); + bool corruptnrarparity = arg_get_lit(ctx, 18); CLIParserFree(ctx); uint8_t dbg_curr = DBG_NONE; @@ -9763,7 +9770,7 @@ static int CmdHF14AMfISEN(const char *Cmd) { return PM3_EFAILED; } - int res = detect_classic_static_encrypted_nonce_ex(blockn, keytype, key, blockn_nested, keytype_nested, key_nested, nr_nested, reset, addread, addauth, incblk2, corruptnrar, corruptnrarparity, true); + int res = detect_classic_static_encrypted_nonce_ex(blockn, keytype, key, blockn_nested, keytype_nested, key_nested, nr_nested, reset, hardreset, addread, addauth, incblk2, corruptnrar, corruptnrarparity, true); if (res == NONCE_STATIC) PrintAndLogEx(SUCCESS, "Static nonce......... " _YELLOW_("yes")); if (res == NONCE_STATIC_ENC) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 6f02846d1..f2e18a1bc 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1405,7 +1405,7 @@ returns: 2 = cmd failed 3 = has encrypted nonce */ -int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity, bool verbose) { +int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool hardreset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity, bool verbose) { clearCommandBuffer(); uint8_t cdata[1 + 1 + MIFARE_KEY_SIZE + 1 + 1 + MIFARE_KEY_SIZE + 1 + 1 + 1 + 1 + 1 + 1 + 1] = { 0 }; cdata[0] = block_no; @@ -1415,7 +1415,7 @@ int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, cdata[9] = key_type_nested; memcpy(&cdata[10], key_nested, MIFARE_KEY_SIZE); cdata[16] = nr_nested; - cdata[17] = reset; + cdata[17] = hardreset << 1 | reset; cdata[18] = addread; cdata[19] = addauth; cdata[20] = incblk2; @@ -1483,7 +1483,7 @@ int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, } int detect_classic_static_encrypted_nonce(uint8_t block_no, uint8_t key_type, uint8_t *key) { - return detect_classic_static_encrypted_nonce_ex(block_no, key_type, key, block_no, key_type, key, 3, false, false, false, false, false, false, false); + return detect_classic_static_encrypted_nonce_ex(block_no, key_type, key, block_no, key_type, key, 3, false, false, false, false, false, false, false, false); } // try to see if card responses to "Chinese magic backdoor" commands. diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index df66377f3..b6e8bbd37 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -106,7 +106,7 @@ int detect_classic_prng(void); int detect_classic_nackbug(bool verbose); uint16_t detect_mf_magic(bool is_mfc, uint8_t key_type, uint64_t key); int detect_classic_static_nonce(void); -int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity, bool verbose); +int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type, uint8_t *key, uint8_t block_no_nested, uint8_t key_type_nested, uint8_t *key_nested, uint8_t nr_nested, bool reset, bool hardreset, bool addread, bool addauth, bool incblk2, bool corruptnrar, bool corruptnrarparity, bool verbose); 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);