mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 07:16:14 +08:00
Merge pull request #2513 from douniwan5788/hitagS_tag
refactor: switch hitagS_tag to union
This commit is contained in:
commit
6149a6f6c8
241
armsrc/hitagS.c
241
armsrc/hitagS.c
|
@ -39,7 +39,7 @@
|
|||
#define CRC_POLYNOM 0x1D
|
||||
|
||||
static struct hitagS_tag tag = {
|
||||
.pages =
|
||||
.data.pages =
|
||||
{
|
||||
// Plain mode: | Authentication mode:
|
||||
[0] = {0x88, 0xcd, 0x6d, 0xf3}, // UID | UID
|
||||
|
@ -70,8 +70,8 @@ static uint32_t rnd = 0x74124485; // random number
|
|||
//#define SENDBIT_TEST
|
||||
|
||||
/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3
|
||||
// UID is 0 1 2 3 // tag.uid is 3210
|
||||
// datasheet HitagS_V11.pdf bytes in tables printed 3 2 1 0
|
||||
UID is 0 1 2 3 // tag.data.s.uid_le is 3210
|
||||
datasheet HitagS_V11.pdf bytes in tables printed 3 2 1 0
|
||||
|
||||
#db# UID: 5F C2 11 84
|
||||
#db# conf0: C9 conf1: 00 conf2: 00
|
||||
|
@ -401,7 +401,7 @@ static int check_select(const uint8_t *rx, uint32_t uid) {
|
|||
// global var?
|
||||
temp_uid = ans;
|
||||
|
||||
if (ans == tag.uid) {
|
||||
if (ans == BSWAP_32(tag.data.s.uid_le)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
//send uid as a response
|
||||
*txlen = 32;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tx[i] = (tag.uid >> (24 - (i * 8))) & 0xFF;
|
||||
tx[i] = (BSWAP_32(tag.data.s.uid_le) >> (24 - (i * 8))) & 0xFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
//select command from reader received
|
||||
DBG DbpString("SELECT");
|
||||
|
||||
if ((rx[0] & 0xf8) == HITAGS_SELECT && check_select(rx, tag.uid) == 1) {
|
||||
if ((rx[0] & 0xf8) == HITAGS_SELECT && check_select(rx, BSWAP_32(tag.data.s.uid_le)) == 1) {
|
||||
|
||||
DBG DbpString("SELECT match");
|
||||
|
||||
|
@ -491,7 +491,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
|
||||
//send configuration
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tx[i] = tag.pages[1][i];
|
||||
tx[i] = tag.data.pages[1][i];
|
||||
}
|
||||
|
||||
tx[3] = 0xff;
|
||||
|
@ -517,8 +517,8 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
temp2++;
|
||||
*txlen = 32;
|
||||
// init crypt engine
|
||||
state = ht2_hitag2_init(REV64(tag.key),
|
||||
REV32((tag.pages[0][3] << 24) + (tag.pages[0][2] << 16) + (tag.pages[0][1] << 8) + tag.pages[0][0]),
|
||||
state = ht2_hitag2_init(reflect64(tag.data.s.key) >> 16 & 0xFFFFFFFFFFFF,
|
||||
REV32((tag.data.pages[0][3] << 24) + (tag.data.pages[0][2] << 16) + (tag.data.pages[0][1] << 8) + tag.data.pages[0][0]),
|
||||
REV32((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0])
|
||||
);
|
||||
DBG Dbprintf(", {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]);
|
||||
|
@ -530,19 +530,19 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
}
|
||||
|
||||
//send con2, pwdh0, pwdl0, pwdl1 encrypted as a response
|
||||
tx[0] = ht2_hitag2_byte(&state) ^ tag.pages[1][2];
|
||||
tx[1] = ht2_hitag2_byte(&state) ^ tag.pwdh0;
|
||||
tx[2] = ht2_hitag2_byte(&state) ^ tag.pwdl0;
|
||||
tx[3] = ht2_hitag2_byte(&state) ^ tag.pwdl1;
|
||||
tx[0] = ht2_hitag2_byte(&state) ^ tag.data.pages[1][2];
|
||||
tx[1] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdh0;
|
||||
tx[2] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl0;
|
||||
tx[3] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl1;
|
||||
|
||||
if (tag.mode != HT_STANDARD) {
|
||||
//add crc8
|
||||
*txlen = 40;
|
||||
crc = CRC_PRESET;
|
||||
calc_crc(&crc, tag.pages[1][2], 8);
|
||||
calc_crc(&crc, tag.pwdh0, 8);
|
||||
calc_crc(&crc, tag.pwdl0, 8);
|
||||
calc_crc(&crc, tag.pwdl1, 8);
|
||||
calc_crc(&crc, tag.data.pages[1][2], 8);
|
||||
calc_crc(&crc, tag.data.s.pwdh0, 8);
|
||||
calc_crc(&crc, tag.data.s.pwdl0, 8);
|
||||
calc_crc(&crc, tag.data.s.pwdl1, 8);
|
||||
tx[4] = (crc ^ ht2_hitag2_byte(&state));
|
||||
}
|
||||
/*
|
||||
|
@ -550,17 +550,9 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
* use this to change the uid between authentications.
|
||||
|
||||
if (temp2 % 2 == 0) {
|
||||
tag.uid = 0x11223344;
|
||||
tag.pages[0][0] = 0x11;
|
||||
tag.pages[0][1] = 0x22;
|
||||
tag.pages[0][2] = 0x33;
|
||||
tag.pages[0][3] = 0x44;
|
||||
tag.data.s.uid_le = 0x44332211;
|
||||
} else {
|
||||
tag.uid = 0x55667788;
|
||||
tag.pages[0][0] = 0x55;
|
||||
tag.pages[0][1] = 0x66;
|
||||
tag.pages[0][2] = 0x77;
|
||||
tag.pages[0][3] = 0x88;
|
||||
tag.data.s.uid_le = 0x88776655;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
|
@ -571,10 +563,10 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
//data received to be written
|
||||
if (tag.tstate == HT_WRITING_PAGE_DATA) {
|
||||
tag.tstate = HT_NO_OP;
|
||||
tag.pages[page_to_be_written][0] = rx[0];
|
||||
tag.pages[page_to_be_written][1] = rx[1];
|
||||
tag.pages[page_to_be_written][2] = rx[2];
|
||||
tag.pages[page_to_be_written][3] = rx[3];
|
||||
tag.data.pages[page_to_be_written][0] = rx[0];
|
||||
tag.data.pages[page_to_be_written][1] = rx[1];
|
||||
tag.data.pages[page_to_be_written][2] = rx[2];
|
||||
tag.data.pages[page_to_be_written][3] = rx[3];
|
||||
//send ack
|
||||
*txlen = 2;
|
||||
tx[0] = 0x40;
|
||||
|
@ -582,10 +574,10 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
hts_set_frame_modulation();
|
||||
|
||||
} else if (tag.tstate == HT_WRITING_BLOCK_DATA) {
|
||||
tag.pages[page_to_be_written][0] = rx[0];
|
||||
tag.pages[page_to_be_written][1] = rx[1];
|
||||
tag.pages[page_to_be_written][2] = rx[2];
|
||||
tag.pages[page_to_be_written][3] = rx[3];
|
||||
tag.data.pages[page_to_be_written][0] = rx[0];
|
||||
tag.data.pages[page_to_be_written][1] = rx[1];
|
||||
tag.data.pages[page_to_be_written][2] = rx[2];
|
||||
tag.data.pages[page_to_be_written][3] = rx[3];
|
||||
//send ack
|
||||
*txlen = 2;
|
||||
tx[0] = 0x40;
|
||||
|
@ -606,12 +598,12 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
//send page data
|
||||
uint8_t page = ((rx[0] & 0x0f) << 4) + ((rx[1] & 0xf0) >> 4);
|
||||
*txlen = 32;
|
||||
tx[0] = tag.pages[page][0];
|
||||
tx[1] = tag.pages[page][1];
|
||||
tx[2] = tag.pages[page][2];
|
||||
tx[3] = tag.pages[page][3];
|
||||
tx[0] = tag.data.pages[page][0];
|
||||
tx[1] = tag.data.pages[page][1];
|
||||
tx[2] = tag.data.pages[page][2];
|
||||
tx[3] = tag.data.pages[page][3];
|
||||
|
||||
if (tag.LKP && page == 1) {
|
||||
if (tag.data.s.LKP && page == 1) {
|
||||
tx[3] = 0xFF;
|
||||
}
|
||||
|
||||
|
@ -627,7 +619,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
tx[4] = crc;
|
||||
}
|
||||
|
||||
if (tag.LKP && (page == 2 || page == 3)) {
|
||||
if (tag.data.s.LKP && (page == 2 || page == 3)) {
|
||||
//if reader asks for key or password and the LKP-mark is set do not respond
|
||||
sof_bits = 0;
|
||||
*txlen = 0;
|
||||
|
@ -640,10 +632,10 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
|
||||
//send page,...,page+3 data
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tx[0 + i * 4] = tag.pages[page + 0 + i * 4][0];
|
||||
tx[1 + i * 4] = tag.pages[page + 1 + i * 4][1];
|
||||
tx[2 + i * 4] = tag.pages[page + 2 + i * 4][2];
|
||||
tx[3 + i * 4] = tag.pages[page + 3 + i * 4][3];
|
||||
tx[0 + i * 4] = tag.data.pages[page + 0 + i * 4][0];
|
||||
tx[1 + i * 4] = tag.data.pages[page + 1 + i * 4][1];
|
||||
tx[2 + i * 4] = tag.data.pages[page + 2 + i * 4][2];
|
||||
tx[3 + i * 4] = tag.data.pages[page + 3 + i * 4][3];
|
||||
}
|
||||
|
||||
hts_set_frame_modulation();
|
||||
|
@ -658,7 +650,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
tx[16] = crc;
|
||||
}
|
||||
|
||||
if ((page) % 4 != 0 || (tag.LKP && (page) == 0)) {
|
||||
if ((page) % 4 != 0 || (tag.data.s.LKP && (page) == 0)) {
|
||||
sof_bits = 0;
|
||||
*txlen = 0;
|
||||
}
|
||||
|
@ -667,8 +659,8 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
|||
|
||||
uint8_t page = ((rx[0] & 0x0f) << 4) + ((rx[1] & 0xf0) >> 4);
|
||||
|
||||
if ((tag.LCON && page == 1)
|
||||
|| (tag.LKP && (page == 2 || page == 3))) {
|
||||
if ((tag.data.s.LCON && page == 1)
|
||||
|| (tag.data.s.LKP && (page == 2 || page == 3))) {
|
||||
//deny
|
||||
*txlen = 0;
|
||||
} else {
|
||||
|
@ -737,101 +729,32 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) {
|
|||
// read tag data into memory
|
||||
if (tag_mem_supplied) {
|
||||
DbpString("Loading hitag S memory...");
|
||||
memcpy((uint8_t *)tag.pages, data, 4 * 64);
|
||||
memcpy((uint8_t *)tag.data.pages, data, 4 * 64);
|
||||
} else {
|
||||
// use the last read tag
|
||||
}
|
||||
|
||||
tag.uid = ((tag.pages[0][3]) << 24) | ((tag.pages[0][2]) << 16) | ((tag.pages[0][1]) << 8) | tag.pages[0][0];
|
||||
tag.key = (((uint64_t)tag.pages[3][3]) << 40) |
|
||||
(((uint64_t)tag.pages[3][2]) << 32) |
|
||||
(((uint64_t)tag.pages[3][1]) << 24) |
|
||||
(((uint64_t)tag.pages[3][0]) << 16) |
|
||||
(((uint64_t)tag.pages[2][3]) << 8) |
|
||||
(((uint64_t)tag.pages[2][2]));
|
||||
|
||||
tag.pwdl0 = tag.pages[2][0];
|
||||
tag.pwdl1 = tag.pages[2][1];
|
||||
tag.pwdh0 = tag.pages[1][3];
|
||||
//con0
|
||||
tag.max_page = 64;
|
||||
|
||||
if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 1) {
|
||||
if ((tag.data.pages[1][0] & 0x2) == 0 && (tag.data.pages[1][0] & 0x1) == 1) {
|
||||
tag.max_page = 8;
|
||||
}
|
||||
|
||||
if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 0) {
|
||||
if ((tag.data.pages[1][0] & 0x2) == 0 && (tag.data.pages[1][0] & 0x1) == 0) {
|
||||
tag.max_page = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tag.max_page; i++) {
|
||||
DBG Dbprintf("Page[%2d]: %02X %02X %02X %02X",
|
||||
i,
|
||||
(tag.pages[i][3]) & 0xFF,
|
||||
(tag.pages[i][2]) & 0xFF,
|
||||
(tag.pages[i][1]) & 0xFF,
|
||||
tag.pages[i][0] & 0xFF
|
||||
tag.data.pages[i][3],
|
||||
tag.data.pages[i][2],
|
||||
tag.data.pages[i][1],
|
||||
tag.data.pages[i][0]
|
||||
);
|
||||
}
|
||||
|
||||
//con1
|
||||
tag.auth = 0;
|
||||
if ((tag.pages[1][1] & 0x80) == 0x80) {
|
||||
tag.auth = 1;
|
||||
}
|
||||
|
||||
tag.LCON = 0;
|
||||
if ((tag.pages[1][1] & 0x2) == 0x02) {
|
||||
tag.LCON = 1;
|
||||
}
|
||||
|
||||
tag.LKP = 0;
|
||||
if ((tag.pages[1][1] & 0x1) == 0x01) {
|
||||
tag.LKP = 1;
|
||||
}
|
||||
|
||||
//con2
|
||||
//0=read write 1=read only
|
||||
tag.LCK7 = 0;
|
||||
if ((tag.pages[1][2] & 0x80) == 0x80) {
|
||||
tag.LCK7 = 1;
|
||||
}
|
||||
|
||||
tag.LCK6 = 0;
|
||||
if ((tag.pages[1][2] & 0x40) == 0x040) {
|
||||
tag.LCK6 = 1;
|
||||
}
|
||||
|
||||
tag.LCK5 = 0;
|
||||
if ((tag.pages[1][2] & 0x20) == 0x20) {
|
||||
tag.LCK5 = 1;
|
||||
}
|
||||
|
||||
tag.LCK4 = 0;
|
||||
if ((tag.pages[1][2] & 0x10) == 0x10) {
|
||||
tag.LCK4 = 1;
|
||||
}
|
||||
|
||||
tag.LCK3 = 0;
|
||||
if ((tag.pages[1][2] & 0x8) == 0x08) {
|
||||
tag.LCK3 = 1;
|
||||
}
|
||||
|
||||
tag.LCK2 = 0;
|
||||
if ((tag.pages[1][2] & 0x4) == 0x04) {
|
||||
tag.LCK2 = 1;
|
||||
}
|
||||
|
||||
tag.LCK1 = 0;
|
||||
if ((tag.pages[1][2] & 0x2) == 0x02) {
|
||||
tag.LCK1 = 1;
|
||||
}
|
||||
|
||||
tag.LCK0 = 0;
|
||||
if ((tag.pages[1][2] & 0x1) == 0x01) {
|
||||
tag.LCK0 = 1;
|
||||
}
|
||||
|
||||
|
||||
// Set up simulator mode, frequency divisor which will drive the FPGA
|
||||
// and analog mux selection.
|
||||
|
@ -1200,7 +1123,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
|||
return -1;
|
||||
}
|
||||
|
||||
tag.uid = (rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]);
|
||||
memcpy(&tag.data.pages[HITAGS_UID_PADR], rx, HITAGS_PAGE_SIZE);
|
||||
|
||||
DBG Dbprintf("UID... %02X%02X%02X%02X", rx[0], rx[1], rx[2], rx[3]);
|
||||
|
||||
|
@ -1219,40 +1142,20 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint8_t conf_pages[3];
|
||||
conf_pages[0] = rx[0];
|
||||
memcpy(&tag.data.pages[HITAGS_CONFIG_PADR], rx, HITAGS_PAGE_SIZE - 1);
|
||||
|
||||
//check which memorysize this tag has
|
||||
if ((conf_pages[0] & 0x3) == 0x00) {
|
||||
if ((tag.data.s.CON0 & 0x3) == 0x00) {
|
||||
tag.max_page = 32 / 32;
|
||||
} else if ((conf_pages[0] & 0x3) == 0x1) {
|
||||
} else if ((tag.data.s.CON0 & 0x3) == 0x1) {
|
||||
tag.max_page = 256 / 32;
|
||||
} else if ((conf_pages[0] & 0x3) == 0x2) {
|
||||
} else if ((tag.data.s.CON0 & 0x3) == 0x2) {
|
||||
tag.max_page = 2048 / 32;
|
||||
}
|
||||
|
||||
conf_pages[1] = rx[1];
|
||||
tag.auth = (conf_pages[1] >> 7) & 0x1;
|
||||
tag.TTFC = (conf_pages[1] >> 6) & 0x1;
|
||||
tag.TTFDR = (conf_pages[1] >> 5) & 0x3;
|
||||
tag.TTFM = (conf_pages[1] >> 3) & 0x3;
|
||||
tag.LCON = (conf_pages[1] >> 1) & 0x1;
|
||||
tag.LKP = (conf_pages[1] >> 0) & 0x1;
|
||||
DBG Dbprintf("conf 0: %02X conf 1: %02X conf 2: %02X", tag.data.pages[HITAGS_CONFIG_PADR][0], tag.data.pages[HITAGS_CONFIG_PADR][1], tag.data.pages[HITAGS_CONFIG_PADR][2]);
|
||||
|
||||
conf_pages[2] = rx[2];
|
||||
|
||||
tag.LCK7 = (conf_pages[2] >> 7) & 0x1;
|
||||
tag.LCK6 = (conf_pages[2] >> 6) & 0x1;
|
||||
tag.LCK5 = (conf_pages[2] >> 5) & 0x1;
|
||||
tag.LCK4 = (conf_pages[2] >> 4) & 0x1;
|
||||
tag.LCK3 = (conf_pages[2] >> 3) & 0x1;
|
||||
tag.LCK2 = (conf_pages[2] >> 2) & 0x1;
|
||||
tag.LCK1 = (conf_pages[2] >> 1) & 0x1;
|
||||
tag.LCK0 = (conf_pages[2] >> 0) & 0x1;
|
||||
|
||||
DBG Dbprintf("conf 0: %02X conf 1: %02X conf 2: %02X", conf_pages[0], conf_pages[1], conf_pages[2]);
|
||||
|
||||
if (tag.auth == 1) {
|
||||
if (tag.data.s.auth == 1) {
|
||||
|
||||
uint64_t key = 0;
|
||||
// if the tag is in authentication mode try the key or challenge
|
||||
|
@ -1269,7 +1172,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
|||
((uint64_t)packet->key[5]) << 40
|
||||
;
|
||||
|
||||
uint64_t state = ht2_hitag2_init(REV64(key), REV32(tag.uid), REV32(rnd));
|
||||
uint64_t state = ht2_hitag2_init(REV64(key), reflect32(tag.data.s.uid_le), REV32(rnd));
|
||||
|
||||
uint8_t auth_ks[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
@ -1353,7 +1256,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
|||
}
|
||||
|
||||
//encrypted con2,password received.
|
||||
DBG Dbprintf("UID... %X", tag.uid);
|
||||
DBG Dbprintf("UID... %X", BSWAP_32(tag.data.s.uid_le));
|
||||
DBG Dbprintf("RND... %X", rnd);
|
||||
|
||||
//decrypt password
|
||||
|
@ -1362,7 +1265,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
|||
pwdl1 = 0;
|
||||
if (packet->cmd == RHTSF_KEY || packet->cmd == WHTSF_KEY) {
|
||||
|
||||
uint64_t state = ht2_hitag2_init(REV64(key), REV32(tag.uid), REV32(rnd));
|
||||
uint64_t state = ht2_hitag2_init(REV64(key), reflect32(tag.data.s.uid_le), REV32(rnd));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ht2_hitag2_byte(&state);
|
||||
}
|
||||
|
@ -1421,27 +1324,27 @@ void hts_read(const lf_hitag_data_t *payload, bool ledcontrol) {
|
|||
|
||||
//save received data - 40 bits
|
||||
for (int i = 0; i < 4 && i < rxlen; i++) { // set page bytes from received bits
|
||||
tag.pages[pageNum][i] = rx[i];
|
||||
tag.data.pages[pageNum][i] = rx[i];
|
||||
}
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED) {
|
||||
if (tag.auth && tag.LKP && pageNum == 1) {
|
||||
if (tag.data.s.auth && tag.data.s.LKP && pageNum == 1) {
|
||||
DBG Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum, pwdh0,
|
||||
(tag.pages[pageNum][2]) & 0xff,
|
||||
(tag.pages[pageNum][1]) & 0xff,
|
||||
tag.pages[pageNum][0] & 0xff);
|
||||
tag.data.pages[pageNum][2],
|
||||
tag.data.pages[pageNum][1],
|
||||
tag.data.pages[pageNum][0]);
|
||||
} else {
|
||||
DBG Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum,
|
||||
(tag.pages[pageNum][3]) & 0xff,
|
||||
(tag.pages[pageNum][2]) & 0xff,
|
||||
(tag.pages[pageNum][1]) & 0xff,
|
||||
tag.pages[pageNum][0] & 0xff);
|
||||
tag.data.pages[pageNum][3],
|
||||
tag.data.pages[pageNum][2],
|
||||
tag.data.pages[pageNum][1],
|
||||
tag.data.pages[pageNum][0]);
|
||||
}
|
||||
}
|
||||
|
||||
pageNum++;
|
||||
//display key and password if possible
|
||||
if (pageNum == 2 && tag.auth == 1 && tag.LKP) {
|
||||
if (pageNum == 2 && tag.data.s.auth == 1 && tag.data.s.LKP) {
|
||||
if (payload->cmd == RHTSF_KEY) {
|
||||
DBG Dbprintf("Page[ 2]: %02X %02X %02X %02X",
|
||||
payload->key[1],
|
||||
|
@ -1473,7 +1376,7 @@ read_end:
|
|||
hts_stop_clock();
|
||||
set_tracing(false);
|
||||
lf_finalize(ledcontrol);
|
||||
reply_ng(CMD_LF_HITAGS_READ, status, (uint8_t *)tag.pages, sizeof(tag.pages));
|
||||
reply_ng(CMD_LF_HITAGS_READ, status, (uint8_t *)tag.data.pages, sizeof(tag.data.pages));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1610,10 +1513,10 @@ int hts_read_uid(uint32_t *uid, bool ledcontrol, bool send_answer) {
|
|||
int status = PM3_SUCCESS;
|
||||
if (rxlen == 32) {
|
||||
|
||||
memcpy(&tag.pages[0], rx, HITAGS_PAGE_SIZE);
|
||||
tag.uid = (rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]);
|
||||
memcpy(&tag.data.pages[0], rx, HITAGS_PAGE_SIZE);
|
||||
|
||||
if (uid) {
|
||||
*uid = tag.uid;
|
||||
*uid = BSWAP_32(tag.data.s.uid_le);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -1624,7 +1527,7 @@ int hts_read_uid(uint32_t *uid, bool ledcontrol, bool send_answer) {
|
|||
hts_stop_clock();
|
||||
set_tracing(false);
|
||||
lf_finalize(ledcontrol);
|
||||
reply_ng(CMD_LF_HITAGS_UID, status, (uint8_t *)tag.pages, sizeof(tag.pages));
|
||||
reply_ng(CMD_LF_HITAGS_UID, status, (uint8_t *)tag.data.pages, sizeof(tag.data.pages));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define HITAGS_BLOCK_SIZE 16
|
||||
#define HITAGS_MAX_PAGES 64
|
||||
#define HITAGS_MAX_BYTE_SIZE (HITAGS_MAX_PAGES * HITAGS_PAGE_SIZE)
|
||||
#define HITAGS_UID_PADR 0
|
||||
#define HITAGS_CONFIG_PADR 1
|
||||
|
||||
// need to see which limits these cards has
|
||||
|
@ -126,31 +127,48 @@ typedef enum SOF_TYPE {
|
|||
|
||||
struct hitagS_tag {
|
||||
PSTATE pstate; // protocol-state
|
||||
TSATE tstate; // tag-state
|
||||
uint32_t uid;
|
||||
uint8_t pages[64][4];
|
||||
uint64_t key;
|
||||
uint8_t pwdl0, pwdl1, pwdh0;
|
||||
// con0
|
||||
TSATE tstate; // tag-state
|
||||
|
||||
int max_page;
|
||||
stype mode;
|
||||
// con1
|
||||
bool auth; // 0 = Plain 1 = Auth
|
||||
bool TTFC; // Transponder Talks first coding. 0 = Manchester 1 = Biphase
|
||||
int TTFDR; // data rate in TTF Mode
|
||||
int TTFM; // the number of pages that are sent to the RWD
|
||||
bool LCON; // 0 = con1/2 read write 1 =con1 read only and con2 OTP
|
||||
bool LKP; // 0 = page2/3 read write 1 =page2/3 read only in Plain mode and no access in authenticate mode
|
||||
// con2
|
||||
// 0 = read write 1 = read only
|
||||
bool LCK7; // page4/5
|
||||
bool LCK6; // page6/7
|
||||
bool LCK5; // page8-11
|
||||
bool LCK4; // page12-15
|
||||
bool LCK3; // page16-23
|
||||
bool LCK2; // page24-31
|
||||
bool LCK1; // page32-47
|
||||
bool LCK0; // page48-63
|
||||
};
|
||||
|
||||
union {
|
||||
uint8_t pages[64][4];
|
||||
struct {
|
||||
// page 0
|
||||
uint32_t uid_le;
|
||||
|
||||
// page 1
|
||||
uint8_t CON0;
|
||||
// con1
|
||||
bool LKP : 1; // 0 = page2/3 read write 1 =page2/3 read only in Plain mode and no access in authenticate mode
|
||||
bool LCON : 1; // 0 = con1/2 read write 1 =con1 read only and con2 OTP
|
||||
int TTFM : 2; // the number of pages that are sent to the RWD
|
||||
int TTFDR : 2; // data rate in TTF Mode
|
||||
bool TTFC : 1; // Transponder Talks first coding. 0 = Manchester 1 = Biphase
|
||||
bool auth : 1; // 0 = Plain 1 = Auth
|
||||
// con2
|
||||
// 0 = read write 1 = read only
|
||||
bool LCK0 : 1; // page48-63
|
||||
bool LCK1 : 1; // page32-47
|
||||
bool LCK2 : 1; // page24-31
|
||||
bool LCK3 : 1; // page16-23
|
||||
bool LCK4 : 1; // page12-15
|
||||
bool LCK5 : 1; // page8-11
|
||||
bool LCK6 : 1; // page6/7
|
||||
bool LCK7 : 1; // page4/5
|
||||
// reserved/pwdh0
|
||||
uint8_t pwdh0;
|
||||
|
||||
// page 2
|
||||
uint8_t pwdl0;
|
||||
uint8_t pwdl1;
|
||||
uint64_t key : 48;
|
||||
|
||||
// page 4
|
||||
} s;
|
||||
} data;
|
||||
|
||||
} PACKED;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue