mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
add: 82xx config parse
This commit is contained in:
parent
cd4c2834a6
commit
d361cd863c
4 changed files with 64 additions and 116 deletions
|
@ -153,11 +153,11 @@ static void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitco
|
||||||
|
|
||||||
static void update_tag_max_page(void) {
|
static void update_tag_max_page(void) {
|
||||||
//check which memorysize this tag has
|
//check which memorysize this tag has
|
||||||
if ((tag.data.s.CON0 & 0x3) == 0x00) {
|
if (tag.data.s.config.MEMT == 0x00) {
|
||||||
tag.max_page = 32 / (HITAGS_PAGE_SIZE * 8) - 1;
|
tag.max_page = 32 / (HITAGS_PAGE_SIZE * 8) - 1;
|
||||||
} else if ((tag.data.s.CON0 & 0x3) == 0x1) {
|
} else if (tag.data.s.config.MEMT == 0x1) {
|
||||||
tag.max_page = 256 / (HITAGS_PAGE_SIZE * 8) - 1;
|
tag.max_page = 256 / (HITAGS_PAGE_SIZE * 8) - 1;
|
||||||
} else if ((tag.data.s.CON0 & 0x3) == 0x2) {
|
} else if (tag.data.s.config.MEMT == 0x2) {
|
||||||
tag.max_page = 2048 / (HITAGS_PAGE_SIZE * 8) - 1;
|
tag.max_page = 2048 / (HITAGS_PAGE_SIZE * 8) - 1;
|
||||||
} else {
|
} else {
|
||||||
tag.max_page = HITAGS_MAX_PAGES - 1;
|
tag.max_page = HITAGS_MAX_PAGES - 1;
|
||||||
|
@ -545,7 +545,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
|
|
||||||
//send con2, pwdh0, pwdl0, pwdl1 encrypted as a response
|
//send con2, pwdh0, pwdl0, pwdl1 encrypted as a response
|
||||||
tx[0] = ht2_hitag2_byte(&state) ^ tag.data.pages[HITAGS_CONFIG_PADR][2];
|
tx[0] = ht2_hitag2_byte(&state) ^ tag.data.pages[HITAGS_CONFIG_PADR][2];
|
||||||
tx[1] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdh0;
|
tx[1] = ht2_hitag2_byte(&state) ^ tag.data.s.config.pwdh0;
|
||||||
tx[2] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl0;
|
tx[2] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl0;
|
||||||
tx[3] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl1;
|
tx[3] = ht2_hitag2_byte(&state) ^ tag.data.s.pwdl1;
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
*txlen += 8;
|
*txlen += 8;
|
||||||
crc = CRC_PRESET;
|
crc = CRC_PRESET;
|
||||||
calc_crc(&crc, tag.data.pages[HITAGS_CONFIG_PADR][2], 8);
|
calc_crc(&crc, tag.data.pages[HITAGS_CONFIG_PADR][2], 8);
|
||||||
calc_crc(&crc, tag.data.s.pwdh0, 8);
|
calc_crc(&crc, tag.data.s.config.pwdh0, 8);
|
||||||
calc_crc(&crc, tag.data.s.pwdl0, 8);
|
calc_crc(&crc, tag.data.s.pwdl0, 8);
|
||||||
calc_crc(&crc, tag.data.s.pwdl1, 8);
|
calc_crc(&crc, tag.data.s.pwdl1, 8);
|
||||||
tx[4] = (crc ^ ht2_hitag2_byte(&state));
|
tx[4] = (crc ^ ht2_hitag2_byte(&state));
|
||||||
|
@ -612,7 +612,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
*txlen = 32;
|
*txlen = 32;
|
||||||
memcpy(tx, tag.data.pages[page], HITAGS_PAGE_SIZE);
|
memcpy(tx, tag.data.pages[page], HITAGS_PAGE_SIZE);
|
||||||
|
|
||||||
if (tag.data.s.auth && page == HITAGS_CONFIG_PADR) {
|
if (tag.data.s.config.auth && page == HITAGS_CONFIG_PADR) {
|
||||||
tx[3] = 0xFF;
|
tx[3] = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +626,7 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
tx[4] = crc;
|
tx[4] = crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.data.s.auth && tag.data.s.LKP && (page == 2 || page == 3)) {
|
if (tag.data.s.config.auth && tag.data.s.config.LKP && (page == 2 || page == 3)) {
|
||||||
//if reader asks for key or password and the LKP-mark is set do not respond
|
//if reader asks for key or password and the LKP-mark is set do not respond
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
}
|
}
|
||||||
|
@ -650,8 +650,8 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
|
|
||||||
} else if ((rx[0] & 0xf0) == HITAGS_WRITE_PAGE) { //write page
|
} else if ((rx[0] & 0xf0) == HITAGS_WRITE_PAGE) { //write page
|
||||||
// TODO: handle con2 LCK*
|
// TODO: handle con2 LCK*
|
||||||
if ((tag.data.s.LCON && page == 1)
|
if ((tag.data.s.config.LCON && page == 1)
|
||||||
|| (tag.data.s.LKP && (page == 2 || page == 3))) {
|
|| (tag.data.s.config.LKP && (page == 2 || page == 3))) {
|
||||||
//deny
|
//deny
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -664,8 +664,8 @@ static void hts_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
|
|
||||||
} else if ((rx[0] & 0xf0) == HITAGS_WRITE_BLOCK) { //write block
|
} else if ((rx[0] & 0xf0) == HITAGS_WRITE_BLOCK) { //write block
|
||||||
// TODO: handle LCON con2 LCK*
|
// TODO: handle LCON con2 LCK*
|
||||||
if ((tag.data.s.LCON && page == 1)
|
if ((tag.data.s.config.LCON && page == 1)
|
||||||
|| (tag.data.s.LKP && (page == 2 || page == 3))) {
|
|| (tag.data.s.config.LKP && (page == 2 || page == 3))) {
|
||||||
//deny
|
//deny
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1146,7 +1146,7 @@ static int hts_select_tag(const lf_hitag_data_t *packet, uint8_t *tx, size_t siz
|
||||||
|
|
||||||
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]);
|
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]);
|
||||||
|
|
||||||
if (tag.data.s.auth == 1) {
|
if (tag.data.s.config.auth == 1) {
|
||||||
|
|
||||||
uint64_t key_le = 0;
|
uint64_t key_le = 0;
|
||||||
// if the tag is in authentication mode try the key or challenge
|
// if the tag is in authentication mode try the key or challenge
|
||||||
|
|
|
@ -282,7 +282,7 @@ static int CmdLFHitagSRead(const char *Cmd) {
|
||||||
|
|
||||||
lf_hts_read_response_t *card = (lf_hts_read_response_t *)resp.data.asBytes;
|
lf_hts_read_response_t *card = (lf_hts_read_response_t *)resp.data.asBytes;
|
||||||
|
|
||||||
hitags_config_t config = hitags_config_unpack(card->config_page.asBytes);
|
hitags_config_t config = card->config_page.s;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
|
@ -297,7 +297,7 @@ static int CmdLFHitagSRead(const char *Cmd) {
|
||||||
const int hts_mem_sizes[] = {1, 8, 64, 64};
|
const int hts_mem_sizes[] = {1, 8, 64, 64};
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
count = hts_mem_sizes[config.memory_type] - page;
|
count = hts_mem_sizes[config.MEMT] - page;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int page_end = page + count;
|
// int page_end = page + count;
|
||||||
|
@ -447,45 +447,38 @@ static int CmdLFHitagSList(const char *Cmd) {
|
||||||
return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags");
|
return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags");
|
||||||
}
|
}
|
||||||
|
|
||||||
hitags_config_t hitags_config_unpack(const uint8_t *config_bytes) {
|
|
||||||
hitags_config_t result = {
|
|
||||||
.memory_type = (config_bytes[0] >> 0) & 0x03,
|
|
||||||
.authentication = (config_bytes[1] >> 7) & 0x01,
|
|
||||||
.ttf_coding = (config_bytes[1] >> 6) & 0x01,
|
|
||||||
.ttf_data_rate = (config_bytes[1] >> 4) & 0x03,
|
|
||||||
.ttf_mode = (config_bytes[1] >> 2) & 0x03,
|
|
||||||
.lock_config = (config_bytes[1] >> 1) & 0x01,
|
|
||||||
.lock_key = (config_bytes[1] >> 0) & 0x01
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hitags_config_print(hitags_config_t config) {
|
void hitags_config_print(hitags_config_t config) {
|
||||||
PrintAndLogEx(INFO, " Memory type...... " _GREEN_("%s"),
|
PrintAndLogEx(INFO, " Memory type...... " _GREEN_("%s"),
|
||||||
(const char *[]) {
|
(const char *[]) {
|
||||||
"Hitag S 32", "Hitag S 256", "Hitag S 2048",
|
"Hitag S 32", "Hitag S 256", "Hitag S 2048",
|
||||||
"Unknown Hitag S/8211"
|
"Unknown Hitag S/8211"
|
||||||
}[config.memory_type]);
|
}[config.MEMT]);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " Authenticaion.... %s", config.authentication ? _YELLOW_("Yes") : "No");
|
PrintAndLogEx(INFO, " Authenticaion.... %s", config.auth ? _YELLOW_("Yes") : "No");
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " TTF coding....... %s",
|
PrintAndLogEx(INFO, " TTF coding....... %s",
|
||||||
(const char *[]) {"Manchester", "Biphase"}[config.ttf_coding]);
|
config.RES3 ? "FSK 0=RF/10 1=RF/8" : (const char *[]){"Manchester", "Biphase"}[config.TTFC]);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " TTF data rate.... %s",
|
PrintAndLogEx(INFO, " TTF data rate.... %s",
|
||||||
(const char *[]) {
|
(const char *[]) {
|
||||||
"4 kBit", "8 kBit", "2 kBit",
|
"4 kBit", "8 kBit", "2 kBit",
|
||||||
"2 kBit and Pigeon Race Standard"
|
"2 kBit and Pigeon Race Standard"
|
||||||
}[config.ttf_data_rate]);
|
}[config.TTFDR]);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " TTF mode......... %s",
|
PrintAndLogEx(INFO, " TTF mode......... %s",
|
||||||
(const char *[]){
|
(const char *[]){
|
||||||
"TTF Mode disabled (= RTF Mode)", "Page 4, Page 5",
|
"TTF Mode disabled (= RTF Mode)",
|
||||||
"Page 4, Page 5, Page 6, Page 7", "Page 4"
|
"Page 4, Page 5",
|
||||||
}[config.ttf_mode]);
|
"Page 4, Page 5, Page 6, Page 7",
|
||||||
|
"Page 4",
|
||||||
|
"TTF Mode disabled (= RTF Mode)",
|
||||||
|
"Page 4, Page 5, Page 6",
|
||||||
|
"Page 4, Page 5, Page 6, Page 7, Page 8",
|
||||||
|
"Page 4, Page 5, Page 6, Page 7, Page 8, Page 9, Page 10, Page 11",
|
||||||
|
}[config.RES0 << 2 | config.TTFM]);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " Config locked.... %s", config.lock_config ? _RED_("Yes") : _GREEN_("No"));
|
PrintAndLogEx(INFO, " Config locked.... %s", config.LCON ? _RED_("Yes") : _GREEN_("No"));
|
||||||
PrintAndLogEx(INFO, " Key/PWD locked... %s", config.lock_key ? _RED_("Yes") : _GREEN_("No"));
|
PrintAndLogEx(INFO, " Key/PWD locked... %s", config.LKP ? _RED_("Yes") : _GREEN_("No"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
|
|
|
@ -20,45 +20,11 @@
|
||||||
#define CMDLFHITAGS_H__
|
#define CMDLFHITAGS_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "hitag.h"
|
||||||
typedef struct {
|
|
||||||
enum {
|
|
||||||
HITAGS_MEMORY_32,
|
|
||||||
HITAGS_MEMORY_256,
|
|
||||||
HITAGS_MEMORY_2048,
|
|
||||||
HITAGS_MEMORY_UNKNOWN
|
|
||||||
} memory_type;
|
|
||||||
|
|
||||||
bool authentication;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
HITAGS_CODING_MANCHESTER,
|
|
||||||
HITAGS_CODING_BIPHASE
|
|
||||||
} ttf_coding;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
HITAGS_DR_4KBIT,
|
|
||||||
HITAGS_DR_8KBIT,
|
|
||||||
HITAGS_DR_2KBIT,
|
|
||||||
HITAGS_DR_2KBIT_PIGEON
|
|
||||||
} ttf_data_rate;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
HITAGS_TTF_DISABLED,
|
|
||||||
HITAGS_TTF_PAGE45,
|
|
||||||
HITAGS_TTF_PAGE4567,
|
|
||||||
HITAGS_TTF_PAGE4
|
|
||||||
} ttf_mode;
|
|
||||||
|
|
||||||
bool lock_config;
|
|
||||||
bool lock_key;
|
|
||||||
} hitags_config_t;
|
|
||||||
|
|
||||||
int CmdLFHitagS(const char *Cmd);
|
int CmdLFHitagS(const char *Cmd);
|
||||||
|
|
||||||
int read_hts_uid(void);
|
int read_hts_uid(void);
|
||||||
hitags_config_t hitags_config_unpack(const uint8_t *config_bytes);
|
|
||||||
void hitags_config_pack(hitags_config_t config, uint8_t *out);
|
|
||||||
void hitags_config_print(hitags_config_t config);
|
void hitags_config_print(hitags_config_t config);
|
||||||
|
|
||||||
#endif //CMDLFHITAGS_H__
|
#endif //CMDLFHITAGS_H__
|
||||||
|
|
|
@ -120,26 +120,21 @@ typedef enum SOF_TYPE {
|
||||||
HT_NO_BITS
|
HT_NO_BITS
|
||||||
} stype;
|
} stype;
|
||||||
|
|
||||||
struct hitagS_tag {
|
typedef struct {
|
||||||
PSTATE pstate; // protocol-state
|
// con0
|
||||||
TSATE tstate; // tag-state
|
uint8_t MEMT : 2;
|
||||||
|
bool RES0 : 1; // for 82xx. Enable somekind extended TTF mode in conjunction with TTFM
|
||||||
|
bool RES1 : 1;
|
||||||
|
bool RES2 : 1;
|
||||||
|
bool RES3 : 1; // for 82xx. Enable TTF FSK mode 0=RF/10 1=RF/8
|
||||||
|
bool RES4 : 1;
|
||||||
|
bool RES5 : 1;
|
||||||
|
|
||||||
int max_page;
|
|
||||||
stype mode;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint8_t pages[64][4];
|
|
||||||
struct {
|
|
||||||
// page 0
|
|
||||||
uint32_t uid_le;
|
|
||||||
|
|
||||||
// page 1
|
|
||||||
uint8_t CON0;
|
|
||||||
// con1
|
// con1
|
||||||
bool LKP : 1; // 0 = page2/3 read write 1 =page2/3 read only in Plain mode and no access in authenticate mode
|
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
|
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
|
uint8_t TTFM : 2; // the number of pages that are sent to the RWD
|
||||||
int TTFDR : 2; // data rate in TTF Mode
|
uint8_t TTFDR : 2; // data rate in TTF Mode
|
||||||
bool TTFC : 1; // Transponder Talks first coding. 0 = Manchester 1 = Biphase
|
bool TTFC : 1; // Transponder Talks first coding. 0 = Manchester 1 = Biphase
|
||||||
bool auth : 1; // 0 = Plain 1 = Auth
|
bool auth : 1; // 0 = Plain 1 = Auth
|
||||||
// con2
|
// con2
|
||||||
|
@ -154,6 +149,22 @@ struct hitagS_tag {
|
||||||
bool LCK7 : 1; // page4/5
|
bool LCK7 : 1; // page4/5
|
||||||
// reserved/pwdh0
|
// reserved/pwdh0
|
||||||
uint8_t pwdh0;
|
uint8_t pwdh0;
|
||||||
|
} PACKED hitags_config_t;
|
||||||
|
|
||||||
|
struct hitagS_tag {
|
||||||
|
PSTATE pstate; // protocol-state
|
||||||
|
TSATE tstate; // tag-state
|
||||||
|
|
||||||
|
int max_page;
|
||||||
|
stype mode;
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint8_t pages[64][4];
|
||||||
|
struct {
|
||||||
|
// page 0
|
||||||
|
uint32_t uid_le;
|
||||||
|
|
||||||
|
hitags_config_t config;
|
||||||
|
|
||||||
// page 2
|
// page 2
|
||||||
uint8_t pwdl0;
|
uint8_t pwdl0;
|
||||||
|
@ -169,29 +180,7 @@ struct hitagS_tag {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
uint8_t asBytes[HITAGS_PAGE_SIZE];
|
uint8_t asBytes[HITAGS_PAGE_SIZE];
|
||||||
struct {
|
hitags_config_t s;
|
||||||
// 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;
|
|
||||||
}s;
|
|
||||||
} config_page;
|
} config_page;
|
||||||
int8_t pages_reason[HITAGS_MAX_PAGES];
|
int8_t pages_reason[HITAGS_MAX_PAGES];
|
||||||
uint8_t pages[HITAGS_MAX_PAGES][HITAGS_PAGE_SIZE];
|
uint8_t pages[HITAGS_MAX_PAGES][HITAGS_PAGE_SIZE];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue