Merge pull request #1811 from DidierA/hf_mf_gen4_rewrite

hf mf gview, gload : 2x speed
This commit is contained in:
Iceman 2022-11-14 21:57:22 +01:00 committed by GitHub
commit dca3c6184c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 70 deletions

View file

@ -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: {

View file

@ -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,16 +2816,20 @@ 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();
if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
if (done || retval != 0) set_tracing(false);
BigBuf_free();
}

View file

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

View file

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

View file

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

View file

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