Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Hitag S get uid #2510

Merged
merged 3 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 28 additions & 42 deletions armsrc/hitagS.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static void hitag_reader_send_bit(int bit, bool ledcontrol) {
if (ledcontrol) LED_A_ON();
// Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV > 0);
while (AT91C_BASE_TC0->TC_CV != 0);

// Binary puls length modulation (BPLM) is used to encode the data stream
// This means that a transmission of a one takes longer than that of a zero
Expand Down Expand Up @@ -334,7 +334,7 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool
}
// send EOF
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV > 0);
while (AT91C_BASE_TC0->TC_CV != 0);
HIGH(GPIO_SSC_DOUT);

// Wait for 4-10 times the carrier period
Expand Down Expand Up @@ -362,22 +362,18 @@ static void hts_init_clock(void) {
// TC1: Capture mode, clock source = MCK/32 (TIMER_CLOCK3), TIOA is external trigger,
// external trigger falling edge, set RA on falling edge of TIOA.
AT91C_BASE_TC1->TC_CMR =
AT91C_TC_CLKS_TIMER_DIV3_CLOCK |
AT91C_TC_ETRGEDG_FALLING | // external trigger on falling edge
AT91C_TC_ABETRG | // TIOA is used as an external trigger.
AT91C_TC_LDRA_FALLING | // load RA on on falling edge
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit)

AT91C_BASE_TC1->TC_RA = 1; // clear carry bit on next clock cycle
AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK/32 (TIMER_CLOCK3)
AT91C_TC_ETRGEDG_FALLING | // external trigger on falling edge
AT91C_TC_ABETRG | // TIOA is used as an external trigger
AT91C_TC_LDRA_FALLING; // load RA on on falling edge

// Enable and reset counters
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;

// synchronized startup procedure
// In theory, with MCK/32, we shouldn't be waiting longer than 32 instruction statements, right?
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero
while (AT91C_BASE_TC0->TC_CV != 0) {}; // wait until TC0 returned to zero

}

