diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d48483b53..f59cc13a3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1651,20 +1651,22 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t blockno; uint8_t pwd[4]; + uint8_t workFlags; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareG4ReadBlk(payload->blockno, payload->pwd); + MifareG4ReadBlk(payload->blockno, payload->pwd, payload->workFlags); break; } - + // Gen 4 GTU magic cards case CMD_HF_MIFARE_G4_WRBL: { struct p { uint8_t blockno; uint8_t pwd[4]; uint8_t data[16]; // data to be written + uint8_t workFlags; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data); + MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags); break; } case CMD_HF_MIFARE_PERSONALIZE_UID: { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 476e7c96a..e1e8dc2a9 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2684,90 +2684,107 @@ OUT: BigBuf_free(); } -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); +// read or write block to GEN4 GTU tag +void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + bool read = rw & 0x1 & 0xFF ; + bool write = rw & 0x2 & 0xFF ; - int retval = PM3_SUCCESS; - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); - uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); - uint8_t *uid = BigBuf_malloc(10); - if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { - retval = PM3_ESOFT; - goto OUT; - } - - LED_B_ON(); - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout - - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCE, blockno, 0x00, 0x00}; - - memcpy(cmd + 1, pwd, 4); - - AddCrc14A(cmd, sizeof(cmd) - 2); - - ReaderTransmit(cmd, sizeof(cmd), NULL); - int res = ReaderReceive(buf, par); - if (res != 18) { - retval = PM3_ESOFT; - } - iso14a_set_timeout(save_iso14a_timeout); - LED_B_OFF(); - -OUT: - reply_ng(CMD_HF_MIFARE_G4_RDBL, retval, buf, 18); - // turns off - OnSuccessMagic(); - BigBuf_free(); -} - -void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + bool setup = workFlags & MAGIC_INIT & 0xFF ; + bool done = workFlags & MAGIC_OFF & 0xFF ; int res = 0; int retval = PM3_SUCCESS; - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); - uint8_t *uid = BigBuf_malloc(10); - if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { - retval = PM3_ESOFT; + if (buf == NULL) { + retval = PM3_EMALLOC; goto OUT; } - LED_B_ON(); - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + // check args + if (write && (data == NULL)) { + retval = PM3_EINVARG; + goto OUT; + } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno, + if (!(read || write)) { + retval = PM3_EINVARG; + goto OUT; + } + + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + if (setup) { + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + } + + LED_B_ON(); + + static uint32_t save_iso14a_timeout; + if (setup) { + save_iso14a_timeout = iso14a_get_timeout(); + iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + } + + uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, (write ? 0xCD : 0xCE), blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(cmd + 1, pwd, 4); - memcpy(cmd + 7, data, 16); + if (write) memcpy(cmd + 7, data, 16); - AddCrc14A(cmd, sizeof(cmd) - 2); + size_t crc_pos = read ? 7 : (sizeof(cmd) - 2) ; + AddCrc14A(cmd, crc_pos); - ReaderTransmit(cmd, sizeof(cmd), NULL); + ReaderTransmit(cmd, crc_pos + 2, NULL); res = ReaderReceive(buf, par); - if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { + + if (write) { + if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { + retval = PM3_ESOFT; + } + } else if (res != 18) { retval = PM3_ESOFT; } - iso14a_set_timeout(save_iso14a_timeout); + + if (done || retval != 0) iso14a_set_timeout(save_iso14a_timeout); LED_B_OFF(); OUT: - reply_ng(CMD_HF_MIFARE_G4_WRBL, retval, buf, res); + reply_ng(write ? CMD_HF_MIFARE_G4_WRBL : CMD_HF_MIFARE_G4_RDBL, retval, buf, res); // turns off - OnSuccessMagic(); + if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + if (done || retval != 0) set_tracing(false); BigBuf_free(); } +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { + MifareG4ReadWriteBlk(0x1, blockno, pwd, NULL, workFlags) ; +} + +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + MifareG4ReadWriteBlk(0x2, blockno, pwd, data, workFlags) ; +} + void MifareSetMod(uint8_t *datain) { uint8_t mod = datain[0]; diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index de3bd416c..a68fed8db 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -57,8 +57,9 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overw void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GTU -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd); -void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data); +void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags); +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); void MifareSetMod(uint8_t *datain); void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 222d0f961..b0c80f54a 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6788,7 +6788,7 @@ static int CmdHF14AGen4GetBlk(const char *cmd) { PrintAndLogEx(NORMAL, "Block: %x", blockno) ; - int res = mfG4GetBlock(pwd, blockno, data); + int res = mfG4GetBlock(pwd, blockno, data, MAGIC_INIT | MAGIC_OFF); if (res) { PrintAndLogEx(ERR, "Can't read block. error=%d", res); return PM3_ESOFT; @@ -6980,7 +6980,7 @@ static int CmdHF14AGen4Load(const char *cmd) { fflush(stdout); // write block - if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) { + if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); if (data != NULL) free(data); @@ -7047,7 +7047,7 @@ static int CmdHF14AGen4SetBlk(const char *cmd) { PrintAndLogEx(INFO, "Writing block number:%2d data:%s", b, sprint_hex_inrow(data, sizeof(data))); uint8_t blockno = (uint8_t)b; - int res = mfG4SetBlock(pwd, blockno, data); + int res = mfG4SetBlock(pwd, blockno, data, MAGIC_INIT | MAGIC_OFF); if (res) { PrintAndLogEx(ERR, "Can't write block. error=%d", res); return PM3_ESOFT; @@ -7164,7 +7164,7 @@ static int CmdHF14AGen4View(const char *Cmd) { PrintAndLogEx(NORMAL, "." NOLF); fflush(stdout); - if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE)) != PM3_SUCCESS) { + if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't get magic card block: %u", i); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 2964289b2..1d57ec533 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1158,13 +1158,15 @@ int mfGen3Freeze(void) { } } -int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { +int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags) { struct p { uint8_t blockno; uint8_t pwd[4]; + uint8_t workFlags; } PACKED payload; payload.blockno = blockno; memcpy(payload.pwd, pwd, sizeof(payload.pwd)); + payload.workFlags = workFlags; clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_G4_RDBL, (uint8_t *)&payload, sizeof(payload)); @@ -1181,15 +1183,17 @@ int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { return PM3_SUCCESS; } -int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags) { struct p { uint8_t blockno; uint8_t pwd[4]; uint8_t data[16]; + uint8_t workFlags; } PACKED payload; payload.blockno = blockno; memcpy(payload.pwd, pwd, sizeof(payload.pwd)); memcpy(payload.data, data, sizeof(payload.data)); + payload.workFlags = workFlags; clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_G4_WRBL, (uint8_t *)&payload, sizeof(payload)); diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index cc0fa1f83..8f50ccbd7 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -95,8 +95,8 @@ int mfGen3UID(uint8_t *uid, uint8_t uidlen, uint8_t *oldUid); int mfGen3Block(uint8_t *block, int blockLen, uint8_t *newBlock); int mfGen3Freeze(void); -int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); -int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); +int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags); +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags); int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len);