Rewrite of magic Gen4 GTU commands : refactor and speed

This commit is contained in:
DidierA 2022-11-09 15:49:07 +01:00
commit 885911c469
6 changed files with 94 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,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);
if (buf == NULL) {
retval = PM3_EMALLOC;
goto OUT;
}
// check args
if (write && (data == NULL)) {
retval = PM3_EINVARG;
goto OUT;
}
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();
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, 0xCD, blockno,
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 (write) {
if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) {
retval = PM3_ESOFT;
}
iso14a_set_timeout(save_iso14a_timeout);
} else if (res != 18) {
retval = PM3_ESOFT;
}
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];

View file

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

View file

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

View file

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

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