mfc writes now support tear off

This commit is contained in:
iceman1001 2023-03-26 13:58:27 +02:00
commit 82f5c8512d
3 changed files with 76 additions and 52 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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,6 +7710,8 @@ 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 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") " )");
}
}
}