Refactor Hitag low-level functions into hitag_common

This commit is contained in:
douniwan5788
2025-03-19 17:05:39 +08:00
parent 4c74704aa1
commit 3d0c8cab5c
12 changed files with 696 additions and 684 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ else
endif
ifneq (,$(findstring WITH_HITAG,$(APP_CFLAGS)))
SRC_HITAG = hitag2_crypto.c hitag2.c hitagS.c hitag2_crack.c
SRC_HITAG = hitag2_crypto.c hitag_common.c hitag2.c hitagS.c hitag2_crack.c
APP_CFLAGS += -I../common/hitag2
else
SRC_HITAG =
+2 -2
View File
@@ -1200,7 +1200,7 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content
hts_simulate((bool)packet->oldarg[0], packet->data.asBytes, true);
hts_simulate((bool)packet->oldarg[0], packet->oldarg[1], packet->data.asBytes, true);
break;
}
case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file
@@ -1218,7 +1218,7 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_LF_HITAGS_UID: {
hts_read_uid(NULL, false, true);
hts_read_uid(NULL, true, true);
break;
}
case CMD_LF_HITAG2_WRITE: {
+45 -633
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -24,7 +24,7 @@
#include "common.h"
#include "hitag.h"
void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol);
void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, bool ledcontrol);
void hts_read(const lf_hitag_data_t *payload, bool ledcontrol);
void hts_write_page(const lf_hitag_data_t *payload, bool ledcontrol);
void hts_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol);
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
#ifndef HITAG_COMMON_H
#define HITAG_COMMON_H
#include "hitag.h"
// Sam7s has several timers, we will use the source TIMER_CLOCK3 (aka AT91C_TC_CLKS_TIMER_DIV3_CLOCK)
// TIMER_CLOCK3 = MCK/32, MCK is running at 48 MHz, Timer is running at 48MHz/32 = 1500 KHz
// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
// T0 = TIMER_CLOCK3 / 125000 = 12
#define T0 12
#define HITAG_FRAME_LEN 20
// TC0 and TC1 are 16-bit counters and will overflow after 5461 * T0
// Ensure not to set these timings above 5461 (~43ms) when comparing without considering overflow, as they will never reach that value.
#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */
#define HITAG_T_0 20 /* T[0] should be 18..22 */
#define HITAG_T_1 28 /* T[1] should be 26..32 */
#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
#define HITAG_T_1_MIN 25 /* T[1] should be 26..32 */
#define HITAG_T_STOP 36 /* T_EOF should be > 36 */
#define HITAG_T_CODE_VIOLATION 36 /* Hitag µ TFcv should be 34..38 */
#define HITAG_T_EOF 80 /* T_EOF should be > 36 */
#define HITAG_T_WAIT_RESP 200 /* T_wresp should be 204..212 */
#define HITAG_T_WAIT_SC 200 /* T_wsc should be 90..5000 */
#define HITAG_T_WAIT_FIRST 300 /* T_wfc should be 280..565 (T_ttf) */
#define HITAG_T_PROG_MAX 750 /* T_prog should be 716..726 */
#define HITAG_T_TAG_ONE_HALF_PERIOD 10
#define HITAG_T_TAG_TWO_HALF_PERIOD 25
#define HITAG_T_TAG_THREE_HALF_PERIOD 41
#define HITAG_T_TAG_FOUR_HALF_PERIOD 57
#define HITAG_T_TAG_HALF_PERIOD 16
#define HITAG_T_TAG_FULL_PERIOD 32
#define HITAG_T_TAG_CAPTURE_ONE_HALF 13
#define HITAG_T_TAG_CAPTURE_TWO_HALF 25
#define HITAG_T_TAG_CAPTURE_THREE_HALF 41
#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57
extern uint16_t timestamp_high;
#define TIMESTAMP ( (AT91C_BASE_TC2->TC_SR & AT91C_TC_COVFS) ? timestamp_high += 1 : 0, ((timestamp_high << 16) + AT91C_BASE_TC2->TC_CV) / T0)
// Common hitag functions
void hitag_setup_fpga(uint16_t conf, uint8_t threshold, bool ledcontrol);
void hitag_cleanup(bool ledcontrol);
void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol, bool send_sof);
void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol, MOD modulation,
int sof_bits);
void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, int *overflow);
void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, MOD modulation, bool ledcontrol);
#endif
-3
View File
@@ -793,9 +793,6 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize,
free(binstr);
}
void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response) {
}
static const char *identify_transponder_hitag2(uint32_t uid) {
switch (uid) {
-1
View File
@@ -31,7 +31,6 @@ int ht2_read_uid(void);
int ht2_read_paxton(void);
void annotateHitag1(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response);
void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, uint8_t bits, bool is_response, const uint64_t *keys, uint32_t keycount, bool isdecrypted);
void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response);
void annotateHitag2_init(void);
bool hitag2_get_plain(uint8_t *plain, uint8_t *plen);
+37 -38
View File
@@ -36,6 +36,8 @@
static int CmdHelp(const char *Cmd);
void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response) {}
static const char *hts_get_type_str(uint32_t uid) {
// source 1: https://www.scorpio-lk.com/downloads/Tango/HITAG_Classification.pdf
// IDE Mark
@@ -88,7 +90,7 @@ static bool hts_get_uid(uint32_t *uid) {
}
if (resp.status != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - failed getting UID");
PrintAndLogEx(DEBUG, "DEBUG: Error - failed getting Hitag S UID");
return false;
}
@@ -253,10 +255,38 @@ static void print_error(int8_t reason) {
break;
default:
// PM3_REASON_UNKNOWN
PrintAndLogEx(DEBUG, "DEBUG: Error - Hitag S failed");
PrintAndLogEx(FAILED, "Error - Hitag S failed");
}
}
static void hitags_config_print(hitags_config_t config) {
PrintAndLogEx(INFO, " Memory type...... " _GREEN_("%s"),
(const char *[]) {"Hitag S 32", "Hitag S 256", "Hitag S 2048", "Unknown Hitag S/8211"}[config.MEMT]);
PrintAndLogEx(INFO, " Authenticaion.... %s", config.auth ? _YELLOW_("Yes") : "No");
PrintAndLogEx(INFO, " TTF coding....... %s",
config.RES3 ? "FSK 0=RF/10 1=RF/8" : (const char *[]) {"Manchester", "Biphase"}[config.TTFC]);
PrintAndLogEx(INFO, " TTF data rate.... %s",
(const char *[]) {"4 kBit", "8 kBit", "2 kBit", "2 kBit and Pigeon Race Standard"}[config.TTFDR]);
PrintAndLogEx(INFO, " TTF mode......... %s",
(const char *[]) {
"TTF Mode disabled (= RTF Mode)",
"Page 4, Page 5",
"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.LCON ? _RED_("Yes") : _GREEN_("No"));
PrintAndLogEx(INFO, " Key/PWD locked... %s", config.LKP ? _RED_("Yes") : _GREEN_("No"));
}
static int CmdLFHitagSRead(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hitag hts rdbl",
@@ -868,20 +898,23 @@ static int CmdLFHitagSSim(const char *Cmd) {
"Simulate Hitag S transponder\n"
"You need to `lf hitag hts eload` first",
"lf hitag hts sim\n"
"lf hitag hts sim --82xx");
"lf hitag hts sim --82xx\n"
"lf hitag hts sim -t 30 -> set threshold to 30");
void *argtable[] = {
arg_param_begin,
arg_lit0("8", "82xx", "simulate 8268/8310"),
arg_int0("t", "threshold", "<dec>", "set edge detect threshold (def: 127)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
// bool use_82xx = arg_get_lit(ctx, 1); // not implemented yet
int threshold = arg_get_int_def(ctx, 2, 127);
CLIParserFree(ctx);
clearCommandBuffer();
SendCommandMIX(CMD_LF_HITAGS_SIMULATE, false, 0, 0, NULL, 0);
SendCommandMIX(CMD_LF_HITAGS_SIMULATE, false, threshold, 0, NULL, 0);
return PM3_SUCCESS;
}
@@ -889,40 +922,6 @@ static int CmdLFHitagSList(const char *Cmd) {
return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags");
}
void hitags_config_print(hitags_config_t config) {
PrintAndLogEx(INFO, " Memory type...... " _GREEN_("%s"),
(const char *[]) {
"Hitag S 32", "Hitag S 256", "Hitag S 2048",
"Unknown Hitag S/8211"
}[config.MEMT]);
PrintAndLogEx(INFO, " Authenticaion.... %s", config.auth ? _YELLOW_("Yes") : "No");
PrintAndLogEx(INFO, " TTF coding....... %s",
config.RES3 ? "FSK 0=RF/10 1=RF/8" : (const char *[]) {"Manchester", "Biphase"}[config.TTFC]);
PrintAndLogEx(INFO, " TTF data rate.... %s",
(const char *[]) {
"4 kBit", "8 kBit", "2 kBit",
"2 kBit and Pigeon Race Standard"
}[config.TTFDR]);
PrintAndLogEx(INFO, " TTF mode......... %s",
(const char *[]) {
"TTF Mode disabled (= RTF Mode)",
"Page 4, Page 5",
"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.LCON ? _RED_("Yes") : _GREEN_("No"));
PrintAndLogEx(INFO, " Key/PWD locked... %s", config.LKP ? _RED_("Yes") : _GREEN_("No"));
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"},
+2 -1
View File
@@ -22,9 +22,10 @@
#include "common.h"
#include "hitag.h"
void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response);
int CmdLFHitagS(const char *Cmd);
int read_hts_uid(void);
void hitags_config_print(hitags_config_t config);
#endif //CMDLFHITAGS_H__
+1
View File
@@ -28,6 +28,7 @@
#include "comms.h" // for sending cmds to device. GetFromBigBuf
#include "fileutils.h" // for saveFile
#include "cmdlfhitag.h" // annotate hitag
#include "cmdlfhitaghts.h" // annotate hitags
#include "pm3_cmd.h" // tracelog_hdr_t
#include "cliparser.h" // args..
+11 -4
View File
@@ -41,11 +41,18 @@
// need to see which limits these cards has
#define HITAG1_MAX_BYTE_SIZE 64
#define HITAGU_MAX_BYTE_SIZE 64
#define HITAG_MAX_BYTE_SIZE (64 * HITAG_BLOCK_SIZE)
#define HITAG_MAX_BYTE_SIZE (64 * HITAG_BLOCK_SIZE)
#define HITAG2_CONFIG_BLOCK 3
// Modulation types - used by shared code
typedef enum modulation {
AC2K = 0, // Amplitude modulation 2000 bits/s
AC4K, // Amplitude modulation 4000 bits/s
MC4K, // Manchester modulation 4000 bits/s
MC8K // Manchester modulation 8000 bits/s
} MOD;
typedef enum {
HTSF_PLAIN,
HTSF_82xx,
@@ -125,7 +132,7 @@ struct hitagS_tag {
int max_page;
union {
uint8_t pages[64][4];
uint8_t pages[HITAGS_MAX_PAGES][HITAGS_PAGE_SIZE];
struct {
// page 0
uint32_t uid_le;
@@ -147,7 +154,7 @@ typedef struct {
hitag_function cmd;
uint8_t page;
uint8_t page_count;
uint8_t data[HITAGS_PAGE_SIZE];
uint8_t data[HITAG_BLOCK_SIZE];
uint8_t NrAr[HITAG_NRAR_SIZE];
// unaligned access to key as uint64_t will abort.
// todo: Why does the compiler without -munaligned-access generate unaligned-access code in the first place?