mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Rewrite of magic Gen4 GTU commands : refactor and speed
This commit is contained in:
parent
3b72c4f772
commit
885911c469
6 changed files with 94 additions and 70 deletions
|
@ -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: {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue