From 82f5c8512de36fee38b1e72643d24eac848f4958 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 13:58:27 +0200 Subject: [PATCH] mfc writes now support tear off --- armsrc/mifarecmd.c | 61 +++++++++++++++++++++++--------------------- armsrc/mifareutil.c | 26 +++++++++++-------- client/src/cmdhfmf.c | 41 +++++++++++++++++++---------- 3 files changed, 76 insertions(+), 52 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9eb44da5a..0d14ffb92 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -453,7 +453,6 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { memcpy(blockdata, datain + 10, 16); // variables - uint8_t isOK = 0; uint8_t uid[10] = {0x00}; uint32_t cuid = 0; struct Crypto1State mpcs = {0, 0}; @@ -469,37 +468,39 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { LED_B_OFF(); LED_C_OFF(); - while (true) { - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); - break; - }; + uint8_t retval = 0; - if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); - break; - }; + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); + goto OUT; + }; - if (mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); - break; - }; + if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); + goto OUT; + }; - if (mifare_classic_halt(pcs, cuid)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); - break; - }; - - isOK = 1; - break; + int res = mifare_classic_writeblock(pcs, cuid, blockNo, blockdata); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + retval = PM3_ESOFT; + goto OUT; } + if (mifare_classic_halt(pcs, cuid)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); + goto OUT; + }; + + retval = 1; + +OUT: crypto1_deinit(pcs); - if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED"); - - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); - + reply_mix(CMD_ACK, retval, 0, 0, 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); @@ -549,18 +550,20 @@ void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t goto OUT; }; - if (mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true)) { + int res = mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res) { retval = PM3_ESOFT; goto OUT; - }; + } if (mifare_classic_halt(pcs, cuid)) { retval = PM3_ESOFT; goto OUT; }; - if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED"); - OUT: crypto1_deinit(pcs); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 11009031b..fd9260e23 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -18,6 +18,7 @@ //----------------------------------------------------------------------------- #include "mifareutil.h" +#include "appmain.h" // tearoff hook #include "string.h" #include "BigBuf.h" #include "iso14443a.h" @@ -451,18 +452,23 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); - // Receive the response - len = ReaderReceive(receivedAnswer, receivedAnswerPar); + // tearoff occurred + if (tearoff_hook() == PM3_ETEAROFF) { + return PM3_ETEAROFF; + } else { + // Receive the response + len = ReaderReceive(receivedAnswer, receivedAnswerPar); - uint8_t res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + uint8_t res = 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; - if ((len != 1) || (res != 0x0A)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); - return 2; + if ((len != 1) || (res != 0x0A)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); + return 2; + } } return 0; } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 0ba8aac98..8093c818d 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -628,10 +628,12 @@ static int CmdHF14AMfWrBl(const char *Cmd) { return PM3_ETIMEOUT; } - uint8_t isok = resp.oldarg[0] & 0xff; - if (isok) { + int status = resp.oldarg[0]; + if (status) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); + } else if (status == PM3_ETEAROFF) { + return status; } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); // suggest the opposite keytype than what was used. @@ -7708,7 +7710,9 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { if (resp.status == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); - } else { + } else if (resp.status == PM3_ETEAROFF) { + return resp.status; + } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); PrintAndLogEx(HINT, "Maybe access rights? Try specify keytype `" _YELLOW_("hf mf gdmsetblk -%c ...") "` instead", (keytype == MF_KEY_A) ? 'b' : 'a'); } @@ -7831,7 +7835,7 @@ static int CmdHF14AMfValue(const char *Cmd) { } if (action < 3) { - uint8_t isok = true; + if (g_session.pm3_present == false) return PM3_ENOTTY; @@ -7858,7 +7862,15 @@ static int CmdHF14AMfValue(const char *Cmd) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - isok = resp.oldarg[0] & 0xff; + + if (resp.oldarg[0] & 0xFF) { + // all ok so set flag to read current value + getval = true; + PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); + } else { + PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); + } + } else { // set value // To set a value block (or setup) we can use the normal mifare classic write block // So build the command options can call CMD_HF_MIFARE_WRITEBL @@ -7883,14 +7895,17 @@ static int CmdHF14AMfValue(const char *Cmd) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - isok = resp.oldarg[0] & 0xff; - } - - if (isok) { - PrintAndLogEx(SUCCESS, "Update ... : " _GREEN_("success")); - getval = true; // all ok so set flag to read current value - } else { - PrintAndLogEx(FAILED, "Update ... : " _RED_("failed")); + int status = resp.oldarg[0]; + if (status) { + // all ok so set flag to read current value + getval = true; + PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); + } else if (status == PM3_ETEAROFF) { + // all ok so set flag to read current value + getval = true; + } else { + PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); + } } }