Merge pull request #2466 from douniwan5788/hitag_protocol

Move Hitag cmds to protocols.h
This commit is contained in:
Iceman 2024-08-23 21:13:08 +02:00 committed by GitHub
commit d9dc0a0e84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 84 additions and 66 deletions

View file

@ -31,6 +31,7 @@
#include "lfdemod.h" #include "lfdemod.h"
#include "commonutil.h" #include "commonutil.h"
#include "appmain.h" #include "appmain.h"
#include "protocols.h"
#define test_bit(data, i) (*(data + (i/8)) >> (7-(i % 8))) & 1 #define test_bit(data, i) (*(data + (i/8)) >> (7-(i % 8))) & 1
#define set_bit(data, i) *(data + (i/8)) |= (1 << (7-(i % 8))) #define set_bit(data, i) *(data + (i/8)) |= (1 << (7-(i % 8)))
@ -210,9 +211,9 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
// Try to find out which command was send by selecting on length (in bits) // Try to find out which command was send by selecting on length (in bits)
switch (rxlen) { switch (rxlen) {
// Received 11000 from the reader, request for UID, send UID // Received 11000 from the reader, request for UID, send UID
case 05: { case 5: {
// Always send over the air in the clear plaintext mode // Always send over the air in the clear plaintext mode
if (rx_air[0] != 0xC0) { if (rx_air[0] != HITAG2_START_AUTH) {
// Unknown frame ? // Unknown frame ?
return; return;
} }
@ -234,13 +235,13 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
switch (rx[0] & 0xC6) { switch (rx[0] & 0xC6) {
// Read command: 11xx x00y // Read command: 11xx x00y
case 0xC0: { case HITAG2_READ_PAGE: {
memcpy(tx, tag.sectors[sector], 4); memcpy(tx, tag.sectors[sector], 4);
*txlen = 32; *txlen = 32;
break; break;
} }
// Inverted Read command: 01xx x10y // Inverted Read command: 01xx x10y
case 0x44: { case HITAG2_READ_PAGE_INVERTED: {
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
tx[i] = tag.sectors[sector][i] ^ 0xff; tx[i] = tag.sectors[sector][i] ^ 0xff;
} }
@ -248,7 +249,7 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
break; break;
} }
// Write command: 10xx x01y // Write command: 10xx x01y
case 0x82: { case HITAG2_WRITE_PAGE: {
// Prepare write, acknowledge by repeating command // Prepare write, acknowledge by repeating command
memcpy(tx, rx, nbytes(rxlen)); memcpy(tx, rx, nbytes(rxlen));
*txlen = rxlen; *txlen = rxlen;
@ -447,13 +448,13 @@ void fix_ac_decoding(uint8_t *input, size_t len) {
// looks at number of received bits. // looks at number of received bits.
// 0 = collision? // 0 = collision?
// 32 = good response // 32 = good response
static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { static bool hitag1_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) {
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
case 0: { case 0: {
// retry waking up card // retry waking up card
/*tx[0] = 0xb0; // Rev 3.0*/ /*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = 0x30; // Rev 2.0 tx[0] = HITAG1_SET_CC; // Rev 2.0
*txlen = 5; *txlen = 5;
if (!bCollision) blocknr--; if (!bCollision) blocknr--;
if (blocknr < 0) { if (blocknr < 0) {
@ -471,7 +472,7 @@ static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *tx
uint8_t crc; uint8_t crc;
if (bCollision) { if (bCollision) {
// Select card by serial from response // Select card by serial from response
tx[0] = 0x00 | rx[0] >> 5; tx[0] = HITAG1_SELECT | rx[0] >> 5;
tx[1] = rx[0] << 3 | rx[1] >> 5; tx[1] = rx[0] << 3 | rx[1] >> 5;
tx[2] = rx[1] << 3 | rx[2] >> 5; tx[2] = rx[1] << 3 | rx[2] >> 5;
tx[3] = rx[2] << 3 | rx[3] >> 5; tx[3] = rx[2] << 3 | rx[3] >> 5;
@ -497,7 +498,7 @@ static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *tx
} }
// read next page of card until done // read next page of card until done
Dbprintf("Reading page %02u", blocknr); Dbprintf("Reading page %02u", blocknr);
tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE tx[0] = HITAG1_RDPPAGE | blocknr >> 4; // RDPPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx, 12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
@ -523,7 +524,7 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
case 0: { case 0: {
// retry waking up card // retry waking up card
/*tx[0] = 0xb0; // Rev 3.0*/ /*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = 0x30; // Rev 2.0 tx[0] = HITAG1_SELECT; // Rev 2.0
*txlen = 5; *txlen = 5;
if (bCrypto && byte_value <= 0xff) { if (bCrypto && byte_value <= 0xff) {
// to retry // to retry
@ -553,7 +554,7 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
// will receive 32 bit encrypted Logdata // will receive 32 bit encrypted Logdata
} else if (bCrypto) { } else if (bCrypto) {
// authed, start reading // authed, start reading
tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE tx[0] = HITAG1_RDCPAGE | blocknr >> 4; // RDCPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx, 12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
@ -566,7 +567,7 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
case 32: { case 32: {
if (bCollision) { if (bCollision) {
// Select card by serial from response // Select card by serial from response
tx[0] = 0x00 | rx[0] >> 5; tx[0] = HITAG1_SELECT | rx[0] >> 5;
tx[1] = rx[0] << 3 | rx[1] >> 5; tx[1] = rx[0] << 3 | rx[1] >> 5;
tx[2] = rx[1] << 3 | rx[2] >> 5; tx[2] = rx[1] << 3 | rx[2] >> 5;
tx[3] = rx[2] << 3 | rx[3] >> 5; tx[3] = rx[2] << 3 | rx[3] >> 5;
@ -580,7 +581,7 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
// will receive 32-bit configuration page // will receive 32-bit configuration page
} else if (bSelecting) { } else if (bSelecting) {
// Initiate auth // Initiate auth
tx[0] = 0xa0 | (key_no); // WRCPAGE tx[0] = HITAG1_WRCPAGE | (key_no); // WRCPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx, 12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
@ -620,7 +621,7 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
return false; return false;
/* /*
// read next page of card until done // read next page of card until done
tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE tx[0] = HITAG1_RDCPAGE | blocknr >> 4; // RDCPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx, 12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
@ -648,7 +649,7 @@ static bool hitag2_write_page(uint8_t *rx, const size_t rxlen, uint8_t *tx, size
switch (writestate) { switch (writestate) {
case WRITE_STATE_START: { case WRITE_STATE_START: {
*txlen = 10; *txlen = 10;
tx[0] = 0x82 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[0] = HITAG2_WRITE_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
writestate = WRITE_STATE_PAGENUM_WRITTEN; writestate = WRITE_STATE_PAGENUM_WRITTEN;
break; break;
@ -656,7 +657,7 @@ static bool hitag2_write_page(uint8_t *rx, const size_t rxlen, uint8_t *tx, size
case WRITE_STATE_PAGENUM_WRITTEN: { case WRITE_STATE_PAGENUM_WRITTEN: {
// Check if page number was received correctly // Check if page number was received correctly
if ((rxlen == 10) if ((rxlen == 10)
&& (rx[0] == (0x82 | (blocknr << 3) | ((blocknr ^ 7) >> 2))) && (rx[0] == (HITAG2_WRITE_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2)))
&& (rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) { && (rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) {
*txlen = 32; *txlen = 32;
@ -748,7 +749,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
} }
*txlen = 10; *txlen = 10;
tx[0] = 0xC0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[0] = HITAG2_READ_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
} }
} }
@ -871,7 +872,7 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
return false; return false;
} else { } else {
*txlen = 10; *txlen = 10;
tx[0] = 0xc0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[0] = HITAG2_READ_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
} }
} }
@ -957,7 +958,7 @@ static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
DBG Dbprintf("Sending read block %u", blocknr); DBG Dbprintf("Sending read block %u", blocknr);
*txlen = 10; *txlen = 10;
tx[0] = 0xc0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[0] = HITAG2_READ_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
} }
} }
@ -1819,7 +1820,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
tx = txbuf; tx = txbuf;
switch (payload->cmd) { switch (payload->cmd) {
case RHT1F_PLAIN: { case RHT1F_PLAIN: {
bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); bStop = !hitag1_plain(rx, rxlen, tx, &txlen, false);
break; break;
} }
case RHT1F_AUTHENTICATE: { case RHT1F_AUTHENTICATE: {
@ -2628,7 +2629,7 @@ int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_fiel
// start AUTH command // start AUTH command
size_t txlen = 5; size_t txlen = 5;
uint8_t tx[1] = {0xC0}; uint8_t tx[] = {HITAG2_START_AUTH};
// Transmit as reader // Transmit as reader
ht2_send(turn_on, &command_start, &command_duration, &response_start, tx, txlen, false); ht2_send(turn_on, &command_start, &command_duration, &response_start, tx, txlen, false);

View file

@ -32,6 +32,7 @@
#include "hitag2/hitag2_crypto.h" #include "hitag2/hitag2_crypto.h"
#include "lfadc.h" #include "lfadc.h"
#include "crc.h" #include "crc.h"
#include <protocols.h>
#define CRC_PRESET 0xFF #define CRC_PRESET 0xFF
#define CRC_POLYNOM 0x1D #define CRC_POLYNOM 0x1D
@ -455,7 +456,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
tag.pstate = HT_READY; tag.pstate = HT_READY;
tag.tstate = HT_NO_OP; tag.tstate = HT_NO_OP;
if ((rx[0] & 0xf0) == 0x30) { if ((rx[0] & 0xf0) == HITAGS_UID_REQ_STD) {
if (g_dbglevel >= DBG_EXTENDED) if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("HT_STANDARD"); Dbprintf("HT_STANDARD");
@ -463,7 +464,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
sof_bits = 1; sof_bits = 1;
m = AC2K; m = AC2K;
} }
if ((rx[0] & 0xf0) == 0xc0) { if ((rx[0] & 0xf0) == HITAGS_UID_REQ_ADV) {
tag.mode = HT_ADVANCED; tag.mode = HT_ADVANCED;
if (g_dbglevel >= DBG_EXTENDED) if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("HT_ADVANCED"); Dbprintf("HT_ADVANCED");
@ -472,7 +473,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
m = AC2K; m = AC2K;
} }
if ((rx[0] & 0xf0) == 0xd0) { if ((rx[0] & 0xf0) == HITAGS_UID_REQ_FADV) {
if (g_dbglevel >= DBG_EXTENDED) if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("HT_FAST_ADVANCED"); Dbprintf("HT_FAST_ADVANCED");
@ -493,7 +494,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
DbpString("SELECT"); DbpString("SELECT");
} }
if (check_select(rx, tag.uid) == 1) { if ((rx[0] & 0xf8) == HITAGS_SELECT && check_select(rx, tag.uid) == 1) {
if (g_dbglevel >= DBG_EXTENDED) { if (g_dbglevel >= DBG_EXTENDED) {
DbpString("SELECT match"); DbpString("SELECT match");
} }
@ -581,7 +582,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
} }
case 40: { case 40: {
if (g_dbglevel >= DBG_EXTENDED) if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("WRITE"); Dbprintf("WRITE DATA");
//data received to be written //data received to be written
if (tag.tstate == HT_WRITING_PAGE_DATA) { if (tag.tstate == HT_WRITING_PAGE_DATA) {
tag.tstate = HT_NO_OP; tag.tstate = HT_NO_OP;
@ -616,7 +617,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
} }
case 20: { case 20: {
//write page, write block, read page or read block command received //write page, write block, read page or read block command received
if ((rx[0] & 0xf0) == 0xc0) { //read page if ((rx[0] & 0xf0) == HITAGS_READ_PAGE) { //read page
//send page data //send page data
uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
*txlen = 32; *txlen = 32;
@ -647,7 +648,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
*txlen = 0; *txlen = 0;
} }
} else if ((rx[0] & 0xf0) == 0xd0) { //read block } 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) * 16) + ((rx[1] & 0xf0) / 16);
*txlen = 32 * 4; *txlen = 32 * 4;
@ -677,7 +678,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
*txlen = 0; *txlen = 0;
} }
} else if ((rx[0] & 0xf0) == 0x80) { //write page } 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) * 16) + ((rx[1] & 0xf0) / 16);
@ -693,7 +694,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
tag.tstate = HT_WRITING_PAGE_DATA; tag.tstate = HT_WRITING_PAGE_DATA;
} }
} else if ((rx[0] & 0xf0) == 0x90) { //write block } 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) * 6) + ((rx[1] & 0xf0) / 16);
hitagS_set_frame_modulation(); hitagS_set_frame_modulation();
@ -1236,8 +1237,8 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo
// UID request FAdvanced 11010 // UID request FAdvanced 11010
size_t txlen = 0; size_t txlen = 0;
size_t rxlen = 0; size_t rxlen = 0;
uint8_t cmd = 0x18; // 11000 UID Request Advanced uint8_t cmd = HITAGS_UID_REQ_ADV;
txlen = concatbits(tx, txlen, &cmd, 8 - 5, 5); txlen = concatbits(tx, txlen, &cmd, 0, 5);
sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, true); sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, true);
if (rxlen != 32) { if (rxlen != 32) {
@ -1253,8 +1254,8 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo
//select uid //select uid
txlen = 0; txlen = 0;
cmd = 0x00; // 00000 SELECT UID cmd = HITAGS_SELECT;
txlen = concatbits(tx, txlen, &cmd, 8 - 5, 5); txlen = concatbits(tx, txlen, &cmd, 0, 5);
txlen = concatbits(tx, txlen, rx, 0, 32); txlen = concatbits(tx, txlen, rx, 0, 32);
uint8_t crc = CRC8Hitag1Bits(tx, txlen); uint8_t crc = CRC8Hitag1Bits(tx, txlen);
txlen = concatbits(tx, txlen, &crc, 0, 8); txlen = concatbits(tx, txlen, &crc, 0, 8);
@ -1432,8 +1433,8 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
//send read request //send read request
size_t txlen = 0; size_t txlen = 0;
uint8_t cmd = 0x0c; // 1100 READ PAGE uint8_t cmd = HITAGS_READ_PAGE;
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4); txlen = concatbits(tx, txlen, &cmd, 0, 4);
uint8_t addr = pageNum; uint8_t addr = pageNum;
txlen = concatbits(tx, txlen, &addr, 0, 8); txlen = concatbits(tx, txlen, &addr, 0, 8);
uint8_t crc = CRC8Hitag1Bits(tx, txlen); uint8_t crc = CRC8Hitag1Bits(tx, txlen);
@ -1537,8 +1538,8 @@ void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
//send write page request //send write page request
txlen = 0; txlen = 0;
uint8_t cmd = 0x08; // 1000 WRITE PAGE uint8_t cmd = HITAGS_WRITE_PAGE;
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4); txlen = concatbits(tx, txlen, &cmd, 0, 4);
uint8_t addr = payload->page; uint8_t addr = payload->page;
txlen = concatbits(tx, txlen, &addr, 0, 8); txlen = concatbits(tx, txlen, &addr, 0, 8);

View file

@ -522,6 +522,13 @@ bool hitag2_get_plain(uint8_t *plain, uint8_t *plen) {
return false; return false;
} }
// HITAG 2 commands
#define HITAG2_BINSTR_START_AUTH "11000" // get UID and/or start the authentication process
#define HITAG2_BINSTR_READ_PAGE "11" // read page after auth
#define HITAG2_BINSTR_READ_PAGE_INVERTED "01" // as read page but all bits inverted
#define HITAG2_BINSTR_WRITE_PAGE "10" // write page after auth
#define HITAG2_BINSTR_HALT "00" // silence currently authenticated tag
static uint8_t hitag2_get_page(const char *bs) { static uint8_t hitag2_get_page(const char *bs) {
if ((memcmp(bs + 2, "000", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "111", 3) == 0)) { if ((memcmp(bs + 2, "000", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "111", 3) == 0)) {
return 0; return 0;
@ -578,24 +585,24 @@ void hitag2_annotate_plain(char *exp, size_t size, const uint8_t *cmd, uint8_t c
break; break;
} }
case 10: { case 10: {
if (memcmp(binstr, HITAG2_HALT, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_HALT, 2) == 0) {
snprintf(exp, size, " "); snprintf(exp, size, " ");
break; break;
} }
uint8_t page = hitag2_get_page(binstr); uint8_t page = hitag2_get_page(binstr);
if (memcmp(binstr, HITAG2_READ_PAGE, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE, 2) == 0) {
snprintf(exp, size, "READ PAGE (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "READ PAGE (" _MAGENTA_("%u") ")", page);
break; break;
} }
if (memcmp(binstr, HITAG2_READ_PAGE_INVERTED, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE_INVERTED, 2) == 0) {
snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page);
break; break;
} }
if (memcmp(binstr, HITAG2_WRITE_PAGE, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_WRITE_PAGE, 2) == 0) {
snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page);
break; break;
} }
@ -654,7 +661,7 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize,
case 5: { case 5: {
annotateHitag2_init(); annotateHitag2_init();
if (memcmp(binstr, HITAG2_START_AUTH, 5) == 0) { if (memcmp(binstr, HITAG2_BINSTR_START_AUTH, 5) == 0) {
snprintf(exp, size, "START AUTH"); snprintf(exp, size, "START AUTH");
_ht2state.state = STATE_START_AUTH; _ht2state.state = STATE_START_AUTH;
} else { } else {
@ -669,7 +676,7 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize,
break; break;
} }
if (memcmp(binstr, HITAG2_HALT, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_HALT, 2) == 0) {
snprintf(exp, size, "HALT"); snprintf(exp, size, "HALT");
_ht2state.state = STATE_HALT; _ht2state.state = STATE_HALT;
break; break;
@ -677,17 +684,17 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize,
uint8_t page = hitag2_get_page(binstr); uint8_t page = hitag2_get_page(binstr);
if (memcmp(binstr, HITAG2_READ_PAGE, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE, 2) == 0) {
snprintf(exp, size, "READ PAGE (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "READ PAGE (" _MAGENTA_("%u") ")", page);
break; break;
} }
if (memcmp(binstr, HITAG2_READ_PAGE_INVERTED, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE_INVERTED, 2) == 0) {
snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page);
break; break;
} }
if (memcmp(binstr, HITAG2_WRITE_PAGE, 2) == 0) { if (memcmp(binstr, HITAG2_BINSTR_WRITE_PAGE, 2) == 0) {
snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page); snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page);
break; break;
} }

View file

@ -897,30 +897,39 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define CALYPSO_SAM_SV_RELOAD 0x56 #define CALYPSO_SAM_SV_RELOAD 0x56
// HITAG 1 commands // HITAG 1 commands
#define HITAG1_SET_CCNEW 0xC2 // left 5 bits only #define HITAG1_SET_CC 0x30 // higher 5 bits only
#define HITAG1_SET_CCNEW 0xC8 // higher 5 bits only
#define HITAG1_READ_ID 0x00 // not a real command, consists of 5 bits length, <length> bits partial SN, 8 bits CRC #define HITAG1_READ_ID 0x00 // not a real command, consists of 5 bits length, <length> bits partial SN, 8 bits CRC
#define HITAG1_SELECT 0x00 // left 5 bits only, followed by 32 bits SN and 8 bits CRC #define HITAG1_SELECT 0x00 // higher 5 bits only, followed by 32 bits SN and 8 bits CRC
#define HITAG1_WRPPAGE 0x80 // left 4 bits only, followed by 8 bits page and 8 bits CRC #define HITAG1_WRPPAGE 0x80 // higher 4 bits only, followed by 8 bits page and 8 bits CRC
#define HITAG1_WRPBLK 0x90 // left 4 bits only, followed by 8 bits block and 8 bits CRC #define HITAG1_WRPBLK 0x90 // higher 4 bits only, followed by 8 bits block and 8 bits CRC
#define HITAG1_WRCPAGE 0xA0 // left 4 bits only, followed by 8 bits page or key information and 8 bits CRC #define HITAG1_WRCPAGE 0xA0 // higher 4 bits only, followed by 8 bits page or key information and 8 bits CRC
#define HITAG1_WRCBLK 0xB0 // left 4 bits only, followed by 8 bits block and 8 bits CRC #define HITAG1_WRCBLK 0xB0 // higher 4 bits only, followed by 8 bits block and 8 bits CRC
#define HITAG1_RDPPAGE 0xC0 // left 4 bits only, followed by 8 bits page and 8 bits CRC #define HITAG1_RDPPAGE 0xC0 // higher 4 bits only, followed by 8 bits page and 8 bits CRC
#define HITAG1_RDPBLK 0xD0 // left 4 bits only, followed by 8 bits block and 8 bits CRC #define HITAG1_RDPBLK 0xD0 // higher 4 bits only, followed by 8 bits block and 8 bits CRC
#define HITAG1_RDCPAGE 0xE0 // left 4 bits only, followed by 8 bits page and 8 bits CRC #define HITAG1_RDCPAGE 0xE0 // higher 4 bits only, followed by 8 bits page and 8 bits CRC
#define HITAG1_RDCBLK 0xF0 // left 4 bits only, followed by 8 bits block and 8 bits CRC #define HITAG1_RDCBLK 0xF0 // higher 4 bits only, followed by 8 bits block and 8 bits CRC
#define HITAG1_HALT 0x70 // left 4 bits only, followed by 8 bits (dummy) page and 8 bits CRC #define HITAG1_HALT 0x70 // higher 4 bits only, followed by 8 bits (dummy) page and 8 bits CRC
// HITAG 2 commands // HITAG 2 commands
#define HITAG2_START_AUTH "11000" // get UID and/or start the authentication process #define HITAG2_START_AUTH 0xC0 // left 5 bits only
#define HITAG2_READ_PAGE "11" // read page after auth #define HITAG2_READ_PAGE 0xC0 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits
#define HITAG2_READ_PAGE_INVERTED "01" // as read page but all bits inverted #define HITAG2_READ_PAGE_INVERTED 0x44 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits
#define HITAG2_WRITE_PAGE "10" // write page after auth #define HITAG2_WRITE_PAGE 0x82 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits
#define HITAG2_HALT "00" // silence currently authenticated tag #define HITAG2_HALT 0x00 // left 5 bits only
// HITAG S commands // HITAG S commands
#define HITAGS_QUIET 0x70 #define HITAGS_UID_REQ_STD 0x30 // 00110 UID REQUEST Std
//inverted in bit 0 and following 2 bits #define HITAGS_UID_REQ_ADV 0xC0 // 11000 UID REQUEST Adv
#define HITAGS_WRITE_BLOCK 0x90 #define HITAGS_UID_REQ_ADV2 0xC8 // 11001 UID REQUEST Adv
#define HITAGS_UID_REQ_FADV 0xD0 // 11010 UID REQUEST FAdv
#define HITAGS_SELECT 0x00 // 00000 SELECT (UID)
#define HITAGS_READ_PAGE 0xC0 // 1100 READ PAGE
#define HITAGS_READ_BLOCK 0xD0 // 1101 READ BLOCK
#define HITAGS_WRITE_PAGE 0x80 // 1000 WRITE PAGE
#define HITAGS_WRITE_BLOCK 0x90 // 1001 WRITE BLOCK
#define HITAGS_QUIET 0x70 // 0111 QUIET
// LTO-CM commands // LTO-CM commands
#define LTO_REQ_STANDARD 0x45 #define LTO_REQ_STANDARD 0x45