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..4fd74c9ef 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2684,63 +2684,124 @@ OUT: BigBuf_free(); } -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { + bool setup = ((workFlags & MAGIC_INIT) == MAGIC_INIT) ; + bool done = ((workFlags & MAGIC_OFF) == MAGIC_OFF) ; + 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 + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCE, blockno, 0x00, 0x00}; + 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, 0xCE, blockno, + 0x00, 0x00 + }; memcpy(cmd + 1, pwd, 4); AddCrc14A(cmd, sizeof(cmd) - 2); ReaderTransmit(cmd, sizeof(cmd), NULL); - int res = ReaderReceive(buf, par); + res = ReaderReceive(buf, par); + 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_RDBL, retval, buf, 18); + reply_ng(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 MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + bool setup = ((workFlags & MAGIC_INIT) == MAGIC_INIT) ; + bool done = ((workFlags & MAGIC_OFF) == MAGIC_OFF) ; 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; } + // check args + if (data == NULL) { + 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(); - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + + 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, 0xCD, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2755,17 +2816,21 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) { ReaderTransmit(cmd, sizeof(cmd), NULL); res = ReaderReceive(buf, par); + if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { 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); // turns off - OnSuccessMagic(); - BigBuf_free(); + if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + if (done || retval != 0) set_tracing(false); + BigBuf_free(); } void MifareSetMod(uint8_t *datain) { diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index de3bd416c..30179aa3b 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -57,8 +57,8 @@ 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 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 6290415bf..5609d0363 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2402,7 +2402,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } - bool load_success = true; + bool load_success = true; // Load the dictionary if (has_filename) { res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); @@ -6828,7 +6828,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; @@ -7022,8 +7022,13 @@ static int CmdHF14AGen4Load(const char *cmd) { fflush(stdout); // write block - if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); + uint8_t flags = 0 ; + if (blockno == start) flags |= MAGIC_INIT ; + if (blockno == end) flags |= MAGIC_OFF ; + + int res=mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), flags); + if ( res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't set magic card block: %d. error=%d", blockno, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(data); return PM3_ESOFT; @@ -7089,7 +7094,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; @@ -7163,31 +7168,6 @@ static int CmdHF14AGen4View(const char *Cmd) { } PrintAndLogEx(SUCCESS, "View magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s); - // Select card to get UID/UIDLEN information - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { - PrintAndLogEx(WARNING, "iso14443a card select timeout"); - return PM3_ETIMEOUT; - } - - /* - 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(WARNING, "iso14443a card select failed"); - return PM3_SUCCESS; - } - - iso14a_card_select_t card; - memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); - // reserve memory uint16_t bytes = block_cnt * MFBLOCK_SIZE; uint8_t *dump = calloc(bytes, sizeof(uint8_t)); @@ -7206,8 +7186,13 @@ static int CmdHF14AGen4View(const char *Cmd) { PrintAndLogEx(NORMAL, "." NOLF); fflush(stdout); - if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE)) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Can't get magic card block: %u", i); + uint8_t flags = 0 ; + if (i == 0) flags |= MAGIC_INIT ; + if (i+1 == block_cnt) flags |= MAGIC_OFF ; + + int res = mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), flags); + if ( res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't get magic card block: %u. error=%d", i, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); return PM3_ESOFT; diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 665f88edf..93727e45f 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1160,13 +1160,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)); @@ -1183,15 +1185,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 9fb359f13..48ec3d38d 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);