Expand Down Expand Up @@ -440,13 +436,9 @@ static void hts_set_frame_modulation(void) {
*/
static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
uint8_t *tx, size_t *txlen) {
uint8_t rx_air[HITAG_FRAME_LEN];
uint64_t state;
unsigned char crc;

// Copy the (original) received frame how it is send over the air
memcpy(rx_air, rx, nbytes(rxlen));

// Reset the transmission frame length
*txlen = 0;

Expand All @@ -458,21 +450,21 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
tag.pstate = HT_READY;
tag.tstate = HT_NO_OP;

if ((rx[0] & 0xf0) == HITAGS_UID_REQ_STD) {
if (rx[0] == HITAGS_UID_REQ_STD) {
DBG Dbprintf("HT_STANDARD");
tag.mode = HT_STANDARD;
sof_bits = 1;
m = AC2K;
}

if ((rx[0] & 0xf0) == HITAGS_UID_REQ_ADV) {
if (rx[0] == HITAGS_UID_REQ_ADV) {
DBG Dbprintf("HT_ADVANCED");
tag.mode = HT_ADVANCED;
sof_bits = 3;
m = AC2K;
}

if ((rx[0] & 0xf0) == HITAGS_UID_REQ_FADV) {
if (rx[0] == HITAGS_UID_REQ_FADV) {
DBG Dbprintf("HT_FAST_ADVANCED");
tag.mode = HT_FAST_ADVANCED;
sof_bits = 3;
Expand Down Expand Up @@ -612,7 +604,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
//write page, write block, read page or read block command received
if ((rx[0] & 0xf0) == HITAGS_READ_PAGE) { //read page
//send page data
uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
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];
Expand Down Expand Up @@ -643,7 +635,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,

} else if ((rx[0] & 0xf0) == HITAGS_READ_BLOCK) { //read block

uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
uint8_t page = ((rx[0] & 0x0f) << 4) + ((rx[1] & 0xf0) >> 4);
*txlen = 32 * 4;

//send page,...,page+3 data
Expand Down Expand Up @@ -673,7 +665,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,

} else if ((rx[0] & 0xf0) == HITAGS_WRITE_PAGE) { //write page

uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
uint8_t page = ((rx[0] & 0x0f) << 4) + ((rx[1] & 0xf0) >> 4);

if ((tag.LCON && page == 1)
|| (tag.LKP && (page == 2 || page == 3))) {
Expand All @@ -689,7 +681,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,

} else if ((rx[0] & 0xf0) == HITAGS_WRITE_BLOCK) { //write block

uint8_t page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16);
uint8_t page = ((rx[0] & 0x0f) << 4) + ((rx[1] & 0xf0) >> 4);
hts_set_frame_modulation();

if (page % 4 != 0 || page == 0) {
Expand Down Expand Up @@ -723,8 +715,7 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) {
int response = 0, overflow = 0;
uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0;
uint8_t txbuf[HITAG_FRAME_LEN];
uint8_t *tx = txbuf;
uint8_t tx[HITAG_FRAME_LEN];
size_t txlen = 0;

// Reset the received frame, frame count and timing info
Expand All @@ -739,20 +730,12 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) {
clear_trace();

DbpString("Starting Hitag S simulation");
if (ledcontrol) LED_D_ON();

tag.pstate = HT_READY;
tag.tstate = HT_NO_OP;

// read tag data into memory
if (tag_mem_supplied) {

for (int i = 0; i < 16; i++) {
for (int j = 0; j < 4; j++) {
tag.pages[i][j] = 0x0;
}
}

DbpString("Loading hitag S memory...");
memcpy((uint8_t *)tag.pages, data, 4 * 64);
} else {
Expand Down Expand Up @@ -888,7 +871,9 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) {
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;

// synchronized startup procedure
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
while (AT91C_BASE_TC0->TC_CV != 0); // wait until TC0 returned to zero

if (ledcontrol) LED_D_ON();

while ((BUTTON_PRESS() == false) && (data_available() == false)) {

Expand Down Expand Up @@ -997,7 +982,7 @@ static void hts_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint3

// Dbprintf("TC0_CV:%i TC1_CV:%i TC1_RA:%i", AT91C_BASE_TC0->TC_CV, AT91C_BASE_TC1->TC_CV ,AT91C_BASE_TC1->TC_RA);

// Receive frame, watch for at most T0*HITAG_T_PROG_MAX periods
// Receive tag frame, watch for at most T0*HITAG_T_PROG_MAX periods
while (AT91C_BASE_TC0->TC_CV < (T0 * HITAG_T_PROG_MAX)) {

// Check if falling edge in tag modulation is detected
Expand Down Expand Up @@ -1129,7 +1114,7 @@ static void hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_
if (ac_seq) {

// Tag Response is AC encoded
// We used UID Request Advanced, meaning AC SEQ header is 111.
// We used UID Request Advanced, meaning AC SEQ SOF is 111.
for (int i = 7; i < rxlen; i += 2) {

rx[k / 8] |= response_bit[i] << (7 - (k % 8));
Expand Down Expand Up @@ -1226,7 +1211,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, true);

if (rxlen != 32) {
DBG DbpString("UID Request failed!");
DbpString("UID Request failed!");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

place back the DBG guard

return -1;
}

Expand All @@ -1245,7 +1230,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);

if (rxlen != 40) {
DBG Dbprintf("Select UID failed! %i", rxlen);
Dbprintf("Select UID failed! %i", rxlen);
return -1;
}

Expand Down Expand Up @@ -1350,7 +1335,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);

if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) {
DBG Dbprintf("no write access on page " _YELLOW_("64") ". not 82xx?");
Dbprintf("no write access on page " _YELLOW_("64") ". not 82xx?");
return -1;
}

Expand All @@ -1362,23 +1347,23 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);

if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) {
DBG Dbprintf("write to page " _YELLOW_("64") " failed! wrong password?");
Dbprintf("write to page " _YELLOW_("64") " failed! wrong password?");
return -1;
}

return 0;
} else if (packet->cmd == RHTSF_PLAIN || packet->cmd == WHTSF_PLAIN) {
DBG Dbprintf("Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode");
Dbprintf("Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode");
return -1;
} else {
DBG Dbprintf("Error, unknown function: " _RED_("%d"), packet->cmd);
Dbprintf("Error, unknown function: " _RED_("%d"), packet->cmd);
return -1;
}

hts_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);

if (rxlen != 40) {
DBG Dbprintf("Authenticate failed! " _RED_("%i"), rxlen);
Dbprintf("Authenticate failed! " _RED_("%i"), rxlen);
return -1;
}

Expand Down Expand Up @@ -1640,6 +1625,7 @@ 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]);
if (uid) {
*uid = tag.uid;
Expand Down
2 changes: 1 addition & 1 deletion client/src/cmdlfem410x.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ static int CmdEM410xClone(const char *Cmd) {
}

packet.cmd = WHTSF_82xx;
memcpy(packet.pwd, (uint8_t[]) {0xBB, 0xDD, 0x33, 0x99}, 4);
memcpy(packet.pwd, "\xBB\xDD\x33\x99", 4);
SendCommandNG(CMD_LF_HITAGS_WRITE, (uint8_t *)&packet, sizeof(packet));
if (WaitForResponseTimeout(CMD_LF_HITAGS_WRITE, &resp, 4000) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
Expand Down
16 changes: 7 additions & 9 deletions client/src/cmdlfhitaghts.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static int CmdLFHitagSRead(const char *Cmd) {
" 8268/8310 password mode: \n"
" - default password BBDD3399\n",
" lf hitag hts rdbl -> Hitag S/8211, plain mode\n"
" lf hitag hts rdbl --8 -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts rdbl --82xx -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts rdbl --nrar 0102030411223344 -> Hitag S, challenge mode\n"
" lf hitag hts rdbl --crypto -> Hitag S, crypto mode, def key\n"
" lf hitag hts rdbl -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
Expand Down Expand Up @@ -187,8 +187,6 @@ static int CmdLFHitagSRead(const char *Cmd) {
lf_hitag_data_t packet;
memset(&packet, 0, sizeof(packet));

int pm3cmd = CMD_LF_HITAGS_READ;

if (use_nrar) {
packet.cmd = RHTSF_CHALLENGE;
memcpy(packet.NrAr, nrar, sizeof(packet.NrAr));
Expand All @@ -205,10 +203,10 @@ static int CmdLFHitagSRead(const char *Cmd) {
}

clearCommandBuffer();
SendCommandNG(pm3cmd, (uint8_t *) &packet, sizeof(packet));
SendCommandNG(CMD_LF_HITAGS_READ, (uint8_t *) &packet, sizeof(packet));

PacketResponseNG resp;
if (WaitForResponseTimeout(pm3cmd, &resp, 2000) == false) {
if (WaitForResponseTimeout(CMD_LF_HITAGS_READ, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
return PM3_ETIMEOUT;
Expand All @@ -226,7 +224,7 @@ static int CmdLFHitagSRead(const char *Cmd) {

uint8_t *data = resp.data.asBytes;

hitags_config_t config = hitags_config_unpack(data + HITAGS_PAGE_SIZE);
hitags_config_t config = hitags_config_unpack(&data[HITAGS_PAGE_SIZE * HITAGS_CONFIG_PADR]);

PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
Expand Down Expand Up @@ -254,7 +252,7 @@ static int CmdLFHitagSWrite(const char *Cmd) {
" 8268/8310 password mode: \n"
" - default password BBDD3399\n",
" lf hitag hts wrbl -p 6 -d 01020304 -> Hitag S/8211, plain mode\n"
" lf hitag hts wrbl -p 6 -d 01020304 --8 -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts wrbl -p 6 -d 01020304 --82xx -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts wrbl -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n"
" lf hitag hts wrbl -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n"
" lf hitag hts wrbl -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
Expand All @@ -263,7 +261,7 @@ static int CmdLFHitagSWrite(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
arg_lit0(NULL, "8", "8268/8310 mode"),
arg_lit0("8", "82xx", "8268/8310 mode"),
arg_lit0(NULL, "crypto", "crypto mode"),
arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
arg_int1("p", "page", "<dec>", "page address to write to"),
Expand Down Expand Up @@ -327,7 +325,7 @@ static int CmdLFHitagSWrite(const char *Cmd) {
use_crypto = true;
}
if ((key_len == 0) && use_82xx) {
memcpy(key, (uint8_t[]) {0xBB, 0xDD, 0x33, 0x99}, 4);
memcpy(key, "\xBB\xDD\x33\x99", 4);
key_len = 4;
}
if ((key_len == 0) && use_crypto) {
Expand Down
4 changes: 3 additions & 1 deletion include/hitag.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@
#define HITAG_PASSWORD_SIZE 4
#define HITAG_UID_SIZE 4
#define HITAG_BLOCK_SIZE 4

#define HITAG2_MAX_BLOCKS 8
#define HITAG2_MAX_BYTE_SIZE (HITAG2_MAX_BLOCKS * HITAG_BLOCK_SIZE)

#define HITAGS_NRAR_SIZE 8
#define HITAGS_CRYPTOKEY_SIZE 6
#define HITAGS_UID_SIZE 4
#define HITAGS_PAGE_SIZE 4
#define HITAGS_BLOCK_SIZE 4
#define HITAGS_BLOCK_SIZE 16
#define HITAGS_MAX_PAGES 64
#define HITAGS_MAX_BYTE_SIZE (HITAGS_MAX_PAGES * HITAGS_PAGE_SIZE)
#define HITAGS_CONFIG_PADR 1

// need to see which limits these cards has
#define HITAG1_MAX_BYTE_SIZE 64
Expand Down
Loading