mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
Merge branch 'master' into purring-basilisk
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
commit
9343014b68
37 changed files with 7056 additions and 5149 deletions
|
@ -3,9 +3,12 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
|
||||||
- Removed `save_restoreDB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2)
|
- Removed `save_restoreDB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2)
|
||||||
- Removed `save_restoreGB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2)
|
- Removed `save_restoreGB` - replaced by `buffer_savestate_t` implementation (@HACKhalo2)
|
||||||
|
- Changed `lf hitag dump --nrar` - now supports attack 1 from "gone in 360 seconds" paper. Thanks @kevsecurity! (@iceman1001)
|
||||||
|
- Added `lf hitag selftest` - converted from RFIDLers selftest (@iceman1001)
|
||||||
|
- Added `lf hitag chk` - dictionary attack against card (@iceman1001)
|
||||||
|
- Added `lf hitag lookup` - verify collected challenges aginst dictionary (@iceman1001)
|
||||||
- Updated windows workflow to use latest setup-wsl script (@iceman1001)
|
- Updated windows workflow to use latest setup-wsl script (@iceman1001)
|
||||||
- Added a micro second clock in the client (@iceman1001)
|
- Added a micro second clock in the client (@iceman1001)
|
||||||
- Fix `hf mfdes read` - buffer overflow when reading large files (@iceman1001)
|
- Fix `hf mfdes read` - buffer overflow when reading large files (@iceman1001)
|
||||||
|
|
|
@ -71,7 +71,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring WITH_HITAG,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_HITAG,$(APP_CFLAGS)))
|
||||||
SRC_HITAG = hitag2_crypto.c hitag2.c hitagS.c
|
SRC_HITAG = hitag2_crypto.c hitag2.c hitagS.c hitag2_crack.c
|
||||||
APP_CFLAGS += -I../common/hitag2
|
APP_CFLAGS += -I../common/hitag2
|
||||||
else
|
else
|
||||||
SRC_HITAG =
|
SRC_HITAG =
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "thinfilm.h"
|
#include "thinfilm.h"
|
||||||
#include "felica.h"
|
#include "felica.h"
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
|
#include "hitag2_crack.h"
|
||||||
#include "hitagS.h"
|
#include "hitagS.h"
|
||||||
#include "em4x50.h"
|
#include "em4x50.h"
|
||||||
#include "em4x70.h"
|
#include "em4x70.h"
|
||||||
|
@ -1131,7 +1132,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
#ifdef WITH_HITAG
|
#ifdef WITH_HITAG
|
||||||
case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type
|
case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type
|
||||||
SniffHitag2(true);
|
SniffHitag2(true);
|
||||||
// SniffHitag2(packet->oldarg[0]);
|
//hitag_sniff();
|
||||||
reply_ng(CMD_LF_HITAG_SNIFF, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_HITAG_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1139,8 +1140,24 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
SimulateHitag2(true);
|
SimulateHitag2(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_LF_HITAG2_CRACK: {
|
||||||
|
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
|
||||||
|
ht2_crack(payload->NrAr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function
|
case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function
|
||||||
ReaderHitag((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes, true);
|
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
|
||||||
|
|
||||||
|
switch (payload->cmd) {
|
||||||
|
case RHT2F_UID_ONLY: {
|
||||||
|
ht2_read_uid(NULL, true, true, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ReaderHitag(payload, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content
|
case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content
|
||||||
|
@ -1148,25 +1165,28 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file
|
case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file
|
||||||
Hitag_check_challenges(packet->data.asBytes, packet->oldarg[0], true);
|
Hitag_check_challenges(packet->data.asBytes, packet->length, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HITAGS_READ: { // Reader for only Hitag S tags, args = key or challenge
|
case CMD_LF_HITAGS_READ: { // Reader for only Hitag S tags, args = key or challenge
|
||||||
ReadHitagS((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes, true);
|
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
|
||||||
|
ReadHitagS(payload, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HITAGS_WRITE: { //writer for Hitag tags args=data to write,page and key or challenge
|
case CMD_LF_HITAGS_WRITE: {
|
||||||
if ((hitag_function)packet->oldarg[0] < 10) {
|
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
|
||||||
WritePageHitagS((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes, packet->oldarg[2], true);
|
WritePageHitagS(payload, true);
|
||||||
} else {
|
break;
|
||||||
WriterHitag((hitag_function)packet->oldarg[0], (hitag_data *)packet->data.asBytes, packet->oldarg[2], true);
|
|
||||||
}
|
}
|
||||||
|
case CMD_LF_HITAG2_WRITE: {
|
||||||
|
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
|
||||||
|
WriterHitag(payload, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HITAG_ELOAD: {
|
case CMD_LF_HITAG_ELOAD: {
|
||||||
lf_hitag_t *payload = (lf_hitag_t *) packet->data.asBytes;
|
lf_hitag_t *payload = (lf_hitag_t *) packet->data.asBytes;
|
||||||
uint8_t *mem = BigBuf_get_EM_addr();
|
uint8_t *mem = BigBuf_get_EM_addr();
|
||||||
memcpy((uint8_t *)mem, payload->data, payload->len);
|
memcpy(mem, payload->data, payload->len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
823
armsrc/hitag2.c
823
armsrc/hitag2.c
File diff suppressed because it is too large
Load diff
|
@ -23,8 +23,12 @@
|
||||||
#include "hitag.h"
|
#include "hitag.h"
|
||||||
|
|
||||||
void SniffHitag2(bool ledcontrol);
|
void SniffHitag2(bool ledcontrol);
|
||||||
|
void hitag_sniff(void);
|
||||||
void SimulateHitag2(bool ledcontrol);
|
void SimulateHitag2(bool ledcontrol);
|
||||||
void ReaderHitag(hitag_function htf, const hitag_data *htd, bool ledcontrol);
|
void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol);
|
||||||
void WriterHitag(hitag_function htf, const hitag_data *htd, int page, bool ledcontrol);
|
void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol);
|
||||||
void EloadHitag(const uint8_t *data, uint16_t len);
|
|
||||||
|
bool ht2_packbits(uint8_t *nrz_samples, size_t nrzs, uint8_t *rx, size_t *rxlen);
|
||||||
|
int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_field_up);
|
||||||
|
int ht2_tx_rx(uint8_t *tx, size_t txlen, uint8_t *rx, size_t *rxlen, bool ledcontrol, bool keep_field_up);
|
||||||
#endif
|
#endif
|
||||||
|
|
468
armsrc/hitagS.c
468
armsrc/hitagS.c
|
@ -125,12 +125,13 @@ static void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitco
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hitag_send_bit(int bit, bool ledcontrol) {
|
static void hitag_send_bit(int bit, bool ledcontrol) {
|
||||||
|
|
||||||
if (ledcontrol) LED_A_ON();
|
if (ledcontrol) LED_A_ON();
|
||||||
// Reset clock for the next bit
|
// Reset clock for the next bit
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case AC2K:
|
case AC2K: {
|
||||||
if (bit == 0) {
|
if (bit == 0) {
|
||||||
// AC Coding --__
|
// AC Coding --__
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
|
@ -156,7 +157,8 @@ static void hitag_send_bit(int bit, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
break;
|
break;
|
||||||
case AC4K:
|
}
|
||||||
|
case AC4K: {
|
||||||
if (bit == 0) {
|
if (bit == 0) {
|
||||||
// AC Coding --__
|
// AC Coding --__
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
|
@ -181,7 +183,8 @@ static void hitag_send_bit(int bit, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
break;
|
break;
|
||||||
case MC4K:
|
}
|
||||||
|
case MC4K: {
|
||||||
if (bit == 0) {
|
if (bit == 0) {
|
||||||
// Manchester: Unloaded, then loaded |__--|
|
// Manchester: Unloaded, then loaded |__--|
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
@ -201,7 +204,8 @@ static void hitag_send_bit(int bit, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
break;
|
break;
|
||||||
case MC8K:
|
}
|
||||||
|
case MC8K: {
|
||||||
if (bit == 0) {
|
if (bit == 0) {
|
||||||
// Manchester: Unloaded, then loaded |__--|
|
// Manchester: Unloaded, then loaded |__--|
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
@ -221,27 +225,34 @@ static void hitag_send_bit(int bit, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void hitag_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol) {
|
static void hitag_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol) {
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
|
||||||
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("hitag_send_frame: (%i) %02X %02X %02X %02X", frame_len, frame[0], frame[1], frame[2], frame[3]);
|
Dbprintf("hitag_send_frame: (%i) %02X %02X %02X %02X", frame_len, frame[0], frame[1], frame[2], frame[3]);
|
||||||
|
}
|
||||||
|
|
||||||
// The beginning of the frame is hidden in some high level; pause until our bits will have an effect
|
// The beginning of the frame is hidden in some high level; pause until our bits will have an effect
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case AC4K:
|
case AC4K:
|
||||||
case MC8K:
|
case MC8K: {
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; //FADV
|
while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; //FADV
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case AC2K:
|
case AC2K:
|
||||||
case MC4K:
|
case MC4K: {
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV
|
while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SOF - send start of frame
|
// SOF - send start of frame
|
||||||
for (size_t i = 0; i < sof_bits; i++) {
|
for (size_t i = 0; i < sof_bits; i++) {
|
||||||
|
@ -317,45 +328,103 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hitagS_init_clock(void) {
|
||||||
|
|
||||||
|
// Enable Peripheral Clock for
|
||||||
|
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||||
|
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||||
|
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||||
|
|
||||||
|
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||||
|
|
||||||
|
// Disable timer during configuration
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
|
||||||
|
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||||
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||||
|
|
||||||
|
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||||
|
// external trigger rising edge, load RA on falling edge of TIOA.
|
||||||
|
AT91C_BASE_TC1->TC_CMR =
|
||||||
|
AT91C_TC_CLKS_TIMER_DIV1_CLOCK |
|
||||||
|
AT91C_TC_ETRGEDG_FALLING |
|
||||||
|
AT91C_TC_ABETRG |
|
||||||
|
AT91C_TC_LDRA_FALLING |
|
||||||
|
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
|
||||||
|
AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit)
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero
|
||||||
|
AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle
|
||||||
|
|
||||||
|
// 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
|
||||||
|
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
|
||||||
|
// while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared)
|
||||||
|
|
||||||
|
// return to zero
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
while (AT91C_BASE_TC0->TC_CV > 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hitagS_stop_clock(void) {
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* to check if the right uid was selected
|
* to check if the right uid was selected
|
||||||
*/
|
*/
|
||||||
static int check_select(const uint8_t *rx, uint32_t uid) {
|
static int check_select(const uint8_t *rx, uint32_t uid) {
|
||||||
|
|
||||||
unsigned char resp[48];
|
unsigned char resp[48];
|
||||||
uint32_t ans = 0x0;
|
uint32_t ans = 0x0;
|
||||||
for (int i = 0; i < 48; i++)
|
|
||||||
resp[i] = (rx[i / 8] >> (7 - (i % 8))) & 0x1;
|
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 48; i++) {
|
||||||
|
resp[i] = (rx[i / 8] >> (7 - (i % 8))) & 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
ans += resp[5 + i] << (31 - i);
|
ans += resp[5 + i] << (31 - i);
|
||||||
|
}
|
||||||
|
|
||||||
// global var?
|
// global var?
|
||||||
temp_uid = ans;
|
temp_uid = ans;
|
||||||
|
|
||||||
if (ans == tag.uid)
|
if (ans == tag.uid) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hitagS_set_frame_modulation(void) {
|
static void hitagS_set_frame_modulation(void) {
|
||||||
switch (tag.mode) {
|
switch (tag.mode) {
|
||||||
case HT_STANDARD:
|
case HT_STANDARD: {
|
||||||
sof_bits = 1;
|
sof_bits = 1;
|
||||||
m = MC4K;
|
m = MC4K;
|
||||||
break;
|
break;
|
||||||
case HT_ADVANCED:
|
}
|
||||||
|
case HT_ADVANCED: {
|
||||||
sof_bits = 6;
|
sof_bits = 6;
|
||||||
m = MC4K;
|
m = MC4K;
|
||||||
break;
|
break;
|
||||||
case HT_FAST_ADVANCED:
|
}
|
||||||
|
case HT_FAST_ADVANCED: {
|
||||||
sof_bits = 6;
|
sof_bits = 6;
|
||||||
m = MC8K;
|
m = MC8K;
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handles all commands from a reader
|
* handles all commands from a reader
|
||||||
|
@ -411,16 +480,18 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
tx[i] = (tag.uid >> (24 - (i * 8))) & 0xFF;
|
tx[i] = (tag.uid >> (24 - (i * 8))) & 0xFF;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 45: {
|
case 45: {
|
||||||
//select command from reader received
|
//select command from reader received
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
DbpString("SELECT");
|
DbpString("SELECT");
|
||||||
|
}
|
||||||
|
|
||||||
if (check_select(rx, tag.uid) == 1) {
|
if (check_select(rx, tag.uid) == 1) {
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
DbpString("SELECT match");
|
DbpString("SELECT match");
|
||||||
|
}
|
||||||
|
|
||||||
//if the right tag was selected
|
//if the right tag was selected
|
||||||
*txlen = 32;
|
*txlen = 32;
|
||||||
|
@ -434,8 +505,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
tx[3] = 0xff;
|
tx[3] = 0xff;
|
||||||
|
|
||||||
if (tag.mode != HT_STANDARD) {
|
if (tag.mode != HT_STANDARD) {
|
||||||
|
|
||||||
*txlen = 40;
|
*txlen = 40;
|
||||||
crc = CRC_PRESET;
|
crc = CRC_PRESET;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
calc_crc(&crc, tx[i], 8);
|
calc_crc(&crc, tx[i], 8);
|
||||||
}
|
}
|
||||||
|
@ -443,8 +516,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
tx[4] = crc;
|
tx[4] = crc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 64: {
|
case 64: {
|
||||||
//challenge message received
|
//challenge message received
|
||||||
Dbprintf("Challenge for UID: %X", temp_uid);
|
Dbprintf("Challenge for UID: %X", temp_uid);
|
||||||
|
@ -499,9 +572,9 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
tag.pages[0][3] = 0x88;
|
tag.pages[0][3] = 0x88;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 40:
|
}
|
||||||
|
case 40: {
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED)
|
||||||
Dbprintf("WRITE");
|
Dbprintf("WRITE");
|
||||||
//data received to be written
|
//data received to be written
|
||||||
|
@ -535,6 +608,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
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) == 0xc0) { //read page
|
||||||
|
@ -567,9 +641,12 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
sof_bits = 0;
|
sof_bits = 0;
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((rx[0] & 0xf0) == 0xd0) { //read block
|
} else if ((rx[0] & 0xf0) == 0xd0) { //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;
|
||||||
|
|
||||||
//send page,...,page+3 data
|
//send page,...,page+3 data
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
tx[0 + i * 4] = tag.pages[page + 0 + i * 4][0];
|
tx[0 + i * 4] = tag.pages[page + 0 + i * 4][0];
|
||||||
|
@ -594,8 +671,11 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
sof_bits = 0;
|
sof_bits = 0;
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((rx[0] & 0xf0) == 0x80) { //write page
|
} else if ((rx[0] & 0xf0) == 0x80) { //write page
|
||||||
|
|
||||||
uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
|
uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
|
||||||
|
|
||||||
if ((tag.LCON && page == 1)
|
if ((tag.LCON && page == 1)
|
||||||
|| (tag.LKP && (page == 2 || page == 3))) {
|
|| (tag.LKP && (page == 2 || page == 3))) {
|
||||||
//deny
|
//deny
|
||||||
|
@ -609,8 +689,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((rx[0] & 0xf0) == 0x90) { //write block
|
} else if ((rx[0] & 0xf0) == 0x90) { //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();
|
||||||
|
|
||||||
if (page % 4 != 0 || page == 0) {
|
if (page % 4 != 0 || page == 0) {
|
||||||
//deny
|
//deny
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
@ -623,12 +705,14 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
|
||||||
tag.tstate = HT_WRITING_BLOCK_DATA;
|
tag.tstate = HT_WRITING_BLOCK_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
|
Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X ...", rxlen, rx[0], rx[1], rx[2], rx[3]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
|
||||||
Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X ...", rxlen, rx[0], rx[1], rx[2], rx[3]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +723,6 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr
|
||||||
|
|
||||||
StopTicks();
|
StopTicks();
|
||||||
|
|
||||||
// int frame_count = 0;
|
|
||||||
int response = 0, overflow = 0;
|
int response = 0, overflow = 0;
|
||||||
uint8_t rx[HITAG_FRAME_LEN];
|
uint8_t rx[HITAG_FRAME_LEN];
|
||||||
size_t rxlen = 0;
|
size_t rxlen = 0;
|
||||||
|
@ -666,6 +749,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr
|
||||||
|
|
||||||
// read tag data into memory
|
// read tag data into memory
|
||||||
if (tag_mem_supplied) {
|
if (tag_mem_supplied) {
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
tag.pages[i][j] = 0x0;
|
tag.pages[i][j] = 0x0;
|
||||||
|
@ -700,7 +784,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr
|
||||||
tag.max_page = 0;
|
tag.max_page = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
|
|
||||||
for (int i = 0; i < tag.max_page; i++) {
|
for (int i = 0; i < tag.max_page; i++) {
|
||||||
Dbprintf("Page[%2d]: %02X %02X %02X %02X", i,
|
Dbprintf("Page[%2d]: %02X %02X %02X %02X", i,
|
||||||
(tag.pages[i][3]) & 0xFF,
|
(tag.pages[i][3]) & 0xFF,
|
||||||
|
@ -709,6 +794,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr
|
||||||
tag.pages[i][0] & 0xFF
|
tag.pages[i][0] & 0xFF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//con1
|
//con1
|
||||||
tag.auth = 0;
|
tag.auth = 0;
|
||||||
if ((tag.pages[1][1] & 0x80) == 0x80) {
|
if ((tag.pages[1][1] & 0x80) == 0x80) {
|
||||||
|
@ -814,8 +901,10 @@ void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontr
|
||||||
|
|
||||||
// Receive frame, watch for at most T0*EOF periods
|
// Receive frame, watch for at most T0*EOF periods
|
||||||
while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) {
|
while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) {
|
||||||
|
|
||||||
// Check if rising edge in modulation is detected
|
// Check if rising edge in modulation is detected
|
||||||
if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
||||||
|
|
||||||
// Retrieve the new timing values
|
// Retrieve the new timing values
|
||||||
int ra = (AT91C_BASE_TC1->TC_RA / T0) + overflow;
|
int ra = (AT91C_BASE_TC1->TC_RA / T0) + overflow;
|
||||||
overflow = 0;
|
overflow = 0;
|
||||||
|
@ -901,6 +990,7 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
// Reset values for receiving frames
|
// Reset values for receiving frames
|
||||||
memset(rx, 0x00, sizeofrx);
|
memset(rx, 0x00, sizeofrx);
|
||||||
*rxlen = 0;
|
*rxlen = 0;
|
||||||
|
|
||||||
int lastbit = 1;
|
int lastbit = 1;
|
||||||
bool bSkip = true;
|
bool bSkip = true;
|
||||||
*resptime = 0;
|
*resptime = 0;
|
||||||
|
@ -914,8 +1004,8 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
|
|
||||||
// Receive frame, watch for at most T0*EOF periods
|
// Receive frame, watch for at most T0*EOF periods
|
||||||
while (AT91C_BASE_TC0->TC_CV + (overcount << 16) < (T0 * HITAG_T_PROG_MAX)) {
|
while (AT91C_BASE_TC0->TC_CV + (overcount << 16) < (T0 * HITAG_T_PROG_MAX)) {
|
||||||
// detect and track counter overflows
|
|
||||||
|
|
||||||
|
// detect and track counter overflows
|
||||||
uint32_t tmpcv = AT91C_BASE_TC0->TC_CV;
|
uint32_t tmpcv = AT91C_BASE_TC0->TC_CV;
|
||||||
if (tmpcv < prevcv) {
|
if (tmpcv < prevcv) {
|
||||||
overcount++;
|
overcount++;
|
||||||
|
@ -924,10 +1014,13 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
|
|
||||||
// Check if falling edge in tag modulation is detected
|
// Check if falling edge in tag modulation is detected
|
||||||
if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
||||||
|
|
||||||
// Retrieve the new timing values
|
// Retrieve the new timing values
|
||||||
uint32_t ra = (AT91C_BASE_TC1->TC_RA + (overcount << 16)) / T0;
|
uint32_t ra = (AT91C_BASE_TC1->TC_RA + (overcount << 16)) / T0;
|
||||||
|
|
||||||
// Reset timer every frame, we have to capture the last edge for timing
|
// Reset timer every frame, we have to capture the last edge for timing
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
|
||||||
prevcv = 0;
|
prevcv = 0;
|
||||||
overcount = 0;
|
overcount = 0;
|
||||||
|
|
||||||
|
@ -935,7 +1028,8 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
|
|
||||||
// Capture tag frame (manchester decoding using only falling edges)
|
// Capture tag frame (manchester decoding using only falling edges)
|
||||||
|
|
||||||
if (!bStarted) {
|
if (bStarted == false) {
|
||||||
|
|
||||||
if (ra >= HITAG_T_EOF) {
|
if (ra >= HITAG_T_EOF) {
|
||||||
bStarted = true;
|
bStarted = true;
|
||||||
// Capture the T0 periods that have passed since last communication or field drop (reset)
|
// Capture the T0 periods that have passed since last communication or field drop (reset)
|
||||||
|
@ -944,28 +1038,37 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
} else {
|
} else {
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) {
|
} else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) {
|
||||||
|
|
||||||
// Manchester coding example |-_|_-|-_| (101)
|
// Manchester coding example |-_|_-|-_| (101)
|
||||||
rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8));
|
rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8));
|
||||||
(*rxlen)++;
|
(*rxlen)++;
|
||||||
|
|
||||||
rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8));
|
rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8));
|
||||||
(*rxlen)++;
|
(*rxlen)++;
|
||||||
|
|
||||||
} else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) {
|
} else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) {
|
||||||
|
|
||||||
// Manchester coding example |_-|...|_-|-_| (0...01)
|
// Manchester coding example |_-|...|_-|-_| (0...01)
|
||||||
rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8));
|
rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8));
|
||||||
(*rxlen)++;
|
(*rxlen)++;
|
||||||
|
|
||||||
// We have to skip this half period at start and add the 'one' the second time
|
// We have to skip this half period at start and add the 'one' the second time
|
||||||
if (!bSkip) {
|
if (bSkip == false) {
|
||||||
rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8));
|
rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8));
|
||||||
(*rxlen)++;
|
(*rxlen)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastbit = !lastbit;
|
lastbit = !lastbit;
|
||||||
bSkip = !bSkip;
|
bSkip = !bSkip;
|
||||||
|
|
||||||
} else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) {
|
} else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) {
|
||||||
// Manchester coding example |_-|_-| (00) or |-_|-_| (11)
|
// Manchester coding example |_-|_-| (00) or |-_|-_| (11)
|
||||||
// bit is same as last bit
|
// bit is same as last bit
|
||||||
rx[(*rxlen) / 8] |= lastbit << (7 - ((*rxlen) % 8));
|
rx[(*rxlen) / 8] |= lastbit << (7 - ((*rxlen) % 8));
|
||||||
(*rxlen)++;
|
(*rxlen)++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Ignore weird value, is to small to mean anything
|
// Ignore weird value, is to small to mean anything
|
||||||
errorCount++;
|
errorCount++;
|
||||||
|
@ -973,11 +1076,13 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we saw over 100 weird values break it probably isn't hitag...
|
// if we saw over 100 weird values break it probably isn't hitag...
|
||||||
if (errorCount > 100) break;
|
if (errorCount > 100) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// We can break this loop if we received the last bit from a frame
|
// We can break this loop if we received the last bit from a frame
|
||||||
if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) {
|
if (AT91C_BASE_TC1->TC_CV > (T0 * HITAG_T_EOF)) {
|
||||||
if ((*rxlen) > 0) {
|
if ((*rxlen)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -998,7 +1103,6 @@ static void sendReceiveHitagS(uint8_t *tx, size_t txlen, uint8_t *rx, size_t siz
|
||||||
// falling edge occurred halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
|
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) {};
|
while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) {};
|
||||||
|
|
||||||
// Transmit the reader frame
|
// Transmit the reader frame
|
||||||
|
@ -1011,48 +1115,82 @@ static void sendReceiveHitagS(uint8_t *tx, size_t txlen, uint8_t *rx, size_t siz
|
||||||
size_t rxlen = 0;
|
size_t rxlen = 0;
|
||||||
hitagS_receive_frame(rx, sizeofrx, &rxlen, &resptime, ledcontrol);
|
hitagS_receive_frame(rx, sizeofrx, &rxlen, &resptime, ledcontrol);
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
// Check if frame was captured and store it
|
// Check if frame was captured and store it
|
||||||
if (rxlen > 0) {
|
if (rxlen > 0) {
|
||||||
|
|
||||||
uint8_t response_bit[sizeofrx * 8];
|
uint8_t response_bit[sizeofrx * 8];
|
||||||
for (int i = 0; i < rxlen; i++) {
|
|
||||||
|
for (size_t i = 0; i < rxlen; i++) {
|
||||||
response_bit[i] = (rx[i / 8] >> (7 - (i % 8))) & 1;
|
response_bit[i] = (rx[i / 8] >> (7 - (i % 8))) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dbprintf("htS: rxlen...... %zu", rxlen);
|
||||||
|
Dbprintf("htS: sizeofrx... %zu", sizeofrx);
|
||||||
|
|
||||||
memset(rx, 0x00, sizeofrx);
|
memset(rx, 0x00, sizeofrx);
|
||||||
|
|
||||||
if (ac_seq) {
|
if (ac_seq) {
|
||||||
|
|
||||||
|
DbpString("htS: AntiCollision Sequence ( ac seq )");
|
||||||
|
Dbhexdump(rxlen, response_bit, false);
|
||||||
|
|
||||||
// Tag Response is AC encoded
|
// Tag Response is AC encoded
|
||||||
|
// We used UID Request Advanced, meaning AC SEQ header is 111.
|
||||||
for (int i = 6; i < rxlen; i += 2) {
|
for (int i = 6; i < rxlen; i += 2) {
|
||||||
|
|
||||||
rx[k / 8] |= response_bit[i] << (7 - (k % 8));
|
rx[k / 8] |= response_bit[i] << (7 - (k % 8));
|
||||||
|
|
||||||
k++;
|
k++;
|
||||||
if (k >= 8 * sizeofrx)
|
|
||||||
|
if (k > 8 * sizeofrx) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DbpString("htS: ac sequence compress");
|
||||||
|
Dbhexdump(k / 8, rx, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = 5; i < rxlen; i++) { // ignore first 5 bits: SOF (actually 1 or 6 depending on response protocol)
|
|
||||||
|
DbpString("htS: skipping 5 bit header");
|
||||||
|
|
||||||
|
// ignore first 5 bits: SOF (actually 1 or 6 depending on response protocol)
|
||||||
|
// or rather a header.
|
||||||
|
for (size_t i = 5; i < rxlen; i++) {
|
||||||
|
|
||||||
rx[k / 8] |= response_bit[i] << (7 - (k % 8));
|
rx[k / 8] |= response_bit[i] << (7 - (k % 8));
|
||||||
k++;
|
k++;
|
||||||
if (k >= 8 * sizeofrx)
|
|
||||||
|
if (k > 8 * sizeofrx) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
LogTraceBits(rx, k, resptime, resptime, false);
|
LogTraceBits(rx, k, resptime, resptime, false);
|
||||||
}
|
}
|
||||||
*prxbits = k;
|
*prxbits = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t concatbits(uint8_t *dstbuf, size_t dstbufskip, const uint8_t *srcbuf, size_t srcbufstart, size_t srcbuflen) {
|
static size_t concatbits(uint8_t *dst, size_t dstskip, const uint8_t *src, size_t srcstart, size_t srclen) {
|
||||||
// erase dstbuf bits that will be overriden
|
// erase dstbuf bits that will be overriden
|
||||||
dstbuf[dstbufskip / 8] &= 0xFF - ((1 << (7 - (dstbufskip % 8) + 1)) - 1);
|
dst[dstskip / 8] &= 0xFF - ((1 << (7 - (dstskip % 8) + 1)) - 1);
|
||||||
for (size_t i = (dstbufskip / 8) + 1; i <= (dstbufskip + srcbuflen) / 8; i++) {
|
for (size_t i = (dstskip / 8) + 1; i <= (dstskip + srclen) / 8; i++) {
|
||||||
dstbuf[i] = 0;
|
dst[i] = 0;
|
||||||
}
|
|
||||||
for (size_t i = 0; i < srcbuflen; i++) {
|
|
||||||
// equiv of dstbufbits[dstbufskip + i] = srcbufbits[srcbufstart + i]
|
|
||||||
dstbuf[(dstbufskip + i) / 8] |= ((srcbuf[(srcbufstart + i) / 8] >> (7 - ((srcbufstart + i) % 8))) & 1) << (7 - ((dstbufskip + i) % 8));
|
|
||||||
}
|
|
||||||
return dstbufskip + srcbuflen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx, size_t sizeoftx, uint8_t *rx, size_t sizeofrx, int t_wait, bool ledcontrol) {
|
for (size_t i = 0; i < srclen; i++) {
|
||||||
|
// equiv of dstbufbits[dstbufskip + i] = srcbufbits[srcbufstart + i]
|
||||||
|
dst[(dstskip + i) / 8] |= ((src[(srcstart + i) / 8] >> (7 - ((srcstart + i) % 8))) & 1) << (7 - ((dstskip + i) % 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dstskip + srclen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeoftx, uint8_t *rx, size_t sizeofrx, int t_wait, bool ledcontrol) {
|
||||||
|
|
||||||
StopTicks();
|
StopTicks();
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
@ -1075,50 +1213,28 @@ static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx,
|
||||||
// Disable modulation at default, which means enable the field
|
// Disable modulation at default, which means enable the field
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
|
||||||
// Enable Peripheral Clock for
|
hitagS_init_clock();
|
||||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
|
||||||
// TIMER_CLOCK1, used to capture edges of the tag frames
|
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
// UID request standard 00110
|
||||||
|
// UID request Advanced 1100x
|
||||||
// Disable timer during configuration
|
// UID request FAdvanced 11010
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
|
||||||
|
|
||||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
|
||||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
|
||||||
|
|
||||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
|
||||||
// external trigger rising edge, load RA on falling edge of TIOA.
|
|
||||||
AT91C_BASE_TC1->TC_CMR =
|
|
||||||
AT91C_TC_CLKS_TIMER_DIV1_CLOCK |
|
|
||||||
AT91C_TC_ETRGEDG_FALLING |
|
|
||||||
AT91C_TC_ABETRG |
|
|
||||||
AT91C_TC_LDRA_FALLING;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
|
|
||||||
|
|
||||||
//start authentication
|
|
||||||
size_t txlen = 0;
|
size_t txlen = 0;
|
||||||
size_t rxlen = 0;
|
size_t rxlen = 0;
|
||||||
uint8_t cmd = 0x18;
|
uint8_t cmd = 0x18; // 11000 UID Request Advanced
|
||||||
txlen = concatbits(tx, txlen, &cmd, 8 - 5, 5);
|
txlen = concatbits(tx, txlen, &cmd, 8 - 5, 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) {
|
||||||
Dbprintf("UID Request failed!");
|
DbpString("UID Request failed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.uid = (rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]);
|
tag.uid = (rx[3] << 24 | rx[2] << 16 | rx[1] << 8 | rx[0]);
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
|
||||||
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("UID: %02X %02X %02X %02X", rx[0], rx[1], rx[2], rx[3]);
|
Dbprintf("UID: %02X %02X %02X %02X", rx[0], rx[1], rx[2], rx[3]);
|
||||||
|
}
|
||||||
|
|
||||||
//select uid
|
//select uid
|
||||||
txlen = 0;
|
txlen = 0;
|
||||||
cmd = 0x00;
|
cmd = 0x00;
|
||||||
|
@ -1165,25 +1281,29 @@ static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx,
|
||||||
tag.LCK1 = (conf_pages[2] >> 1) & 0x1;
|
tag.LCK1 = (conf_pages[2] >> 1) & 0x1;
|
||||||
tag.LCK0 = (conf_pages[2] >> 0) & 0x1;
|
tag.LCK0 = (conf_pages[2] >> 0) & 0x1;
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("conf 0: %02X conf 1: %02X conf 2: %02X", conf_pages[0], conf_pages[1], conf_pages[2]);
|
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.auth == 1) {
|
||||||
uint64_t key = 0;
|
uint64_t key = 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
|
||||||
if (htf == RHTSF_KEY || htf == WHTSF_KEY) {
|
if (packet->cmd == RHTSF_KEY || packet->cmd == WHTSF_KEY) {
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
DbpString("Authenticating using key:");
|
DbpString("Authenticating using key:");
|
||||||
Dbhexdump(6, htd->crypto.key, false);
|
Dbhexdump(6, packet->key, false);
|
||||||
}
|
}
|
||||||
key = ((uint64_t)htd->crypto.key[0]) << 0 |
|
key = ((uint64_t)packet->key[0]) << 0 |
|
||||||
((uint64_t)htd->crypto.key[1]) << 8 |
|
((uint64_t)packet->key[1]) << 8 |
|
||||||
((uint64_t)htd->crypto.key[2]) << 16 |
|
((uint64_t)packet->key[2]) << 16 |
|
||||||
((uint64_t)htd->crypto.key[3]) << 24 |
|
((uint64_t)packet->key[3]) << 24 |
|
||||||
((uint64_t)htd->crypto.key[4]) << 32 |
|
((uint64_t)packet->key[4]) << 32 |
|
||||||
((uint64_t)htd->crypto.key[5]) << 40
|
((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), REV32(tag.uid), REV32(rnd));
|
||||||
|
|
||||||
uint8_t auth_ks[4];
|
uint8_t auth_ks[4];
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
auth_ks[i] = ht2_hitag2_byte(&state) ^ 0xff;
|
auth_ks[i] = ht2_hitag2_byte(&state) ^ 0xff;
|
||||||
|
@ -1194,37 +1314,44 @@ static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx,
|
||||||
txlen = concatbits(tx, txlen, revrnd, 0, 32);
|
txlen = concatbits(tx, txlen, revrnd, 0, 32);
|
||||||
txlen = concatbits(tx, txlen, auth_ks, 0, 32);
|
txlen = concatbits(tx, txlen, auth_ks, 0, 32);
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx[0],
|
Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X"
|
||||||
tx[1], tx[2], tx[3], tx[4], tx[5], tx[6], tx[7]);
|
, tx[0], tx[1], tx[2], tx[3]
|
||||||
|
, tx[4], tx[5], tx[6], tx[7]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (packet->cmd == RHTSF_CHALLENGE || packet->cmd == WHTSF_CHALLENGE) {
|
||||||
|
|
||||||
} else if (htf == RHTSF_CHALLENGE || htf == WHTSF_CHALLENGE) {
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
DbpString("Authenticating using nr,ar pair:");
|
DbpString("Authenticating using nr,ar pair:");
|
||||||
Dbhexdump(8, htd->auth.NrAr, false);
|
Dbhexdump(8, packet->NrAr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t NrAr = 0;
|
uint64_t NrAr = 0;
|
||||||
NrAr = ((uint64_t)htd->auth.NrAr[7]) << 0 |
|
NrAr = ((uint64_t)packet->NrAr[7]) << 0 |
|
||||||
((uint64_t)htd->auth.NrAr[6]) << 8 |
|
((uint64_t)packet->NrAr[6]) << 8 |
|
||||||
((uint64_t)htd->auth.NrAr[5]) << 16 |
|
((uint64_t)packet->NrAr[5]) << 16 |
|
||||||
((uint64_t)htd->auth.NrAr[4]) << 24 |
|
((uint64_t)packet->NrAr[4]) << 24 |
|
||||||
((uint64_t)htd->auth.NrAr[3]) << 32 |
|
((uint64_t)packet->NrAr[3]) << 32 |
|
||||||
((uint64_t)htd->auth.NrAr[2]) << 40 |
|
((uint64_t)packet->NrAr[2]) << 40 |
|
||||||
((uint64_t)htd->auth.NrAr[1]) << 48 |
|
((uint64_t)packet->NrAr[1]) << 48 |
|
||||||
((uint64_t)htd->auth.NrAr[0]) << 56;
|
((uint64_t)packet->NrAr[0]) << 56;
|
||||||
|
|
||||||
txlen = 64;
|
txlen = 64;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF);
|
tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Error , unknown function: %d", htf);
|
Dbprintf("Error , unknown function: " _RED_("%d"), packet->cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, false);
|
sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, false);
|
||||||
|
|
||||||
if (rxlen != 40) {
|
if (rxlen != 40) {
|
||||||
Dbprintf("Authenticate failed! %i", rxlen);
|
Dbprintf("Authenticate failed! " _RED_("%i"), rxlen);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,19 +1365,21 @@ static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx,
|
||||||
pwdh0 = 0;
|
pwdh0 = 0;
|
||||||
pwdl0 = 0;
|
pwdl0 = 0;
|
||||||
pwdl1 = 0;
|
pwdl1 = 0;
|
||||||
if (htf == RHTSF_KEY || htf == WHTSF_KEY) {
|
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), REV32(tag.uid), REV32(rnd));
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ht2_hitag2_byte(&state);
|
ht2_hitag2_byte(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t con2 = rx[0] ^ ht2_hitag2_byte(&state);
|
uint8_t con2 = rx[0] ^ ht2_hitag2_byte(&state);
|
||||||
pwdh0 = rx[1] ^ ht2_hitag2_byte(&state);
|
pwdh0 = rx[1] ^ ht2_hitag2_byte(&state);
|
||||||
pwdl0 = rx[2] ^ ht2_hitag2_byte(&state);
|
pwdl0 = rx[2] ^ ht2_hitag2_byte(&state);
|
||||||
pwdl1 = rx[3] ^ ht2_hitag2_byte(&state);
|
pwdl1 = rx[3] ^ ht2_hitag2_byte(&state);
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED)
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("con2 %02X pwdh0 %02X pwdl0 %02X pwdl1 %02X", con2, pwdh0, pwdl0, pwdl1);
|
Dbprintf("con2 %02X pwdh0 %02X pwdl0 %02X pwdl1 %02X", con2, pwdh0, pwdl0, pwdl1);
|
||||||
|
}
|
||||||
//Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16));
|
//Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16));
|
||||||
//rnd += 1;
|
//rnd += 1;
|
||||||
}
|
}
|
||||||
|
@ -1263,21 +1392,26 @@ static int selectHitagS(hitag_function htf, const hitag_data *htd, uint8_t *tx,
|
||||||
* If the key was given the password will be decrypted.
|
* If the key was given the password will be decrypted.
|
||||||
* Reads every page of a hitag S transpoder.
|
* Reads every page of a hitag S transpoder.
|
||||||
*/
|
*/
|
||||||
void ReadHitagS(hitag_function htf, const hitag_data *htd, bool ledcontrol) {
|
void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
|
||||||
|
|
||||||
uint8_t rx[HITAG_FRAME_LEN];
|
uint8_t rx[HITAG_FRAME_LEN];
|
||||||
size_t rxlen = 0;
|
size_t rxlen = 0;
|
||||||
|
|
||||||
uint8_t tx[HITAG_FRAME_LEN];
|
uint8_t tx[HITAG_FRAME_LEN];
|
||||||
|
|
||||||
int t_wait = HITAG_T_WAIT_MAX;
|
int t_wait = HITAG_T_WAIT_MAX;
|
||||||
|
|
||||||
|
if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol) == -1) {
|
||||||
|
|
||||||
if (selectHitagS(htf, htd, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol) == -1) {
|
hitagS_stop_clock();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
lf_finalize(ledcontrol);
|
lf_finalize(ledcontrol);
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
reply_ng(CMD_LF_HITAGS_READ, PM3_ERFTRANS, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pageNum = 0;
|
int pageNum = 0;
|
||||||
|
|
||||||
while ((BUTTON_PRESS() == false) && (data_available() == false)) {
|
while ((BUTTON_PRESS() == false) && (data_available() == false)) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1319,18 +1453,18 @@ void ReadHitagS(hitag_function htf, const hitag_data *htd, bool ledcontrol) {
|
||||||
pageNum++;
|
pageNum++;
|
||||||
//display key and password if possible
|
//display key and password if possible
|
||||||
if (pageNum == 2 && tag.auth == 1 && tag.LKP) {
|
if (pageNum == 2 && tag.auth == 1 && tag.LKP) {
|
||||||
if (htf == RHTSF_KEY) {
|
if (payload->cmd == RHTSF_KEY) {
|
||||||
Dbprintf("Page[ 2]: %02X %02X %02X %02X",
|
Dbprintf("Page[ 2]: %02X %02X %02X %02X",
|
||||||
htd->crypto.key[1],
|
payload->key[1],
|
||||||
htd->crypto.key[0],
|
payload->key[0],
|
||||||
pwdl1,
|
pwdl1,
|
||||||
pwdl0
|
pwdl0
|
||||||
);
|
);
|
||||||
Dbprintf("Page[ 3]: %02X %02X %02X %02X",
|
Dbprintf("Page[ 3]: %02X %02X %02X %02X",
|
||||||
htd->crypto.key[5],
|
payload->key[5],
|
||||||
htd->crypto.key[4],
|
payload->key[4],
|
||||||
htd->crypto.key[3],
|
payload->key[3],
|
||||||
htd->crypto.key[2]
|
payload->key[2]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
//if the authentication is done with a challenge the key and password are unknown
|
//if the authentication is done with a challenge the key and password are unknown
|
||||||
|
@ -1344,78 +1478,89 @@ void ReadHitagS(hitag_function htf, const hitag_data *htd, bool ledcontrol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hitagS_stop_clock();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
lf_finalize(ledcontrol);
|
lf_finalize(ledcontrol);
|
||||||
|
reply_ng(CMD_LF_HITAGS_READ, PM3_SUCCESS, (uint8_t *)tag.pages, sizeof(tag.pages));
|
||||||
// TODO reply_mix(CMD_ACK, 1, 0, 0, 0, 0); and send dump as well, to be decoded in the client
|
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authenticates to the Tag with the given Key or Challenge.
|
* Authenticates to the Tag with the given Key or Challenge.
|
||||||
* Writes the given 32Bit data into page_
|
* Writes the given 32Bit data into page_
|
||||||
*/
|
*/
|
||||||
void WritePageHitagS(hitag_function htf, const hitag_data *htd, int page, bool ledcontrol) {
|
void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
|
||||||
|
|
||||||
bool bSuccessful = false;
|
|
||||||
//check for valid input
|
//check for valid input
|
||||||
if (page == 0) {
|
if (payload->page == 0) {
|
||||||
Dbprintf("Error, invalid page");
|
Dbprintf("Error, invalid page");
|
||||||
reply_mix(CMD_ACK, bSuccessful, 0, 0, 0, 0);
|
reply_ng(CMD_LF_HITAGS_WRITE, PM3_EINVARG, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rx[HITAG_FRAME_LEN];
|
uint8_t rx[HITAG_FRAME_LEN];
|
||||||
size_t rxlen = 0;
|
size_t rxlen = 0;
|
||||||
|
|
||||||
uint8_t tx[HITAG_FRAME_LEN];
|
uint8_t tx[HITAG_FRAME_LEN];
|
||||||
size_t txlen = 0;
|
size_t txlen = 0;
|
||||||
|
|
||||||
int t_wait = HITAG_T_WAIT_MAX;
|
int t_wait = HITAG_T_WAIT_MAX;
|
||||||
|
|
||||||
if (selectHitagS(htf, htd, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol) == -1) {
|
int res = PM3_ESOFT;
|
||||||
|
|
||||||
|
if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol) == -1) {
|
||||||
|
res = PM3_ERFTRANS;
|
||||||
goto write_end;
|
goto write_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the given page exists
|
//check if the given page exists
|
||||||
if (page > tag.max_page) {
|
if (payload->page > tag.max_page) {
|
||||||
Dbprintf("page number too big for this tag");
|
Dbprintf("Error, page number too large");
|
||||||
|
res = PM3_EINVARG;
|
||||||
goto write_end;
|
goto write_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
//send write page request
|
//send write page request
|
||||||
txlen = 0;
|
txlen = 0;
|
||||||
|
|
||||||
uint8_t cmd = 0x08;
|
uint8_t cmd = 0x08;
|
||||||
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4);
|
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4);
|
||||||
uint8_t addr = page;
|
|
||||||
|
uint8_t addr = payload->page;
|
||||||
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);
|
||||||
txlen = concatbits(tx, txlen, &crc, 0, 8);
|
txlen = concatbits(tx, txlen, &crc, 0, 8);
|
||||||
|
|
||||||
sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, t_wait, ledcontrol, false);
|
sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, t_wait, ledcontrol, false);
|
||||||
|
|
||||||
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x1)) {
|
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x1)) {
|
||||||
Dbprintf("no write access on page %d", page);
|
Dbprintf("no write access on page " _YELLOW_("%d"), payload->page);
|
||||||
|
res = PM3_ESOFT;
|
||||||
goto write_end;
|
goto write_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ACK received to write the page. send data
|
//ACK received to write the page. send data
|
||||||
uint8_t data[4] = {0, 0, 0, 0};
|
uint8_t data[4] = {0, 0, 0, 0};
|
||||||
switch (htf) {
|
switch (payload->cmd) {
|
||||||
case WHTSF_CHALLENGE:
|
case WHTSF_CHALLENGE:
|
||||||
data[0] = htd->auth.data[3];
|
data[0] = payload->data[3];
|
||||||
data[1] = htd->auth.data[2];
|
data[1] = payload->data[2];
|
||||||
data[2] = htd->auth.data[1];
|
data[2] = payload->data[1];
|
||||||
data[3] = htd->auth.data[0];
|
data[3] = payload->data[0];
|
||||||
break;
|
break;
|
||||||
case WHTSF_KEY:
|
case WHTSF_KEY:
|
||||||
data[0] = htd->crypto.data[3];
|
data[0] = payload->data[3];
|
||||||
data[1] = htd->crypto.data[2];
|
data[1] = payload->data[2];
|
||||||
data[2] = htd->crypto.data[1];
|
data[2] = payload->data[1];
|
||||||
data[3] = htd->crypto.data[0];
|
data[3] = payload->data[0];
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
res = PM3_EINVARG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
txlen = 0;
|
txlen = 0;
|
||||||
txlen = concatbits(tx, txlen, data, 0, 32);
|
txlen = concatbits(tx, txlen, data, 0, 32);
|
||||||
crc = CRC8Hitag1Bits(tx, txlen);
|
crc = CRC8Hitag1Bits(tx, txlen);
|
||||||
|
@ -1424,16 +1569,16 @@ void WritePageHitagS(hitag_function htf, const hitag_data *htd, int page, bool l
|
||||||
sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, t_wait, ledcontrol, false);
|
sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, t_wait, ledcontrol, false);
|
||||||
|
|
||||||
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x1)) {
|
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x1)) {
|
||||||
Dbprintf("write on page %d failed", page);
|
res = PM3_ESOFT; // write failed
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("write on page %d successful", page);
|
res = PM3_SUCCESS;
|
||||||
bSuccessful = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_end:
|
write_end:
|
||||||
|
hitagS_stop_clock();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
lf_finalize(ledcontrol);
|
lf_finalize(ledcontrol);
|
||||||
reply_mix(CMD_ACK, bSuccessful, 0, 0, 0, 0);
|
reply_ng(CMD_LF_HITAGS_WRITE, res, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1444,10 +1589,11 @@ write_end:
|
||||||
* detects these challenges.
|
* detects these challenges.
|
||||||
*/
|
*/
|
||||||
void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol) {
|
void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol) {
|
||||||
|
|
||||||
//check for valid input
|
//check for valid input
|
||||||
if (datalen < 8) {
|
if (datalen < 8) {
|
||||||
Dbprintf("Error, need chals");
|
Dbprintf("Error, missing challenges");
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
reply_ng(CMD_LF_HITAGS_TEST_TRACES, PM3_EINVARG, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t dataoffset = 0;
|
uint32_t dataoffset = 0;
|
||||||
|
@ -1460,38 +1606,42 @@ void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontr
|
||||||
// Watchdog hit
|
// Watchdog hit
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
hitag_data htd;
|
lf_hitag_data_t payload;
|
||||||
memset(&htd, 0, sizeof(htd));
|
memset(&payload, 0, sizeof(payload));
|
||||||
|
payload.cmd = RHTSF_CHALLENGE;
|
||||||
|
|
||||||
memcpy(htd.auth.NrAr, data + dataoffset, 8);
|
memcpy(payload.NrAr, data + dataoffset, 8);
|
||||||
|
|
||||||
int res = selectHitagS(RHTSF_CHALLENGE, &htd, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol);
|
int res = selectHitagS(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol);
|
||||||
Dbprintf("Challenge %s: %02X %02X %02X %02X %02X %02X %02X %02X",
|
Dbprintf("Challenge %s: %02X %02X %02X %02X %02X %02X %02X %02X",
|
||||||
res == -1 ? "failed " : "success",
|
res == -1 ? "failed " : "success",
|
||||||
htd.auth.NrAr[0], htd.auth.NrAr[1],
|
payload.NrAr[0], payload.NrAr[1],
|
||||||
htd.auth.NrAr[2], htd.auth.NrAr[3],
|
payload.NrAr[2], payload.NrAr[3],
|
||||||
htd.auth.NrAr[4], htd.auth.NrAr[5],
|
payload.NrAr[4], payload.NrAr[5],
|
||||||
htd.auth.NrAr[6], htd.auth.NrAr[7]
|
payload.NrAr[6], payload.NrAr[7]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
// Need to do a dummy UID select that will fail
|
// Need to do a dummy UID select that will fail
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(2);
|
SpinDelay(2);
|
||||||
selectHitagS(RHTSF_CHALLENGE, &htd, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol);
|
selectHitagS(&payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), t_wait, ledcontrol);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataoffset += 8;
|
dataoffset += 8;
|
||||||
if (dataoffset >= datalen - 8)
|
if (dataoffset >= datalen - 8) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// reset field
|
// reset field
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
// min t_reset = 2ms
|
// min t_reset = 2ms
|
||||||
SpinDelay(2);
|
SpinDelay(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hitagS_stop_clock();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
lf_finalize(ledcontrol);
|
lf_finalize(ledcontrol);
|
||||||
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
|
reply_ng(CMD_ACK, PM3_SUCCESS, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,10 @@
|
||||||
#define _HITAGS_H_
|
#define _HITAGS_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "hitag.h"
|
#include "hitag.h"
|
||||||
|
|
||||||
void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol);
|
void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol);
|
||||||
void ReadHitagS(hitag_function htf, const hitag_data *htd, bool ledcontrol);
|
void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol);
|
||||||
void WritePageHitagS(hitag_function htf, const hitag_data *htd, int page, bool ledcontrol);
|
void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol);
|
||||||
void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol);
|
void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2941,14 +2941,11 @@ void SetTag15693Uid_v2(const uint8_t *uid) {
|
||||||
{ ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x47, 0x3f, 0x03, 0x8b, 0x00, 0x00, 0x00 },
|
{ ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x47, 0x3f, 0x03, 0x8b, 0x00, 0x00, 0x00 },
|
||||||
{ ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
{ ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
// hf 15 raw -wac -d 02 e0 09 41 + uid first four bytes
|
// hf 15 raw -wac -d 02 e0 09 41 + uid first four bytes
|
||||||
{ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x41, uid[7], uid[6], uid[5], uid[4], 0x00, 0x00},
|
{ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x40, uid[7], uid[6], uid[5], uid[4], 0x00, 0x00},
|
||||||
// hf 15 raw -wac -d 02 e0 09 40 + uid last four bytes
|
// hf 15 raw -wac -d 02 e0 09 40 + uid last four bytes
|
||||||
{ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x40, uid[3], uid[2], uid[1], uid[0], 0x00, 0x00}
|
{ISO15_REQ_DATARATE_HIGH, ISO15693_MAGIC_WRITE, 0x09, 0x41, uid[3], uid[2], uid[1], uid[0], 0x00, 0x00}
|
||||||
};
|
};
|
||||||
|
|
||||||
AddCrc15(cmd[0], 8);
|
|
||||||
AddCrc15(cmd[1], 8);
|
|
||||||
|
|
||||||
uint8_t buf[ISO15693_MAX_RESPONSE_LENGTH] = {0x00};
|
uint8_t buf[ISO15693_MAX_RESPONSE_LENGTH] = {0x00};
|
||||||
|
|
||||||
uint32_t start_time = 0;
|
uint32_t start_time = 0;
|
||||||
|
@ -2958,6 +2955,8 @@ void SetTag15693Uid_v2(const uint8_t *uid) {
|
||||||
int res = PM3_SUCCESS;
|
int res = PM3_SUCCESS;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
||||||
|
AddCrc15(cmd[i], 8);
|
||||||
res = SendDataTag(
|
res = SendDataTag(
|
||||||
cmd[i],
|
cmd[i],
|
||||||
sizeof(cmd[i]),
|
sizeof(cmd[i]),
|
||||||
|
|
|
@ -263,6 +263,7 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/common/cardhelper.c
|
${PM3_ROOT}/common/cardhelper.c
|
||||||
${PM3_ROOT}/common/generator.c
|
${PM3_ROOT}/common/generator.c
|
||||||
${PM3_ROOT}/common/bruteforce.c
|
${PM3_ROOT}/common/bruteforce.c
|
||||||
|
${PM3_ROOT}/common/hitag2/hitag2_crypto.c
|
||||||
${PM3_ROOT}/client/src/crypto/asn1dump.c
|
${PM3_ROOT}/client/src/crypto/asn1dump.c
|
||||||
${PM3_ROOT}/client/src/crypto/asn1utils.c
|
${PM3_ROOT}/client/src/crypto/asn1utils.c
|
||||||
${PM3_ROOT}/client/src/crypto/libpcrypto.c
|
${PM3_ROOT}/client/src/crypto/libpcrypto.c
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
#
|
#
|
||||||
|
# Mifare Default Keys
|
||||||
|
# -- Iceman version --
|
||||||
|
# -- contribute to this list, sharing is caring --
|
||||||
|
#
|
||||||
|
# Lets see how long it takes before other project takes this file
|
||||||
|
# and claim they created it.
|
||||||
|
#
|
||||||
# factory HT2 pwd
|
# factory HT2 pwd
|
||||||
4D494B52
|
4D494B52
|
||||||
|
# factory HT2 crypto key
|
||||||
|
4F4E4D494B52
|
||||||
|
#
|
||||||
|
# Gone in 360 seconds
|
||||||
|
FFFF814632FF
|
||||||
|
#
|
||||||
|
# Paxton HT2
|
||||||
|
BDF5E846
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# GE HT2 reader
|
# GE HT2 reader
|
||||||
#
|
|
||||||
# TSPL
|
# TSPL
|
||||||
5453504C
|
5453504C
|
||||||
05040202
|
05040202
|
||||||
25293C2F
|
25293C2F
|
||||||
#
|
|
||||||
# Paxton HT2
|
|
||||||
BDF5E846
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,6 +22,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define HITAG_NRAR_SIZE 8
|
||||||
#define HITAG_CRYPTOKEY_SIZE 6
|
#define HITAG_CRYPTOKEY_SIZE 6
|
||||||
#define HITAG_PASSWORD_SIZE 4
|
#define HITAG_PASSWORD_SIZE 4
|
||||||
#define HITAG_UID_SIZE 4
|
#define HITAG_UID_SIZE 4
|
||||||
|
@ -37,16 +38,18 @@
|
||||||
|
|
||||||
#define HITAG2_CONFIG_BLOCK 3
|
#define HITAG2_CONFIG_BLOCK 3
|
||||||
#define HITAG2_CONFIG_OFFSET (HITAG_BLOCK_SIZE * HITAG2_CONFIG_BLOCK)
|
#define HITAG2_CONFIG_OFFSET (HITAG_BLOCK_SIZE * HITAG2_CONFIG_BLOCK)
|
||||||
|
#define HITAG_DICTIONARY "ht2_default"
|
||||||
|
|
||||||
int CmdLFHitag(const char *Cmd);
|
int CmdLFHitag(const char *Cmd);
|
||||||
|
|
||||||
int readHitagUid(void);
|
int readHitagUid(void);
|
||||||
void annotateHitag1(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response);
|
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);
|
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 annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response);
|
||||||
|
|
||||||
void annotateHitag2_init(void);
|
void annotateHitag2_init(void);
|
||||||
|
bool hitag2_get_plain(uint8_t *plain, uint8_t *plen);
|
||||||
|
void hitag2_annotate_plain(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, uint8_t bits);
|
||||||
|
|
||||||
uint8_t hitag1_CRC_check(uint8_t *d, uint32_t nbit);
|
uint8_t hitag1_CRC_check(uint8_t *d, uint32_t nbit);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -501,7 +501,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
|
|
||||||
uint32_t end_of_transmission_timestamp = 0;
|
uint32_t end_of_transmission_timestamp = 0;
|
||||||
uint8_t topaz_reader_command[9];
|
uint8_t topaz_reader_command[9];
|
||||||
char explanation[40] = {0};
|
char explanation[60] = {0};
|
||||||
tracelog_hdr_t *first_hdr = (tracelog_hdr_t *)(trace);
|
tracelog_hdr_t *first_hdr = (tracelog_hdr_t *)(trace);
|
||||||
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos);
|
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos);
|
||||||
|
|
||||||
|
@ -774,10 +774,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
|
|
||||||
end_of_transmission_timestamp = hdr->timestamp + duration;
|
end_of_transmission_timestamp = hdr->timestamp + duration;
|
||||||
|
|
||||||
if (prev_eot)
|
if (prev_eot) {
|
||||||
*prev_eot = end_of_transmission_timestamp;
|
*prev_eot = end_of_transmission_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Always annotate these protocols both reader/tag messages
|
// Always annotate these protocols both reader/tag messages
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
|
@ -793,7 +792,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
annotateHitag1(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
|
annotateHitag1(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
|
||||||
break;
|
break;
|
||||||
case PROTO_HITAG2:
|
case PROTO_HITAG2:
|
||||||
annotateHitag2(explanation, sizeof(explanation), frame, data_len, parityBytes[0], hdr->isResponse);
|
annotateHitag2(explanation, sizeof(explanation), frame, data_len, parityBytes[0], hdr->isResponse, mfDicKeys, mfDicKeysCount, false);
|
||||||
break;
|
break;
|
||||||
case PROTO_HITAGS:
|
case PROTO_HITAGS:
|
||||||
annotateHitagS(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
|
annotateHitagS(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
|
||||||
|
@ -979,6 +978,71 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (protocol == PROTO_HITAG2) {
|
||||||
|
|
||||||
|
uint8_t ht2plain[9] = {0};
|
||||||
|
uint8_t n = 0;
|
||||||
|
if (hitag2_get_plain(ht2plain, &n)) {
|
||||||
|
|
||||||
|
memset(explanation, 0x00, sizeof(explanation));
|
||||||
|
|
||||||
|
// handle partial bytes. The parity array[0] is used to store number of left over bits from NBYTES
|
||||||
|
// This part prints the number of bits in the trace entry for hitag.
|
||||||
|
uint8_t nbits = parityBytes[0];
|
||||||
|
|
||||||
|
annotateHitag2(explanation, sizeof(explanation), ht2plain, n, nbits, hdr->isResponse, NULL, 0, true);
|
||||||
|
|
||||||
|
// iceman: colorise crc bytes here will need a refactor of code from above.
|
||||||
|
for (int j = 0; j < n && (j / TRACE_MAX_HEX_BYTES) < TRACE_MAX_HEX_BYTES; j++) {
|
||||||
|
|
||||||
|
|
||||||
|
if (j == 0) {
|
||||||
|
|
||||||
|
// only apply this to lesser than one byte
|
||||||
|
if (n == 1) {
|
||||||
|
|
||||||
|
if (nbits == 5) {
|
||||||
|
snprintf(line[0], 120, "%2u: %02X ", nbits, ht2plain[0] >> (8 - nbits));
|
||||||
|
} else {
|
||||||
|
snprintf(line[0], 120, "%2u: %02X ", nbits, ht2plain[0] >> (8 - nbits));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (nbits == 0) {
|
||||||
|
snprintf(line[0], 120, "%2u: %02X ", (n * 8), ht2plain[0]);
|
||||||
|
} else {
|
||||||
|
snprintf(line[0], 120, "%2u: %02X ", ((n - 1) * 8) + nbits, ht2plain[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset = 4;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snprintf(line[j / 18] + ((j % 18) * 4) + offset, 120, "%02X ", ht2plain[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
num_lines = MIN((n - 1) / TRACE_MAX_HEX_BYTES + 1, TRACE_MAX_HEX_BYTES);
|
||||||
|
|
||||||
|
for (int j = 0; j < num_lines ; j++) {
|
||||||
|
if (hdr->isResponse) {
|
||||||
|
PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s",
|
||||||
|
str_padder,
|
||||||
|
line[j],
|
||||||
|
" ",
|
||||||
|
explanation);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(NORMAL, " | | * |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"),
|
||||||
|
str_padder,
|
||||||
|
line[j],
|
||||||
|
" ",
|
||||||
|
explanation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_last_record(tracepos, traceLen)) {
|
if (is_last_record(tracepos, traceLen)) {
|
||||||
return traceLen;
|
return traceLen;
|
||||||
}
|
}
|
||||||
|
@ -1436,6 +1500,30 @@ int CmdTraceList(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (protocol == PROTO_HITAG2) {
|
||||||
|
|
||||||
|
if (strlen(dictionary) == 0) {
|
||||||
|
snprintf(dictionary, sizeof(dictionary), HITAG_DICTIONARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load keys
|
||||||
|
uint8_t *keyBlock = NULL;
|
||||||
|
int res = loadFileDICTIONARY_safe(dictionary, (void **) &keyBlock, HITAG_CRYPTOKEY_SIZE, &dicKeysCount);
|
||||||
|
if (res != PM3_SUCCESS || dicKeysCount == 0 || keyBlock == NULL) {
|
||||||
|
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary!");
|
||||||
|
} else {
|
||||||
|
dicKeys = calloc(dicKeysCount, sizeof(uint64_t));
|
||||||
|
for (int i = 0; i < dicKeysCount; i++) {
|
||||||
|
uint64_t key = bytes_to_num(keyBlock + i * HITAG_CRYPTOKEY_SIZE, HITAG_CRYPTOKEY_SIZE);
|
||||||
|
memcpy((uint8_t *) &dicKeys[i], &key, sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
dictionaryLoad = true;
|
||||||
|
}
|
||||||
|
if (keyBlock != NULL) {
|
||||||
|
free(keyBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
if (use_relative) {
|
if (use_relative) {
|
||||||
PrintAndLogEx(NORMAL, " Gap | Duration | Src | Data (! denotes parity error, ' denotes short bytes) | CRC | Annotation");
|
PrintAndLogEx(NORMAL, " Gap | Duration | Src | Data (! denotes parity error, ' denotes short bytes) | CRC | Annotation");
|
||||||
|
@ -1463,16 +1551,19 @@ int CmdTraceList(const char *Cmd) {
|
||||||
while (tracepos < gs_traceLen) {
|
while (tracepos < gs_traceLen) {
|
||||||
tracepos = printTraceLine(tracepos, gs_traceLen, gs_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us, dicKeys, dicKeysCount);
|
tracepos = printTraceLine(tracepos, gs_traceLen, gs_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us, dicKeys, dicKeysCount);
|
||||||
|
|
||||||
if (kbd_enter_pressed())
|
if (kbd_enter_pressed()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dictionaryLoad)
|
|
||||||
free((void *) dicKeys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_hex)
|
if (dictionaryLoad) {
|
||||||
|
free((void *) dicKeys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_hex) {
|
||||||
PrintAndLogEx(HINT, "syntax to use: " _YELLOW_("`text2pcap -t \"%%S.\" -l 264 -n <input-text-file> <output-pcapng-file>`"));
|
PrintAndLogEx(HINT, "syntax to use: " _YELLOW_("`text2pcap -t \"%%S.\" -l 264 -n <input-text-file> <output-pcapng-file>`"));
|
||||||
|
}
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,34 +127,38 @@ void des3_decrypt(void *out, const void *in, const void *key, uint8_t keycount)
|
||||||
// NIST Special Publication 800-38A — Recommendation for block cipher modes of operation: methods and techniques, 2001.
|
// NIST Special Publication 800-38A — Recommendation for block cipher modes of operation: methods and techniques, 2001.
|
||||||
int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length) {
|
int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length) {
|
||||||
uint8_t iiv[16] = {0};
|
uint8_t iiv[16] = {0};
|
||||||
if (iv)
|
if (iv) {
|
||||||
memcpy(iiv, iv, 16);
|
memcpy(iiv, iv, 16);
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_aes_context aes;
|
mbedtls_aes_context aes;
|
||||||
mbedtls_aes_init(&aes);
|
mbedtls_aes_init(&aes);
|
||||||
if (mbedtls_aes_setkey_enc(&aes, key, 128))
|
if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
|
||||||
return 1;
|
return 1;
|
||||||
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, length, iiv, input, output))
|
}
|
||||||
|
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, length, iiv, input, output)) {
|
||||||
return 2;
|
return 2;
|
||||||
|
}
|
||||||
mbedtls_aes_free(&aes);
|
mbedtls_aes_free(&aes);
|
||||||
|
return PM3_SUCCESS;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length) {
|
int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length) {
|
||||||
uint8_t iiv[16] = {0};
|
uint8_t iiv[16] = {0};
|
||||||
if (iv)
|
if (iv) {
|
||||||
memcpy(iiv, iv, 16);
|
memcpy(iiv, iv, 16);
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_aes_context aes;
|
mbedtls_aes_context aes;
|
||||||
mbedtls_aes_init(&aes);
|
mbedtls_aes_init(&aes);
|
||||||
if (mbedtls_aes_setkey_dec(&aes, key, 128))
|
if (mbedtls_aes_setkey_dec(&aes, key, 128)) {
|
||||||
return 1;
|
return 1;
|
||||||
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, length, iiv, input, output))
|
}
|
||||||
|
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, length, iiv, input, output)) {
|
||||||
return 2;
|
return 2;
|
||||||
|
}
|
||||||
mbedtls_aes_free(&aes);
|
mbedtls_aes_free(&aes);
|
||||||
|
return PM3_SUCCESS;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NIST Special Publication 800-38B — Recommendation for block cipher modes of operation: The CMAC mode for authentication.
|
// NIST Special Publication 800-38B — Recommendation for block cipher modes of operation: The CMAC mode for authentication.
|
||||||
|
@ -171,13 +175,14 @@ int aes_cmac8(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int lengt
|
||||||
memset(mac, 0x00, 8);
|
memset(mac, 0x00, 8);
|
||||||
|
|
||||||
int res = aes_cmac(iv, key, input, cmac_tmp, length);
|
int res = aes_cmac(iv, key, input, cmac_tmp, length);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++) {
|
||||||
mac[i] = cmac_tmp[i * 2 + 1];
|
mac[i] = cmac_tmp[i * 2 + 1];
|
||||||
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t fixed_rand_value[250] = {0};
|
static uint8_t fixed_rand_value[250] = {0};
|
||||||
|
@ -188,21 +193,23 @@ static int fixed_rand(void *rng_state, unsigned char *output, size_t len) {
|
||||||
memset(output, 0x00, len);
|
memset(output, 0x00, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sha1hash(uint8_t *input, int length, uint8_t *hash) {
|
int sha1hash(uint8_t *input, int length, uint8_t *hash) {
|
||||||
if (!hash || !input)
|
if (!hash || !input) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_sha1(input, length, hash);
|
mbedtls_sha1(input, length, hash);
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sha256hash(uint8_t *input, int length, uint8_t *hash) {
|
int sha256hash(uint8_t *input, int length, uint8_t *hash) {
|
||||||
if (!hash || !input)
|
if (!hash || !input) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_sha256_context sctx;
|
mbedtls_sha256_context sctx;
|
||||||
mbedtls_sha256_init(&sctx);
|
mbedtls_sha256_init(&sctx);
|
||||||
|
@ -211,12 +218,13 @@ int sha256hash(uint8_t *input, int length, uint8_t *hash) {
|
||||||
mbedtls_sha256_finish(&sctx, hash);
|
mbedtls_sha256_finish(&sctx, hash);
|
||||||
mbedtls_sha256_free(&sctx);
|
mbedtls_sha256_free(&sctx);
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sha512hash(uint8_t *input, int length, uint8_t *hash) {
|
int sha512hash(uint8_t *input, int length, uint8_t *hash) {
|
||||||
if (!hash || !input)
|
if (!hash || !input) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_sha512_context sctx;
|
mbedtls_sha512_context sctx;
|
||||||
mbedtls_sha512_init(&sctx);
|
mbedtls_sha512_init(&sctx);
|
||||||
|
@ -225,33 +233,35 @@ int sha512hash(uint8_t *input, int length, uint8_t *hash) {
|
||||||
mbedtls_sha512_finish(&sctx, hash);
|
mbedtls_sha512_finish(&sctx, hash);
|
||||||
mbedtls_sha512_free(&sctx);
|
mbedtls_sha512_free(&sctx);
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, const char *key_d, const char *key_x, const char *key_y) {
|
static int ecdsa_init_str(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, const char *key_d, const char *key_x, const char *key_y) {
|
||||||
if (!ctx)
|
if (!ctx) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
int res;
|
|
||||||
|
|
||||||
mbedtls_ecdsa_init(ctx);
|
mbedtls_ecdsa_init(ctx);
|
||||||
res = mbedtls_ecp_group_load(&ctx->grp, curveid);
|
int res = mbedtls_ecp_group_load(&ctx->grp, curveid);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (key_d) {
|
if (key_d) {
|
||||||
res = mbedtls_mpi_read_string(&ctx->d, 16, key_d);
|
res = mbedtls_mpi_read_string(&ctx->d, 16, key_d);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (key_x && key_y) {
|
if (key_x && key_y) {
|
||||||
res = mbedtls_ecp_point_read_string(&ctx->Q, 16, key_x, key_y);
|
res = mbedtls_ecp_point_read_string(&ctx->Q, 16, key_x, key_y);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ecdsa_init(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) {
|
static int ecdsa_init(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) {
|
||||||
|
@ -278,7 +288,7 @@ static int ecdsa_init(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id curveid,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) {
|
int ecdsa_key_create(mbedtls_ecp_group_id curveid, uint8_t *key_d, uint8_t *key_xy) {
|
||||||
|
@ -519,8 +529,9 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
size_t siglen = 0;
|
size_t siglen = 0;
|
||||||
|
|
||||||
// NIST ecdsa test
|
// NIST ecdsa test
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, " ECDSA NIST test: " NOLF);
|
PrintAndLogEx(INFO, "ECDSA NIST test " NOLF);
|
||||||
|
}
|
||||||
// make signature
|
// make signature
|
||||||
res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen);
|
res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen);
|
||||||
// PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen));
|
// PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen));
|
||||||
|
@ -540,15 +551,16 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
uint8_t sval_s[33] = {0};
|
uint8_t sval_s[33] = {0};
|
||||||
param_gethex_to_eol(T_S, 0, sval_s, sizeof(sval_s), &slen);
|
param_gethex_to_eol(T_S, 0, sval_s, sizeof(sval_s), &slen);
|
||||||
if (strncmp((char *)rval, (char *)rval_s, 32) || strncmp((char *)sval, (char *)sval_s, 32)) {
|
if (strncmp((char *)rval, (char *)rval_s, 32) || strncmp((char *)sval, (char *)sval_s, 32)) {
|
||||||
PrintAndLogEx(INFO, "R or S check error");
|
PrintAndLogEx(NORMAL, "( " _RED_("R or S check error") " )");
|
||||||
res = 100;
|
res = 100;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify signature
|
// verify signature
|
||||||
res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true);
|
res = ecdsa_signature_verify_keystr(curveid, T_Q_X, T_Q_Y, input, length, signature, siglen, true);
|
||||||
if (res)
|
if (res) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
// verify wrong signature
|
// verify wrong signature
|
||||||
input[0] ^= 0xFF;
|
input[0] ^= 0xFF;
|
||||||
|
@ -559,8 +571,8 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(NORMAL, _GREEN_("passed"));
|
PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )");
|
||||||
PrintAndLogEx(INFO, " ECDSA binary signature create/check test: " NOLF);
|
PrintAndLogEx(INFO, "ECDSA binary signature create/check test " NOLF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// random ecdsa test
|
// random ecdsa test
|
||||||
|
@ -587,12 +599,12 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(NORMAL, _GREEN_("passed\n"));
|
PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
exit:
|
exit:
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(NORMAL, _RED_("failed\n"));
|
PrintAndLogEx(NORMAL, "( " _RED_("fail") " )");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -536,8 +536,7 @@ SWIG_TypePrettyName(const swig_type_info *type) {
|
||||||
for (s = type->str; *s; s++)
|
for (s = type->str; *s; s++)
|
||||||
if (*s == '|') last_name = s + 1;
|
if (*s == '|') last_name = s + 1;
|
||||||
return last_name;
|
return last_name;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return type->name;
|
return type->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,8 +962,7 @@ static const char *(lua_tolstring)(lua_State *L, int idx, size_t *len) {
|
||||||
prefixed with the location of the innermost Lua call-point
|
prefixed with the location of the innermost Lua call-point
|
||||||
(as formatted by luaL_where). */
|
(as formatted by luaL_where). */
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Lua_pusherrstring (lua_State *L, const char *str)
|
SWIG_Lua_pusherrstring(lua_State *L, const char *str) {
|
||||||
{
|
|
||||||
luaL_where(L, 1);
|
luaL_where(L, 1);
|
||||||
lua_pushstring(L, str);
|
lua_pushstring(L, str);
|
||||||
lua_concat(L, 2);
|
lua_concat(L, 2);
|
||||||
|
@ -974,8 +972,7 @@ SWIG_Lua_pusherrstring (lua_State *L, const char *str)
|
||||||
the Lua stack, like lua_pushfstring, but prefixed with the
|
the Lua stack, like lua_pushfstring, but prefixed with the
|
||||||
location of the innermost Lua call-point (as formatted by luaL_where). */
|
location of the innermost Lua call-point (as formatted by luaL_where). */
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Lua_pushferrstring (lua_State *L, const char *fmt, ...)
|
SWIG_Lua_pushferrstring(lua_State *L, const char *fmt, ...) {
|
||||||
{
|
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
luaL_where(L, 1);
|
luaL_where(L, 1);
|
||||||
|
@ -1153,8 +1150,7 @@ SWIG_Lua_SetModule(lua_State *L, swig_module_info *module) {
|
||||||
/* this function is called when trying to set an immutable.
|
/* this function is called when trying to set an immutable.
|
||||||
default action is to print an error.
|
default action is to print an error.
|
||||||
This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */
|
This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */
|
||||||
SWIGINTERN int SWIG_Lua_set_immutable(lua_State *L)
|
SWIGINTERN int SWIG_Lua_set_immutable(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 1 param passed in: the new value */
|
/* there should be 1 param passed in: the new value */
|
||||||
#ifndef SWIGLUA_IGNORE_SET_IMMUTABLE
|
#ifndef SWIGLUA_IGNORE_SET_IMMUTABLE
|
||||||
lua_pop(L, 1); /* remove it */
|
lua_pop(L, 1); /* remove it */
|
||||||
|
@ -1170,8 +1166,7 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_t
|
||||||
static int swig_lua_elua_emulate_unique_key;
|
static int swig_lua_elua_emulate_unique_key;
|
||||||
|
|
||||||
/* This function emulates eLua rotables behaviour. It loads a rotable definition into the usual lua table. */
|
/* This function emulates eLua rotables behaviour. It loads a rotable definition into the usual lua table. */
|
||||||
SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_entry *table)
|
SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_entry *table) {
|
||||||
{
|
|
||||||
int i, table_parsed, parsed_tables_array, target_table;
|
int i, table_parsed, parsed_tables_array, target_table;
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
target_table = lua_gettop(L);
|
target_table = lua_gettop(L);
|
||||||
|
@ -1188,8 +1183,7 @@ SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_ent
|
||||||
lua_rawsetp(L, parsed_tables_array, table);
|
lua_rawsetp(L, parsed_tables_array, table);
|
||||||
table_parsed = 0;
|
table_parsed = 0;
|
||||||
const int SWIGUNUSED pairs_start = lua_gettop(L);
|
const int SWIGUNUSED pairs_start = lua_gettop(L);
|
||||||
for(i = 0;table[i].key.type != LUA_TNIL || table[i].value.type != LUA_TNIL;i++)
|
for (i = 0; table[i].key.type != LUA_TNIL || table[i].value.type != LUA_TNIL; i++) {
|
||||||
{
|
|
||||||
const swig_elua_entry *entry = table + i;
|
const swig_elua_entry *entry = table + i;
|
||||||
int is_metatable = 0;
|
int is_metatable = 0;
|
||||||
switch (entry->key.type) {
|
switch (entry->key.type) {
|
||||||
|
@ -1254,16 +1248,14 @@ SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_ent
|
||||||
assert(lua_gettop(L) == target_table);
|
assert(lua_gettop(L) == target_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_elua_emulate_register_clear(lua_State *L)
|
SWIGINTERN void SWIG_Lua_elua_emulate_register_clear(lua_State *L) {
|
||||||
{
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
lua_rawsetp(L, LUA_REGISTRYINDEX, &swig_lua_elua_emulate_unique_key);
|
lua_rawsetp(L, LUA_REGISTRYINDEX, &swig_lua_elua_emulate_unique_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L);
|
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L);
|
||||||
|
|
||||||
SWIGINTERN int SWIG_Lua_emulate_elua_getmetatable(lua_State *L)
|
SWIGINTERN int SWIG_Lua_emulate_elua_getmetatable(lua_State *L) {
|
||||||
{
|
|
||||||
SWIG_check_num_args("getmetatable(SWIG eLua emulation)", 1, 1);
|
SWIG_check_num_args("getmetatable(SWIG eLua emulation)", 1, 1);
|
||||||
SWIG_Lua_get_class_registry(L);
|
SWIG_Lua_get_class_registry(L);
|
||||||
lua_getfield(L, -1, "lua_getmetatable");
|
lua_getfield(L, -1, "lua_getmetatable");
|
||||||
|
@ -1288,8 +1280,7 @@ fail:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L)
|
SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L) {
|
||||||
{
|
|
||||||
SWIG_Lua_get_class_registry(L);
|
SWIG_Lua_get_class_registry(L);
|
||||||
lua_pushglobaltable(L);
|
lua_pushglobaltable(L);
|
||||||
lua_pushstring(L, "lua_getmetatable");
|
lua_pushstring(L, "lua_getmetatable");
|
||||||
|
@ -1309,8 +1300,7 @@ SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L)
|
||||||
* global variable support code: namespaces and modules (which are the same thing)
|
* global variable support code: namespaces and modules (which are the same thing)
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 2 params passed in
|
/* there should be 2 params passed in
|
||||||
(1) table (not the meta table)
|
(1) table (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1324,8 +1314,8 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
||||||
lua_pushvalue(L, 2); /* key */
|
lua_pushvalue(L, 2); /* key */
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
lua_remove(L, -2); /* stack tidy, remove .get table */
|
lua_remove(L, -2); /* stack tidy, remove .get table */
|
||||||
if (lua_iscfunction(L,-1))
|
if (lua_iscfunction(L, -1)) {
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_call(L, 0, 1); /* 1 value in (userdata),1 out (result) */
|
lua_call(L, 0, 1); /* 1 value in (userdata),1 out (result) */
|
||||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1337,8 +1327,8 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
||||||
lua_pushvalue(L, 2); /* key */
|
lua_pushvalue(L, 2); /* key */
|
||||||
lua_rawget(L, -2); /* look for the fn */
|
lua_rawget(L, -2); /* look for the fn */
|
||||||
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
||||||
if (lua_isfunction(L,-1)) /* note: whether it's a C function or lua function */
|
if (lua_isfunction(L, -1)) { /* note: whether it's a C function or lua function */
|
||||||
{ /* found it so return the fn & let lua call it */
|
/* found it so return the fn & let lua call it */
|
||||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1346,8 +1336,7 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L)
|
SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 3 params passed in
|
/* there should be 3 params passed in
|
||||||
(1) table (not the meta table)
|
(1) table (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1359,13 +1348,12 @@ SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L)
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
|
|
||||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||||
if (lua_istable(L,-1))
|
if (lua_istable(L, -1)) {
|
||||||
{
|
|
||||||
/* look for the key in the .set table */
|
/* look for the key in the .set table */
|
||||||
lua_pushvalue(L, 2); /* key */
|
lua_pushvalue(L, 2); /* key */
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
if (lua_iscfunction(L,-1))
|
if (lua_iscfunction(L, -1)) {
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_pushvalue(L, 3); /* value */
|
lua_pushvalue(L, 3); /* value */
|
||||||
lua_call(L, 1, 0);
|
lua_call(L, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1384,8 +1372,7 @@ SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFuncti
|
||||||
SWIGINTERN void SWIG_Lua_class_register(lua_State *L, swig_lua_class *clss);
|
SWIGINTERN void SWIG_Lua_class_register(lua_State *L, swig_lua_class *clss);
|
||||||
|
|
||||||
/* helper function - register namespace methods and attributes into namespace */
|
/* helper function - register namespace methods and attributes into namespace */
|
||||||
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *ns)
|
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *ns) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
/* There must be namespace table (not metatable) at the top of the stack */
|
/* There must be namespace table (not metatable) at the top of the stack */
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
|
@ -1408,8 +1395,7 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register all classes in the namespace */
|
/* Register all classes in the namespace */
|
||||||
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace *ns)
|
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace *ns) {
|
||||||
{
|
|
||||||
swig_lua_class **classes;
|
swig_lua_class **classes;
|
||||||
|
|
||||||
/* There must be a module/namespace table at the top of the stack */
|
/* There must be a module/namespace table at the top of the stack */
|
||||||
|
@ -1430,8 +1416,7 @@ SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace
|
||||||
when function is called).
|
when function is called).
|
||||||
Function always returns newly registered table on top of the stack.
|
Function always returns newly registered table on top of the stack.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN void SWIG_Lua_namespace_register(lua_State *L, swig_lua_namespace *ns, int reg)
|
SWIGINTERN void SWIG_Lua_namespace_register(lua_State *L, swig_lua_namespace *ns, int reg) {
|
||||||
{
|
|
||||||
swig_lua_namespace **sub_namespace;
|
swig_lua_namespace **sub_namespace;
|
||||||
/* 1 argument - table on the top of the stack */
|
/* 1 argument - table on the top of the stack */
|
||||||
const int SWIGUNUSED begin = lua_gettop(L);
|
const int SWIGUNUSED begin = lua_gettop(L);
|
||||||
|
@ -1491,8 +1476,7 @@ SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname);
|
||||||
typedef int (*swig_lua_base_iterator_func)(lua_State *, swig_type_info *, int, int *ret);
|
typedef int (*swig_lua_base_iterator_func)(lua_State *, swig_type_info *, int, int *ret);
|
||||||
|
|
||||||
SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info *SWIGUNUSED swig_type,
|
SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info *SWIGUNUSED swig_type,
|
||||||
int first_arg, swig_lua_base_iterator_func func, int *const ret)
|
int first_arg, swig_lua_base_iterator_func func, int *const ret) {
|
||||||
{
|
|
||||||
/* first_arg - position of the object in stack. Everything that is above are arguments
|
/* first_arg - position of the object in stack. Everything that is above are arguments
|
||||||
* and is passed to every evocation of the func */
|
* and is passed to every evocation of the func */
|
||||||
int last_arg = lua_gettop(L);/* position of last argument */
|
int last_arg = lua_gettop(L);/* position of last argument */
|
||||||
|
@ -1523,8 +1507,7 @@ SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info * SWIGUNUSED
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = 0;
|
*ret = 0;
|
||||||
if(bases_count>0)
|
if (bases_count > 0) {
|
||||||
{
|
|
||||||
int to_remove;
|
int to_remove;
|
||||||
size_t i;
|
size_t i;
|
||||||
int j;
|
int j;
|
||||||
|
@ -1590,8 +1573,7 @@ SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info * SWIGUNUSED
|
||||||
* It returns an error code. Number of function return values is passed inside 'ret'.
|
* It returns an error code. Number of function return values is passed inside 'ret'.
|
||||||
* first_arg is not used in this function because function always has 2 arguments.
|
* first_arg is not used in this function because function always has 2 arguments.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret)
|
SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret) {
|
||||||
{
|
|
||||||
/* there should be 2 params passed in
|
/* there should be 2 params passed in
|
||||||
(1) userdata (not the meta table)
|
(1) userdata (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1607,8 +1589,8 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i
|
||||||
/* NEW: looks for the __getitem() fn
|
/* NEW: looks for the __getitem() fn
|
||||||
this is a user provided get fn */
|
this is a user provided get fn */
|
||||||
SWIG_Lua_get_table(L, "__getitem"); /* find the __getitem fn */
|
SWIG_Lua_get_table(L, "__getitem"); /* find the __getitem fn */
|
||||||
if (lua_iscfunction(L,-1)) /* if it's there */
|
if (lua_iscfunction(L, -1)) { /* if it's there */
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||||
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
||||||
lua_call(L, 2, 1); /* 2 value in (userdata),1 out (result) */
|
lua_call(L, 2, 1); /* 2 value in (userdata),1 out (result) */
|
||||||
|
@ -1629,8 +1611,7 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i
|
||||||
* It returns an error code. Number of function return values is passed inside 'ret'.
|
* It returns an error code. Number of function return values is passed inside 'ret'.
|
||||||
* first_arg is not used in this function because function always has 2 arguments.
|
* first_arg is not used in this function because function always has 2 arguments.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret)
|
SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret) {
|
||||||
{
|
|
||||||
/* there should be 2 params passed in
|
/* there should be 2 params passed in
|
||||||
(1) userdata (not the meta table)
|
(1) userdata (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1649,8 +1630,8 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
||||||
lua_pushvalue(L, substack_start + 2); /* key */
|
lua_pushvalue(L, substack_start + 2); /* key */
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
lua_remove(L, -2); /* stack tidy, remove .get table */
|
lua_remove(L, -2); /* stack tidy, remove .get table */
|
||||||
if (lua_iscfunction(L,-1))
|
if (lua_iscfunction(L, -1)) {
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||||
lua_call(L, 1, 1); /* 1 value in (userdata),1 out (result) */
|
lua_call(L, 1, 1); /* 1 value in (userdata),1 out (result) */
|
||||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||||
|
@ -1665,8 +1646,8 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
||||||
lua_pushvalue(L, substack_start + 2); /* key */
|
lua_pushvalue(L, substack_start + 2); /* key */
|
||||||
lua_rawget(L, -2); /* look for the fn */
|
lua_rawget(L, -2); /* look for the fn */
|
||||||
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
||||||
if (lua_isfunction(L,-1)) /* note: if it's a C function or lua function */
|
if (lua_isfunction(L, -1)) { /* note: if it's a C function or lua function */
|
||||||
{ /* found it so return the fn & let lua call it */
|
/* found it so return the fn & let lua call it */
|
||||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = 1;
|
*ret = 1;
|
||||||
|
@ -1682,8 +1663,7 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
||||||
|
|
||||||
/* the class.get method, performs the lookup of class attributes
|
/* the class.get method, performs the lookup of class attributes
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_class_get(lua_State *L)
|
SWIGINTERN int SWIG_Lua_class_get(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 2 params passed in
|
/* there should be 2 params passed in
|
||||||
(1) userdata (not the meta table)
|
(1) userdata (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1709,8 +1689,7 @@ SWIGINTERN int SWIG_Lua_class_get(lua_State *L)
|
||||||
/* helper for the class.set method, performs the lookup of class attributes
|
/* helper for the class.set method, performs the lookup of class attributes
|
||||||
* It returns error code. Number of function return values is passed inside 'ret'
|
* It returns error code. Number of function return values is passed inside 'ret'
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int first_arg, int *ret)
|
SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int first_arg, int *ret) {
|
||||||
{
|
|
||||||
/* there should be 3 params passed in
|
/* there should be 3 params passed in
|
||||||
(1) table (not the meta table)
|
(1) table (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1727,14 +1706,13 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
||||||
*ret = 0; /* it is setter - number of return values is always 0 */
|
*ret = 0; /* it is setter - number of return values is always 0 */
|
||||||
|
|
||||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||||
if (lua_istable(L,-1))
|
if (lua_istable(L, -1)) {
|
||||||
{
|
|
||||||
/* look for the key in the .set table */
|
/* look for the key in the .set table */
|
||||||
lua_pushvalue(L, substack_start + 2); /* key */
|
lua_pushvalue(L, substack_start + 2); /* key */
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
lua_remove(L, -2); /* tidy stack, remove .set table */
|
lua_remove(L, -2); /* tidy stack, remove .set table */
|
||||||
if (lua_iscfunction(L,-1))
|
if (lua_iscfunction(L, -1)) {
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_pushvalue(L, substack_start + 1); /* userdata */
|
lua_pushvalue(L, substack_start + 1); /* userdata */
|
||||||
lua_pushvalue(L, substack_start + 3); /* value */
|
lua_pushvalue(L, substack_start + 3); /* value */
|
||||||
lua_call(L, 2, 0);
|
lua_call(L, 2, 0);
|
||||||
|
@ -1748,8 +1726,8 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
||||||
/* NEW: looks for the __setitem() fn
|
/* NEW: looks for the __setitem() fn
|
||||||
this is a user provided set fn */
|
this is a user provided set fn */
|
||||||
SWIG_Lua_get_table(L, "__setitem"); /* find the fn */
|
SWIG_Lua_get_table(L, "__setitem"); /* find the fn */
|
||||||
if (lua_iscfunction(L,-1)) /* if it's there */
|
if (lua_iscfunction(L, -1)) { /* if it's there */
|
||||||
{ /* found it so call the fn & return its value */
|
/* found it so call the fn & return its value */
|
||||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||||
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
||||||
lua_pushvalue(L, substack_start + 3); /* the value */
|
lua_pushvalue(L, substack_start + 3); /* the value */
|
||||||
|
@ -1771,8 +1749,7 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
||||||
/* This is the actual method exported to Lua. It calls SWIG_Lua_class_do_set and correctly
|
/* This is the actual method exported to Lua. It calls SWIG_Lua_class_do_set and correctly
|
||||||
* handles return values.
|
* handles return values.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_class_set(lua_State *L)
|
SWIGINTERN int SWIG_Lua_class_set(lua_State *L) {
|
||||||
{
|
|
||||||
/* There should be 3 params passed in
|
/* There should be 3 params passed in
|
||||||
(1) table (not the meta table)
|
(1) table (not the meta table)
|
||||||
(2) string name of the attribute
|
(2) string name of the attribute
|
||||||
|
@ -1796,8 +1773,7 @@ SWIGINTERN int SWIG_Lua_class_set(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the class.destruct method called by the interpreter */
|
/* the class.destruct method called by the interpreter */
|
||||||
SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 1 params passed in
|
/* there should be 1 params passed in
|
||||||
(1) userdata (not the meta table) */
|
(1) userdata (not the meta table) */
|
||||||
swig_lua_userdata *usr;
|
swig_lua_userdata *usr;
|
||||||
|
@ -1805,11 +1781,9 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
||||||
assert(lua_isuserdata(L, -1)); /* just in case */
|
assert(lua_isuserdata(L, -1)); /* just in case */
|
||||||
usr = (swig_lua_userdata *)lua_touserdata(L, -1); /* get it */
|
usr = (swig_lua_userdata *)lua_touserdata(L, -1); /* get it */
|
||||||
/* if must be destroyed & has a destructor */
|
/* if must be destroyed & has a destructor */
|
||||||
if (usr->own) /* if must be destroyed */
|
if (usr->own) { /* if must be destroyed */
|
||||||
{
|
|
||||||
clss = (swig_lua_class *)usr->type->clientdata; /* get the class */
|
clss = (swig_lua_class *)usr->type->clientdata; /* get the class */
|
||||||
if (clss && clss->destructor) /* there is a destroy fn */
|
if (clss && clss->destructor) { /* there is a destroy fn */
|
||||||
{
|
|
||||||
clss->destructor(usr->ptr); /* bye bye */
|
clss->destructor(usr->ptr); /* bye bye */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1817,8 +1791,7 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the class.__tostring method called by the interpreter and print */
|
/* the class.__tostring method called by the interpreter and print */
|
||||||
SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L)
|
SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 1 param passed in
|
/* there should be 1 param passed in
|
||||||
(1) userdata (not the metatable) */
|
(1) userdata (not the metatable) */
|
||||||
swig_lua_userdata *userData;
|
swig_lua_userdata *userData;
|
||||||
|
@ -1830,8 +1803,7 @@ SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* to manually disown some userdata */
|
/* to manually disown some userdata */
|
||||||
SWIGINTERN int SWIG_Lua_class_disown(lua_State *L)
|
SWIGINTERN int SWIG_Lua_class_disown(lua_State *L) {
|
||||||
{
|
|
||||||
/* there should be 1 params passed in
|
/* there should be 1 params passed in
|
||||||
(1) userdata (not the meta table) */
|
(1) userdata (not the meta table) */
|
||||||
swig_lua_userdata *usr;
|
swig_lua_userdata *usr;
|
||||||
|
@ -1845,8 +1817,7 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State *L)
|
||||||
/* lua callable function to compare userdata's value
|
/* lua callable function to compare userdata's value
|
||||||
the issue is that two userdata may point to the same thing
|
the issue is that two userdata may point to the same thing
|
||||||
but to lua, they are different objects */
|
but to lua, they are different objects */
|
||||||
SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L)
|
SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L) {
|
||||||
{
|
|
||||||
int result;
|
int result;
|
||||||
swig_lua_userdata *usr1, *usr2;
|
swig_lua_userdata *usr1, *usr2;
|
||||||
if (!lua_isuserdata(L, 1) || !lua_isuserdata(L, 2)) /* just in case */
|
if (!lua_isuserdata(L, 1) || !lua_isuserdata(L, 2)) /* just in case */
|
||||||
|
@ -1860,8 +1831,7 @@ SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* populate table at the top of the stack with metamethods that ought to be inherited */
|
/* populate table at the top of the stack with metamethods that ought to be inherited */
|
||||||
SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L)
|
SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L) {
|
||||||
{
|
|
||||||
SWIG_Lua_add_boolean(L, "__add", 1);
|
SWIG_Lua_add_boolean(L, "__add", 1);
|
||||||
SWIG_Lua_add_boolean(L, "__sub", 1);
|
SWIG_Lua_add_boolean(L, "__sub", 1);
|
||||||
SWIG_Lua_add_boolean(L, "__mul", 1);
|
SWIG_Lua_add_boolean(L, "__mul", 1);
|
||||||
|
@ -1880,8 +1850,7 @@ SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creates the swig registry */
|
/* creates the swig registry */
|
||||||
SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L)
|
SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L) {
|
||||||
{
|
|
||||||
/* create main SWIG registry table */
|
/* create main SWIG registry table */
|
||||||
lua_pushstring(L, "SWIG");
|
lua_pushstring(L, "SWIG");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
@ -1904,13 +1873,12 @@ SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gets the swig registry (or creates it) */
|
/* gets the swig registry (or creates it) */
|
||||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L) {
|
||||||
{
|
|
||||||
/* add this all into the swig registry: */
|
/* add this all into the swig registry: */
|
||||||
lua_pushstring(L, "SWIG");
|
lua_pushstring(L, "SWIG");
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get the registry */
|
lua_rawget(L, LUA_REGISTRYINDEX); /* get the registry */
|
||||||
if (!lua_istable(L,-1)) /* not there */
|
if (!lua_istable(L, -1)) { /* not there */
|
||||||
{ /* must be first time, so add it */
|
/* must be first time, so add it */
|
||||||
lua_pop(L, 1); /* remove the result */
|
lua_pop(L, 1); /* remove the result */
|
||||||
SWIG_Lua_create_class_registry(L);
|
SWIG_Lua_create_class_registry(L);
|
||||||
/* then get it */
|
/* then get it */
|
||||||
|
@ -1919,8 +1887,7 @@ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L)
|
SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L) {
|
||||||
{
|
|
||||||
SWIG_Lua_get_class_registry(L);
|
SWIG_Lua_get_class_registry(L);
|
||||||
lua_pushstring(L, ".library");
|
lua_pushstring(L, ".library");
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
|
@ -1934,8 +1901,7 @@ SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to get the classes metatable from the register */
|
/* Helper function to get the classes metatable from the register */
|
||||||
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname)
|
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L, const char *cname) {
|
||||||
{
|
|
||||||
SWIG_Lua_get_class_registry(L); /* get the registry */
|
SWIG_Lua_get_class_registry(L); /* get the registry */
|
||||||
lua_pushstring(L, cname); /* get the name */
|
lua_pushstring(L, cname); /* get the name */
|
||||||
lua_rawget(L, -2); /* get it */
|
lua_rawget(L, -2); /* get it */
|
||||||
|
@ -1949,14 +1915,11 @@ It cannot be done at compile time, as this will not work with hireachies
|
||||||
spread over more than one swig file.
|
spread over more than one swig file.
|
||||||
Therefore it must be done at runtime, querying the SWIG type system.
|
Therefore it must be done at runtime, querying the SWIG type system.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L,swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
swig_module_info *module = SWIG_GetModule(L);
|
swig_module_info *module = SWIG_GetModule(L);
|
||||||
for(i=0;clss->base_names[i];i++)
|
for (i = 0; clss->base_names[i]; i++) {
|
||||||
{
|
if (clss->bases[i] == 0) { /* not found yet */
|
||||||
if (clss->bases[i]==0) /* not found yet */
|
|
||||||
{
|
|
||||||
/* lookup and cache the base class */
|
/* lookup and cache the base class */
|
||||||
swig_type_info *info = SWIG_TypeQueryModule(module, module, clss->base_names[i]);
|
swig_type_info *info = SWIG_TypeQueryModule(module, module, clss->base_names[i]);
|
||||||
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
|
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
|
||||||
|
@ -1966,8 +1929,7 @@ SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L,swig_lua_class *clss)
|
||||||
|
|
||||||
#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA)
|
#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA)
|
||||||
/* Merges two tables */
|
/* Merges two tables */
|
||||||
SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int source)
|
SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int source) {
|
||||||
{
|
|
||||||
/* iterating */
|
/* iterating */
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, source) != 0) {
|
while (lua_next(L, source) != 0) {
|
||||||
|
@ -1982,8 +1944,7 @@ SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int sou
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Merges two tables with given name. original - index of target metatable, base - index of source metatable */
|
/* Merges two tables with given name. original - index of target metatable, base - index of source metatable */
|
||||||
SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char* name, int original, int base)
|
SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char *name, int original, int base) {
|
||||||
{
|
|
||||||
/* push original[name], then base[name] */
|
/* push original[name], then base[name] */
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
lua_rawget(L, original);
|
lua_rawget(L, original);
|
||||||
|
@ -1997,8 +1958,7 @@ SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char* name, int origin
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function takes all symbols from base and adds it to derived class. It's just a helper. */
|
/* Function takes all symbols from base and adds it to derived class. It's just a helper. */
|
||||||
SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cls)
|
SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cls) {
|
||||||
{
|
|
||||||
/* There is one parameter - original, i.e. 'derived' class metatable */
|
/* There is one parameter - original, i.e. 'derived' class metatable */
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
int original = lua_gettop(L);
|
int original = lua_gettop(L);
|
||||||
|
@ -2011,12 +1971,10 @@ SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cl
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function squashes all symbols from 'clss' bases into itself */
|
/* Function squashes all symbols from 'clss' bases into itself */
|
||||||
SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
SWIG_Lua_get_class_metatable(L, clss->fqname);
|
SWIG_Lua_get_class_metatable(L, clss->fqname);
|
||||||
for(i=0;clss->base_names[i];i++)
|
for (i = 0; clss->base_names[i]; i++) {
|
||||||
{
|
|
||||||
if (clss->bases[i] == 0) /* Somehow it's not found. Skip it */
|
if (clss->bases[i] == 0) /* Somehow it's not found. Skip it */
|
||||||
continue;
|
continue;
|
||||||
/* Thing is: all bases are already registered. Thus they have already executed
|
/* Thing is: all bases are already registered. Thus they have already executed
|
||||||
|
@ -2031,15 +1989,13 @@ SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss)
|
||||||
|
|
||||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) /* In elua this is useless */
|
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) /* In elua this is useless */
|
||||||
/* helper add a variable to a registered class */
|
/* helper add a variable to a registered class */
|
||||||
SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFunction getFn,lua_CFunction setFn)
|
SWIGINTERN void SWIG_Lua_add_variable(lua_State *L, const char *name, lua_CFunction getFn, lua_CFunction setFn) {
|
||||||
{
|
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
SWIG_Lua_get_table(L, ".get"); /* find the .get table */
|
SWIG_Lua_get_table(L, ".get"); /* find the .get table */
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
SWIG_Lua_add_function(L, name, getFn);
|
SWIG_Lua_add_function(L, name, getFn);
|
||||||
lua_pop(L, 1); /* tidy stack (remove table) */
|
lua_pop(L, 1); /* tidy stack (remove table) */
|
||||||
if (setFn)
|
if (setFn) {
|
||||||
{
|
|
||||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
SWIG_Lua_add_function(L, name, setFn);
|
SWIG_Lua_add_function(L, name, setFn);
|
||||||
|
@ -2048,14 +2004,12 @@ SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFuncti
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helper to recursively add class static details (static attributes, operations and constants) */
|
/* helper to recursively add class static details (static attributes, operations and constants) */
|
||||||
SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
/* The class namespace table must be on the top of the stack */
|
/* The class namespace table must be on the top of the stack */
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
/* call all the base classes first: we can then override these later: */
|
/* call all the base classes first: we can then override these later: */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
SWIG_Lua_add_class_static_details(L, clss->bases[i]);
|
SWIG_Lua_add_class_static_details(L, clss->bases[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,15 +2019,13 @@ SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *
|
||||||
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss); /* forward declaration */
|
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss); /* forward declaration */
|
||||||
|
|
||||||
/* helper to recursively add class details (attributes & operations) */
|
/* helper to recursively add class details (attributes & operations) */
|
||||||
SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
size_t bases_count = 0;
|
size_t bases_count = 0;
|
||||||
/* Add bases to .bases table */
|
/* Add bases to .bases table */
|
||||||
SWIG_Lua_get_table(L, ".bases");
|
SWIG_Lua_get_table(L, ".bases");
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
||||||
/* Base class must be already registered */
|
/* Base class must be already registered */
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1));
|
||||||
|
@ -2137,8 +2089,7 @@ SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration
|
||||||
* SWIG_Lua_resolve_metamethod
|
* SWIG_Lua_resolve_metamethod
|
||||||
* */
|
* */
|
||||||
SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx,
|
SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx,
|
||||||
int skip_check)
|
int skip_check) {
|
||||||
{
|
|
||||||
/* This function is called recursively */
|
/* This function is called recursively */
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -2159,8 +2110,7 @@ SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forwarding calls to bases */
|
/* Forwarding calls to bases */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
result = SWIG_Lua_do_resolve_metamethod(L, clss->bases[i], metamethod_name_idx, 0);
|
result = SWIG_Lua_do_resolve_metamethod(L, clss->bases[i], metamethod_name_idx, 0);
|
||||||
if (result)
|
if (result)
|
||||||
break;
|
break;
|
||||||
|
@ -2171,8 +2121,7 @@ SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class
|
||||||
|
|
||||||
/* The proxy function for metamethod. All parameters are passed as cclosure. Searches for actual method
|
/* The proxy function for metamethod. All parameters are passed as cclosure. Searches for actual method
|
||||||
* and calls it */
|
* and calls it */
|
||||||
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L)
|
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L) {
|
||||||
{
|
|
||||||
int numargs;
|
int numargs;
|
||||||
int metamethod_name_idx;
|
int metamethod_name_idx;
|
||||||
const swig_lua_class *clss;
|
const swig_lua_class *clss;
|
||||||
|
@ -2208,8 +2157,7 @@ SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L)
|
||||||
* Returns 1 if successfully added, 0 if not added because no base class has it, -1
|
* Returns 1 if successfully added, 0 if not added because no base class has it, -1
|
||||||
* if method is defined in the class metatable itself
|
* if method is defined in the class metatable itself
|
||||||
*/
|
*/
|
||||||
SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index)
|
SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index) {
|
||||||
{
|
|
||||||
int key_index;
|
int key_index;
|
||||||
int success = 0;
|
int success = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -2229,8 +2177,7 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
/* Iterating over immediate bases */
|
/* Iterating over immediate bases */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
const swig_lua_class *base = clss->bases[i];
|
const swig_lua_class *base = clss->bases[i];
|
||||||
SWIG_Lua_get_class_metatable(L, base->fqname);
|
SWIG_Lua_get_class_metatable(L, base->fqname);
|
||||||
lua_pushvalue(L, key_index);
|
lua_pushvalue(L, key_index);
|
||||||
|
@ -2256,8 +2203,7 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int metatable_index;
|
int metatable_index;
|
||||||
int metamethods_info_index;
|
int metamethods_info_index;
|
||||||
int tostring_undefined;
|
int tostring_undefined;
|
||||||
|
@ -2313,8 +2259,7 @@ SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register class static methods,attributes etc as well as constructor proxy */
|
/* Register class static methods,attributes etc as well as constructor proxy */
|
||||||
SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
const int SWIGUNUSED begin = lua_gettop(L);
|
const int SWIGUNUSED begin = lua_gettop(L);
|
||||||
lua_checkstack(L, 5); /* just in case */
|
lua_checkstack(L, 5); /* just in case */
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
|
@ -2328,8 +2273,7 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *cls
|
||||||
so you can do MyClass(...) as well as new_MyClass(...)
|
so you can do MyClass(...) as well as new_MyClass(...)
|
||||||
BUT only if a constructor is defined
|
BUT only if a constructor is defined
|
||||||
(this overcomes the problem of pure virtual classes without constructors)*/
|
(this overcomes the problem of pure virtual classes without constructors)*/
|
||||||
if (clss->constructor)
|
if (clss->constructor) {
|
||||||
{
|
|
||||||
lua_getmetatable(L, -1);
|
lua_getmetatable(L, -1);
|
||||||
assert(lua_istable(L, -1)); /* just in case */
|
assert(lua_istable(L, -1)); /* just in case */
|
||||||
SWIG_Lua_add_function(L, "__call", clss->constructor);
|
SWIG_Lua_add_function(L, "__call", clss->constructor);
|
||||||
|
@ -2347,8 +2291,7 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *cls
|
||||||
/* Performs the instance (non-static) class registration process. Metatable for class is created
|
/* Performs the instance (non-static) class registration process. Metatable for class is created
|
||||||
* and added to the class registry.
|
* and added to the class registry.
|
||||||
*/
|
*/
|
||||||
SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
const int SWIGUNUSED begin = lua_gettop(L);
|
const int SWIGUNUSED begin = lua_gettop(L);
|
||||||
int i;
|
int i;
|
||||||
/* if name already there (class is already registered) then do nothing */
|
/* if name already there (class is already registered) then do nothing */
|
||||||
|
@ -2362,8 +2305,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
||||||
}
|
}
|
||||||
lua_pop(L, 2); /* tidy stack */
|
lua_pop(L, 2); /* tidy stack */
|
||||||
/* Recursively initialize all bases */
|
/* Recursively initialize all bases */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
SWIG_Lua_class_register_instance(L, clss->bases[i]);
|
SWIG_Lua_class_register_instance(L, clss->bases[i]);
|
||||||
}
|
}
|
||||||
/* Again, get registry and push name */
|
/* Again, get registry and push name */
|
||||||
|
@ -2377,8 +2319,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int new_metatable_index = lua_absindex(L, -1);
|
int new_metatable_index = lua_absindex(L, -1);
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
int base_metatable;
|
int base_metatable;
|
||||||
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
||||||
base_metatable = lua_absindex(L, -1);
|
base_metatable = lua_absindex(L, -1);
|
||||||
|
@ -2429,8 +2370,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
||||||
assert(lua_gettop(L) == begin);
|
assert(lua_gettop(L) == begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_class_register(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
int SWIGUNUSED begin;
|
int SWIGUNUSED begin;
|
||||||
assert(lua_istable(L, -1)); /* This is a table (module or namespace) where classes will be added */
|
assert(lua_istable(L, -1)); /* This is a table (module or namespace) where classes will be added */
|
||||||
SWIG_Lua_class_register_instance(L, clss);
|
SWIG_Lua_class_register_instance(L, clss);
|
||||||
|
@ -2467,8 +2407,7 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss)
|
||||||
#endif /* SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA */
|
#endif /* SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA */
|
||||||
|
|
||||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)
|
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)
|
||||||
SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_class *clss)
|
SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_class *clss) {
|
||||||
{
|
|
||||||
const int SWIGUNUSED begin = lua_gettop(L);
|
const int SWIGUNUSED begin = lua_gettop(L);
|
||||||
int i;
|
int i;
|
||||||
/* if name already there (class is already registered) then do nothing */
|
/* if name already there (class is already registered) then do nothing */
|
||||||
|
@ -2482,8 +2421,7 @@ SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_cla
|
||||||
}
|
}
|
||||||
lua_pop(L, 2); /* tidy stack */
|
lua_pop(L, 2); /* tidy stack */
|
||||||
/* Recursively initialize all bases */
|
/* Recursively initialize all bases */
|
||||||
for(i=0;clss->bases[i];i++)
|
for (i = 0; clss->bases[i]; i++) {
|
||||||
{
|
|
||||||
SWIG_Lua_elua_class_register_instance(L, clss->bases[i]);
|
SWIG_Lua_elua_class_register_instance(L, clss->bases[i]);
|
||||||
}
|
}
|
||||||
/* Again, get registry and push name */
|
/* Again, get registry and push name */
|
||||||
|
@ -2502,25 +2440,19 @@ SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_cla
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* helper to add metatable to new lua object */
|
/* helper to add metatable to new lua object */
|
||||||
SWIGINTERN void SWIG_Lua_AddMetatable(lua_State *L,swig_type_info *type)
|
SWIGINTERN void SWIG_Lua_AddMetatable(lua_State *L, swig_type_info *type) {
|
||||||
{
|
if (type->clientdata) { /* there is clientdata: so add the metatable */
|
||||||
if (type->clientdata) /* there is clientdata: so add the metatable */
|
|
||||||
{
|
|
||||||
SWIG_Lua_get_class_metatable(L, ((swig_lua_class *)(type->clientdata))->fqname);
|
SWIG_Lua_get_class_metatable(L, ((swig_lua_class *)(type->clientdata))->fqname);
|
||||||
if (lua_istable(L,-1))
|
if (lua_istable(L, -1)) {
|
||||||
{
|
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pushes a new object into the lua stack */
|
/* pushes a new object into the lua stack */
|
||||||
SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *type, int own)
|
SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L, void *ptr, swig_type_info *type, int own) {
|
||||||
{
|
|
||||||
swig_lua_userdata *usr;
|
swig_lua_userdata *usr;
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
@ -2537,51 +2469,40 @@ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *t
|
||||||
|
|
||||||
/* takes a object from the lua stack & converts it into an object of the correct type
|
/* takes a object from the lua stack & converts it into an object of the correct type
|
||||||
(if possible) */
|
(if possible) */
|
||||||
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags)
|
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L, int index, void **ptr, swig_type_info *type, int flags) {
|
||||||
{
|
|
||||||
int ret = SWIG_ERROR;
|
int ret = SWIG_ERROR;
|
||||||
swig_lua_userdata *usr;
|
swig_lua_userdata *usr;
|
||||||
swig_cast_info *cast;
|
swig_cast_info *cast;
|
||||||
/* special case: lua nil => NULL pointer */
|
/* special case: lua nil => NULL pointer */
|
||||||
if (lua_isnil(L,index))
|
if (lua_isnil(L, index)) {
|
||||||
{
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
|
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
|
||||||
}
|
}
|
||||||
if (lua_islightuserdata(L,index))
|
if (lua_islightuserdata(L, index)) {
|
||||||
{
|
|
||||||
*ptr = lua_touserdata(L, index);
|
*ptr = lua_touserdata(L, index);
|
||||||
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
|
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
|
||||||
}
|
}
|
||||||
usr = (swig_lua_userdata *)lua_touserdata(L, index); /* get data */
|
usr = (swig_lua_userdata *)lua_touserdata(L, index); /* get data */
|
||||||
if (usr)
|
if (usr) {
|
||||||
{
|
if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !usr->own) {
|
||||||
if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !usr->own)
|
|
||||||
{
|
|
||||||
return SWIG_ERROR_RELEASE_NOT_OWNED;
|
return SWIG_ERROR_RELEASE_NOT_OWNED;
|
||||||
}
|
}
|
||||||
if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
|
if (flags & SWIG_POINTER_DISOWN) { /* must disown the object */
|
||||||
{
|
|
||||||
usr->own = 0;
|
usr->own = 0;
|
||||||
}
|
}
|
||||||
if (!type) /* special cast void*, no casting fn */
|
if (!type) { /* special cast void*, no casting fn */
|
||||||
{
|
|
||||||
*ptr = usr->ptr;
|
*ptr = usr->ptr;
|
||||||
ret = SWIG_OK;
|
ret = SWIG_OK;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cast = SWIG_TypeCheck(usr->type->name, type); /* performs normal type checking */
|
cast = SWIG_TypeCheck(usr->type->name, type); /* performs normal type checking */
|
||||||
if (cast)
|
if (cast) {
|
||||||
{
|
|
||||||
int newmemory = 0;
|
int newmemory = 0;
|
||||||
*ptr = SWIG_TypeCast(cast, usr->ptr, &newmemory);
|
*ptr = SWIG_TypeCast(cast, usr->ptr, &newmemory);
|
||||||
assert(!newmemory); /* newmemory handling not yet implemented */
|
assert(!newmemory); /* newmemory handling not yet implemented */
|
||||||
ret = SWIG_OK;
|
ret = SWIG_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ret == SWIG_OK) && (flags & SWIG_POINTER_CLEAR))
|
if ((ret == SWIG_OK) && (flags & SWIG_POINTER_CLEAR)) {
|
||||||
{
|
|
||||||
usr->ptr = 0;
|
usr->ptr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2599,8 +2520,7 @@ SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *typ
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pushes a packed userdata. user for member fn pointers only */
|
/* pushes a packed userdata. user for member fn pointers only */
|
||||||
SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_type_info *type)
|
SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L, void *ptr, size_t size, swig_type_info *type) {
|
||||||
{
|
|
||||||
swig_lua_rawdata *raw;
|
swig_lua_rawdata *raw;
|
||||||
assert(ptr); /* not acceptable to pass in a NULL value */
|
assert(ptr); /* not acceptable to pass in a NULL value */
|
||||||
raw = (swig_lua_rawdata *)lua_newuserdata(L, sizeof(swig_lua_rawdata) - 1 + size); /* alloc data */
|
raw = (swig_lua_rawdata *)lua_newuserdata(L, sizeof(swig_lua_rawdata) - 1 + size); /* alloc data */
|
||||||
|
@ -2611,13 +2531,11 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* converts a packed userdata. user for member fn pointers only */
|
/* converts a packed userdata. user for member fn pointers only */
|
||||||
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L,int index,void *ptr,size_t size,swig_type_info *type)
|
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L, int index, void *ptr, size_t size, swig_type_info *type) {
|
||||||
{
|
|
||||||
swig_lua_rawdata *raw;
|
swig_lua_rawdata *raw;
|
||||||
raw = (swig_lua_rawdata *)lua_touserdata(L, index); /* get data */
|
raw = (swig_lua_rawdata *)lua_touserdata(L, index); /* get data */
|
||||||
if (!raw) return SWIG_ERROR; /* error */
|
if (!raw) return SWIG_ERROR; /* error */
|
||||||
if (type==0 || type==raw->type) /* void* or identical type */
|
if (type == 0 || type == raw->type) { /* void* or identical type */
|
||||||
{
|
|
||||||
memcpy(ptr, raw->data, size); /* copy it */
|
memcpy(ptr, raw->data, size); /* copy it */
|
||||||
return SWIG_OK; /* ok */
|
return SWIG_OK; /* ok */
|
||||||
}
|
}
|
||||||
|
@ -2625,11 +2543,9 @@ SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L,int index,void *ptr,size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a function to get the typestring of a piece of data */
|
/* a function to get the typestring of a piece of data */
|
||||||
SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp)
|
SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp) {
|
||||||
{
|
|
||||||
swig_lua_userdata *usr;
|
swig_lua_userdata *usr;
|
||||||
if (lua_isuserdata(L,tp))
|
if (lua_isuserdata(L, tp)) {
|
||||||
{
|
|
||||||
usr = (swig_lua_userdata *)lua_touserdata(L, tp); /* get data */
|
usr = (swig_lua_userdata *)lua_touserdata(L, tp); /* get data */
|
||||||
if (usr && usr->type && usr->type->str)
|
if (usr && usr->type && usr->type->str)
|
||||||
return usr->type->str;
|
return usr->type->str;
|
||||||
|
@ -2639,8 +2555,7 @@ SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lua callable function to get the userdata's type */
|
/* lua callable function to get the userdata's type */
|
||||||
SWIGRUNTIME int SWIG_Lua_type(lua_State *L)
|
SWIGRUNTIME int SWIG_Lua_type(lua_State *L) {
|
||||||
{
|
|
||||||
lua_pushstring(L, SWIG_Lua_typename(L, 1));
|
lua_pushstring(L, SWIG_Lua_typename(L, 1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2789,10 +2704,12 @@ static int _wrap_new_pm3__SWIG_0(lua_State* L) {
|
||||||
|
|
||||||
SWIG_check_num_args("pm3::pm3", 0, 0)
|
SWIG_check_num_args("pm3::pm3", 0, 0)
|
||||||
result = (pm3 *)new_pm3__SWIG_0();
|
result = (pm3 *)new_pm3__SWIG_0();
|
||||||
SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++;
|
SWIG_NewPointerObj(L, result, SWIGTYPE_p_pm3, 1);
|
||||||
|
SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
|
||||||
fail: SWIGUNUSED;
|
fail:
|
||||||
|
SWIGUNUSED;
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2807,10 +2724,12 @@ static int _wrap_new_pm3__SWIG_1(lua_State* L) {
|
||||||
if (!SWIG_lua_isnilstring(L, 1)) SWIG_fail_arg("pm3::pm3", 1, "char *");
|
if (!SWIG_lua_isnilstring(L, 1)) SWIG_fail_arg("pm3::pm3", 1, "char *");
|
||||||
arg1 = (char *)lua_tostring(L, 1);
|
arg1 = (char *)lua_tostring(L, 1);
|
||||||
result = (pm3 *)new_pm3__SWIG_1(arg1);
|
result = (pm3 *)new_pm3__SWIG_1(arg1);
|
||||||
SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++;
|
SWIG_NewPointerObj(L, result, SWIGTYPE_p_pm3, 1);
|
||||||
|
SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
|
||||||
fail: SWIGUNUSED;
|
fail:
|
||||||
|
SWIGUNUSED;
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2840,7 +2759,8 @@ static int _wrap_new_pm3(lua_State* L) {
|
||||||
" Possible C/C++ prototypes are:\n"
|
" Possible C/C++ prototypes are:\n"
|
||||||
" pm3::pm3()\n"
|
" pm3::pm3()\n"
|
||||||
" pm3::pm3(char *)\n");
|
" pm3::pm3(char *)\n");
|
||||||
lua_error(L);return 0;
|
lua_error(L);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2860,10 +2780,12 @@ static int _wrap_pm3_console(lua_State* L) {
|
||||||
|
|
||||||
arg2 = (char *)lua_tostring(L, 2);
|
arg2 = (char *)lua_tostring(L, 2);
|
||||||
result = (int)pm3_console(arg1, arg2);
|
result = (int)pm3_console(arg1, arg2);
|
||||||
lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
|
lua_pushnumber(L, (lua_Number) result);
|
||||||
|
SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
|
||||||
fail: SWIGUNUSED;
|
fail:
|
||||||
|
SWIGUNUSED;
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2882,10 +2804,12 @@ static int _wrap_pm3_name_get(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (char *)pm3_name_get(arg1);
|
result = (char *)pm3_name_get(arg1);
|
||||||
lua_pushstring(L,(const char *)result); SWIG_arg++;
|
lua_pushstring(L, (const char *)result);
|
||||||
|
SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
|
||||||
fail: SWIGUNUSED;
|
fail:
|
||||||
|
SWIGUNUSED;
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3215,7 +3139,8 @@ SWIG_PropagateClientData(void) {
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#if 0
|
#if 0
|
||||||
{ /* c-mode */
|
{
|
||||||
|
/* c-mode */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3312,8 +3237,7 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
|
||||||
const char *SWIG_LUACODE =
|
const char *SWIG_LUACODE =
|
||||||
"";
|
"";
|
||||||
|
|
||||||
void SWIG_init_user(lua_State* L)
|
void SWIG_init_user(lua_State *L) {
|
||||||
{
|
|
||||||
/* exec Lua code if applicable */
|
/* exec Lua code if applicable */
|
||||||
SWIG_Lua_dostring(L, SWIG_LUACODE);
|
SWIG_Lua_dostring(L, SWIG_LUACODE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,8 +574,7 @@ SWIG_TypePrettyName(const swig_type_info *type) {
|
||||||
for (s = type->str; *s; s++)
|
for (s = type->str; *s; s++)
|
||||||
if (*s == '|') last_name = s + 1;
|
if (*s == '|') last_name = s + 1;
|
||||||
return last_name;
|
return last_name;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return type->name;
|
return type->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,8 +835,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
|
||||||
|
|
||||||
/* Wrapper around PyUnicode_AsUTF8AndSize - call Py_XDECREF on the returned pbytes when finished with the returned string */
|
/* Wrapper around PyUnicode_AsUTF8AndSize - call Py_XDECREF on the returned pbytes when finished with the returned string */
|
||||||
SWIGINTERN const char *
|
SWIGINTERN const char *
|
||||||
SWIG_PyUnicode_AsUTF8AndSize(PyObject *str, Py_ssize_t *psize, PyObject **pbytes)
|
SWIG_PyUnicode_AsUTF8AndSize(PyObject *str, Py_ssize_t *psize, PyObject **pbytes) {
|
||||||
{
|
|
||||||
#if PY_VERSION_HEX >= 0x03030000
|
#if PY_VERSION_HEX >= 0x03030000
|
||||||
# if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
# if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
||||||
*pbytes = NULL;
|
*pbytes = NULL;
|
||||||
|
@ -858,8 +856,7 @@ SWIG_PyUnicode_AsUTF8AndSize(PyObject *str, Py_ssize_t *psize, PyObject **pbytes
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN PyObject *
|
SWIGINTERN PyObject *
|
||||||
SWIG_Python_str_FromChar(const char *c)
|
SWIG_Python_str_FromChar(const char *c) {
|
||||||
{
|
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
return PyUnicode_FromString(c);
|
return PyUnicode_FromString(c);
|
||||||
#else
|
#else
|
||||||
|
@ -949,8 +946,7 @@ SWIG_Python_ErrorType(int code) {
|
||||||
|
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Python_AddErrorMsg(const char* mesg)
|
SWIG_Python_AddErrorMsg(const char *mesg) {
|
||||||
{
|
|
||||||
PyObject *type = 0;
|
PyObject *type = 0;
|
||||||
PyObject *value = 0;
|
PyObject *value = 0;
|
||||||
PyObject *traceback = 0;
|
PyObject *traceback = 0;
|
||||||
|
@ -976,8 +972,7 @@ SWIG_Python_AddErrorMsg(const char* mesg)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SWIG_Python_TypeErrorOccurred(PyObject *obj)
|
SWIG_Python_TypeErrorOccurred(PyObject *obj) {
|
||||||
{
|
|
||||||
PyObject *error;
|
PyObject *error;
|
||||||
if (obj)
|
if (obj)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -986,8 +981,7 @@ SWIG_Python_TypeErrorOccurred(PyObject *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Python_RaiseOrModifyTypeError(const char *message)
|
SWIG_Python_RaiseOrModifyTypeError(const char *message) {
|
||||||
{
|
|
||||||
if (SWIG_Python_TypeErrorOccurred(NULL)) {
|
if (SWIG_Python_TypeErrorOccurred(NULL)) {
|
||||||
/* Use existing TypeError to preserve stacktrace and enhance with given message */
|
/* Use existing TypeError to preserve stacktrace and enhance with given message */
|
||||||
PyObject *newvalue;
|
PyObject *newvalue;
|
||||||
|
@ -1255,8 +1249,7 @@ SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
|
||||||
/* Unpack the argument tuple */
|
/* Unpack the argument tuple */
|
||||||
|
|
||||||
SWIGINTERN Py_ssize_t
|
SWIGINTERN Py_ssize_t
|
||||||
SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
|
SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) {
|
||||||
{
|
|
||||||
if (!args) {
|
if (!args) {
|
||||||
if (!min && !max) {
|
if (!min && !max) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1601,8 +1594,7 @@ extern "C" {
|
||||||
/* The python void return value */
|
/* The python void return value */
|
||||||
|
|
||||||
SWIGRUNTIMEINLINE PyObject *
|
SWIGRUNTIMEINLINE PyObject *
|
||||||
SWIG_Py_Void(void)
|
SWIG_Py_Void(void) {
|
||||||
{
|
|
||||||
PyObject *none = Py_None;
|
PyObject *none = Py_None;
|
||||||
Py_INCREF(none);
|
Py_INCREF(none);
|
||||||
return none;
|
return none;
|
||||||
|
@ -1621,8 +1613,7 @@ typedef struct {
|
||||||
} SwigPyClientData;
|
} SwigPyClientData;
|
||||||
|
|
||||||
SWIGRUNTIMEINLINE int
|
SWIGRUNTIMEINLINE int
|
||||||
SWIG_Python_CheckImplicit(swig_type_info *ty)
|
SWIG_Python_CheckImplicit(swig_type_info *ty) {
|
||||||
{
|
|
||||||
SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
|
SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
|
||||||
int fail = data ? data->implicitconv : 0;
|
int fail = data ? data->implicitconv : 0;
|
||||||
if (fail)
|
if (fail)
|
||||||
|
@ -1639,8 +1630,7 @@ SWIG_Python_ExceptionType(swig_type_info *desc) {
|
||||||
|
|
||||||
|
|
||||||
SWIGRUNTIME SwigPyClientData *
|
SWIGRUNTIME SwigPyClientData *
|
||||||
SwigPyClientData_New(PyObject* obj)
|
SwigPyClientData_New(PyObject *obj) {
|
||||||
{
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1689,8 +1679,7 @@ SwigPyClientData_New(PyObject* obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SwigPyClientData_Del(SwigPyClientData *data)
|
SwigPyClientData_Del(SwigPyClientData *data) {
|
||||||
{
|
|
||||||
Py_XDECREF(data->klass);
|
Py_XDECREF(data->klass);
|
||||||
Py_XDECREF(data->newraw);
|
Py_XDECREF(data->newraw);
|
||||||
Py_XDECREF(data->newargs);
|
Py_XDECREF(data->newargs);
|
||||||
|
@ -1715,8 +1704,7 @@ typedef struct {
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||||
|
|
||||||
if (!sobj->dict)
|
if (!sobj->dict)
|
||||||
|
@ -1729,14 +1717,12 @@ SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_long(SwigPyObject *v)
|
SwigPyObject_long(SwigPyObject *v) {
|
||||||
{
|
|
||||||
return PyLong_FromVoidPtr(v->ptr);
|
return PyLong_FromVoidPtr(v->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_format(const char* fmt, SwigPyObject *v)
|
SwigPyObject_format(const char *fmt, SwigPyObject *v) {
|
||||||
{
|
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
PyObject *args = PyTuple_New(1);
|
PyObject *args = PyTuple_New(1);
|
||||||
if (args) {
|
if (args) {
|
||||||
|
@ -1760,20 +1746,17 @@ SwigPyObject_format(const char* fmt, SwigPyObject *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_oct(SwigPyObject *v)
|
SwigPyObject_oct(SwigPyObject *v) {
|
||||||
{
|
|
||||||
return SwigPyObject_format("%o", v);
|
return SwigPyObject_format("%o", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_hex(SwigPyObject *v)
|
SwigPyObject_hex(SwigPyObject *v) {
|
||||||
{
|
|
||||||
return SwigPyObject_format("%x", v);
|
return SwigPyObject_format("%x", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_repr(SwigPyObject *v)
|
SwigPyObject_repr(SwigPyObject *v) {
|
||||||
{
|
|
||||||
const char *name = SWIG_TypePrettyName(v->ty);
|
const char *name = SWIG_TypePrettyName(v->ty);
|
||||||
PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
|
PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
|
||||||
if (repr && v->next) {
|
if (repr && v->next) {
|
||||||
|
@ -1798,14 +1781,12 @@ SwigPyObject_repr(SwigPyObject *v)
|
||||||
/* We need a version taking two PyObject* parameters so it's a valid
|
/* We need a version taking two PyObject* parameters so it's a valid
|
||||||
* PyCFunction to use in swigobject_methods[]. */
|
* PyCFunction to use in swigobject_methods[]. */
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||||
{
|
|
||||||
return SwigPyObject_repr((SwigPyObject *)v);
|
return SwigPyObject_repr((SwigPyObject *)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
|
SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) {
|
||||||
{
|
|
||||||
void *i = v->ptr;
|
void *i = v->ptr;
|
||||||
void *j = w->ptr;
|
void *j = w->ptr;
|
||||||
return (i < j) ? -1 : ((i > j) ? 1 : 0);
|
return (i < j) ? -1 : ((i > j) ? 1 : 0);
|
||||||
|
@ -1813,8 +1794,7 @@ SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
|
||||||
|
|
||||||
/* Added for Python 3.x, would it also be useful for Python 2.x? */
|
/* Added for Python 3.x, would it also be useful for Python 2.x? */
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
|
SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) {
|
||||||
{
|
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
if (!PyErr_Occurred()) {
|
if (!PyErr_Occurred()) {
|
||||||
if (op != Py_EQ && op != Py_NE) {
|
if (op != Py_EQ && op != Py_NE) {
|
||||||
|
@ -1879,8 +1859,7 @@ SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
|
||||||
static PyObject *Swig_Capsule_global = NULL;
|
static PyObject *Swig_Capsule_global = NULL;
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SwigPyObject_dealloc(PyObject *v)
|
SwigPyObject_dealloc(PyObject *v) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||||
PyObject *next = sobj->next;
|
PyObject *next = sobj->next;
|
||||||
if (sobj->own == SWIG_POINTER_OWN) {
|
if (sobj->own == SWIG_POINTER_OWN) {
|
||||||
|
@ -1938,8 +1917,7 @@ SwigPyObject_dealloc(PyObject *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_append(PyObject* v, PyObject* next)
|
SwigPyObject_append(PyObject *v, PyObject *next) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||||
if (!SwigPyObject_Check(next)) {
|
if (!SwigPyObject_Check(next)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
|
PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
|
||||||
|
@ -1952,8 +1930,7 @@ SwigPyObject_append(PyObject* v, PyObject* next)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
SwigPyObject_next(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||||
if (sobj->next) {
|
if (sobj->next) {
|
||||||
Py_INCREF(sobj->next);
|
Py_INCREF(sobj->next);
|
||||||
|
@ -1964,24 +1941,21 @@ SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN PyObject *
|
SWIGINTERN PyObject *
|
||||||
SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
SwigPyObject_disown(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||||
sobj->own = 0;
|
sobj->own = 0;
|
||||||
return SWIG_Py_Void();
|
return SWIG_Py_Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN PyObject *
|
SWIGINTERN PyObject *
|
||||||
SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
SwigPyObject_acquire(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||||
sobj->own = SWIG_POINTER_OWN;
|
sobj->own = SWIG_POINTER_OWN;
|
||||||
return SWIG_Py_Void();
|
return SWIG_Py_Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN PyObject *
|
SWIGINTERN PyObject *
|
||||||
SwigPyObject_own(PyObject *v, PyObject *args)
|
SwigPyObject_own(PyObject *v, PyObject *args) {
|
||||||
{
|
|
||||||
PyObject *val = 0;
|
PyObject *val = 0;
|
||||||
if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) {
|
if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2171,8 +2145,7 @@ SwigPyObject_TypeOnce(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
|
SwigPyObject_New(void *ptr, swig_type_info *ty, int own) {
|
||||||
{
|
|
||||||
SwigPyObject *sobj = PyObject_New(SwigPyObject, SwigPyObject_type());
|
SwigPyObject *sobj = PyObject_New(SwigPyObject, SwigPyObject_type());
|
||||||
if (sobj) {
|
if (sobj) {
|
||||||
sobj->ptr = ptr;
|
sobj->ptr = ptr;
|
||||||
|
@ -2204,8 +2177,7 @@ typedef struct {
|
||||||
} SwigPyPacked;
|
} SwigPyPacked;
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyPacked_repr(SwigPyPacked *v)
|
SwigPyPacked_repr(SwigPyPacked *v) {
|
||||||
{
|
|
||||||
char result[SWIG_BUFFER_SIZE];
|
char result[SWIG_BUFFER_SIZE];
|
||||||
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
||||||
return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
|
return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
|
||||||
|
@ -2215,8 +2187,7 @@ SwigPyPacked_repr(SwigPyPacked *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyPacked_str(SwigPyPacked *v)
|
SwigPyPacked_str(SwigPyPacked *v) {
|
||||||
{
|
|
||||||
char result[SWIG_BUFFER_SIZE];
|
char result[SWIG_BUFFER_SIZE];
|
||||||
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
||||||
return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
|
return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
|
||||||
|
@ -2226,8 +2197,7 @@ SwigPyPacked_str(SwigPyPacked *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
|
SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) {
|
||||||
{
|
|
||||||
size_t i = v->size;
|
size_t i = v->size;
|
||||||
size_t j = w->size;
|
size_t j = w->size;
|
||||||
int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
|
int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
|
||||||
|
@ -2261,8 +2231,7 @@ SwigPyPacked_Check(PyObject *op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SwigPyPacked_dealloc(PyObject *v)
|
SwigPyPacked_dealloc(PyObject *v) {
|
||||||
{
|
|
||||||
if (SwigPyPacked_Check(v)) {
|
if (SwigPyPacked_Check(v)) {
|
||||||
SwigPyPacked *sobj = (SwigPyPacked *) v;
|
SwigPyPacked *sobj = (SwigPyPacked *) v;
|
||||||
free(sobj->pack);
|
free(sobj->pack);
|
||||||
|
@ -2385,8 +2354,7 @@ SwigPyPacked_TypeOnce(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
|
SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) {
|
||||||
{
|
|
||||||
SwigPyPacked *sobj = PyObject_New(SwigPyPacked, SwigPyPacked_type());
|
SwigPyPacked *sobj = PyObject_New(SwigPyPacked, SwigPyPacked_type());
|
||||||
if (sobj) {
|
if (sobj) {
|
||||||
void *pack = malloc(size);
|
void *pack = malloc(size);
|
||||||
|
@ -2404,8 +2372,7 @@ SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME swig_type_info *
|
SWIGRUNTIME swig_type_info *
|
||||||
SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
|
SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) {
|
||||||
{
|
|
||||||
if (SwigPyPacked_Check(obj)) {
|
if (SwigPyPacked_Check(obj)) {
|
||||||
SwigPyPacked *sobj = (SwigPyPacked *)obj;
|
SwigPyPacked *sobj = (SwigPyPacked *)obj;
|
||||||
if (sobj->size != size) return 0;
|
if (sobj->size != size) return 0;
|
||||||
|
@ -2423,8 +2390,7 @@ SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
|
||||||
static PyObject *Swig_This_global = NULL;
|
static PyObject *Swig_This_global = NULL;
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SWIG_This(void)
|
SWIG_This(void) {
|
||||||
{
|
|
||||||
if (Swig_This_global == NULL)
|
if (Swig_This_global == NULL)
|
||||||
Swig_This_global = SWIG_Python_str_FromChar("this");
|
Swig_This_global = SWIG_Python_str_FromChar("this");
|
||||||
return Swig_This_global;
|
return Swig_This_global;
|
||||||
|
@ -2438,8 +2404,7 @@ SWIG_This(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SWIGRUNTIME SwigPyObject *
|
SWIGRUNTIME SwigPyObject *
|
||||||
SWIG_Python_GetSwigThis(PyObject *pyobj)
|
SWIG_Python_GetSwigThis(PyObject *pyobj) {
|
||||||
{
|
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
|
|
||||||
if (SwigPyObject_Check(pyobj))
|
if (SwigPyObject_Check(pyobj))
|
||||||
|
@ -2693,8 +2658,7 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
|
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) {
|
||||||
{
|
|
||||||
PyObject *inst = 0;
|
PyObject *inst = 0;
|
||||||
PyObject *newraw = data->newraw;
|
PyObject *newraw = data->newraw;
|
||||||
if (newraw) {
|
if (newraw) {
|
||||||
|
@ -2759,8 +2723,7 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
|
SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) {
|
||||||
{
|
|
||||||
#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
|
#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
|
||||||
PyObject **dictptr = _PyObject_GetDictPtr(inst);
|
PyObject **dictptr = _PyObject_GetDictPtr(inst);
|
||||||
if (dictptr != NULL) {
|
if (dictptr != NULL) {
|
||||||
|
@ -2906,8 +2869,7 @@ SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
|
||||||
static int interpreter_counter = 0; /* how many (sub-)interpreters are using swig_module's types */
|
static int interpreter_counter = 0; /* how many (sub-)interpreters are using swig_module's types */
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Python_DestroyModule(PyObject *obj)
|
SWIG_Python_DestroyModule(PyObject *obj) {
|
||||||
{
|
|
||||||
swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
|
swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
|
||||||
swig_type_info **types = swig_module->types;
|
swig_type_info **types = swig_module->types;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -2953,8 +2915,7 @@ SWIG_Python_SetModule(swig_module_info *swig_module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME swig_type_info *
|
SWIGRUNTIME swig_type_info *
|
||||||
SWIG_Python_TypeQuery(const char *type)
|
SWIG_Python_TypeQuery(const char *type) {
|
||||||
{
|
|
||||||
PyObject *cache = SWIG_Python_TypeCache();
|
PyObject *cache = SWIG_Python_TypeCache();
|
||||||
PyObject *key = SWIG_Python_str_FromChar(type);
|
PyObject *key = SWIG_Python_str_FromChar(type);
|
||||||
PyObject *obj = PyDict_GetItem(cache, key);
|
PyObject *obj = PyDict_GetItem(cache, key);
|
||||||
|
@ -2984,8 +2945,7 @@ SWIG_Python_TypeQuery(const char *type)
|
||||||
#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
|
#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SWIG_Python_AddErrMesg(const char* mesg, int infront)
|
SWIG_Python_AddErrMesg(const char *mesg, int infront) {
|
||||||
{
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
PyObject *type = 0;
|
PyObject *type = 0;
|
||||||
PyObject *value = 0;
|
PyObject *value = 0;
|
||||||
|
@ -3013,8 +2973,7 @@ SWIG_Python_AddErrMesg(const char* mesg, int infront)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME int
|
SWIGRUNTIME int
|
||||||
SWIG_Python_ArgFail(int argnum)
|
SWIG_Python_ArgFail(int argnum) {
|
||||||
{
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
/* add information about failing argument */
|
/* add information about failing argument */
|
||||||
char mesg[256];
|
char mesg[256];
|
||||||
|
@ -3026,16 +2985,14 @@ SWIG_Python_ArgFail(int argnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIMEINLINE const char *
|
SWIGRUNTIMEINLINE const char *
|
||||||
SwigPyObject_GetDesc(PyObject *self)
|
SwigPyObject_GetDesc(PyObject *self) {
|
||||||
{
|
|
||||||
SwigPyObject *v = (SwigPyObject *)self;
|
SwigPyObject *v = (SwigPyObject *)self;
|
||||||
swig_type_info *ty = v ? v->ty : 0;
|
swig_type_info *ty = v ? v->ty : 0;
|
||||||
return ty ? ty->str : "";
|
return ty ? ty->str : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SWIG_Python_TypeError(const char *type, PyObject *obj)
|
SWIG_Python_TypeError(const char *type, PyObject *obj) {
|
||||||
{
|
|
||||||
if (type) {
|
if (type) {
|
||||||
#if defined(SWIG_COBJECT_TYPES)
|
#if defined(SWIG_COBJECT_TYPES)
|
||||||
if (obj && SwigPyObject_Check(obj)) {
|
if (obj && SwigPyObject_Check(obj)) {
|
||||||
|
@ -3197,8 +3154,7 @@ SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN swig_type_info *
|
SWIGINTERN swig_type_info *
|
||||||
SWIG_pchar_descriptor(void)
|
SWIG_pchar_descriptor(void) {
|
||||||
{
|
|
||||||
static int init = 0;
|
static int init = 0;
|
||||||
static swig_type_info *info = 0;
|
static swig_type_info *info = 0;
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
@ -3212,8 +3168,7 @@ SWIG_pchar_descriptor(void)
|
||||||
/* Return string from Python obj. NOTE: obj must remain in scope in order
|
/* Return string from Python obj. NOTE: obj must remain in scope in order
|
||||||
to use the returned cptr (but only when alloc is set to SWIG_OLDOBJ) */
|
to use the returned cptr (but only when alloc is set to SWIG_OLDOBJ) */
|
||||||
SWIGINTERN int
|
SWIGINTERN int
|
||||||
SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc)
|
SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc) {
|
||||||
{
|
|
||||||
#if PY_VERSION_HEX>=0x03000000
|
#if PY_VERSION_HEX>=0x03000000
|
||||||
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
|
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
|
||||||
if (PyBytes_Check(obj))
|
if (PyBytes_Check(obj))
|
||||||
|
@ -3224,7 +3179,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc)
|
||||||
if (PyString_Check(obj))
|
if (PyString_Check(obj))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
char *cstr; Py_ssize_t len;
|
char *cstr;
|
||||||
|
Py_ssize_t len;
|
||||||
PyObject *bytes = NULL;
|
PyObject *bytes = NULL;
|
||||||
int ret = SWIG_OK;
|
int ret = SWIG_OK;
|
||||||
if (alloc)
|
if (alloc)
|
||||||
|
@ -3258,7 +3214,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc)
|
||||||
#endif
|
#endif
|
||||||
#if PY_VERSION_HEX<0x03000000
|
#if PY_VERSION_HEX<0x03000000
|
||||||
if (PyUnicode_Check(obj)) {
|
if (PyUnicode_Check(obj)) {
|
||||||
char *cstr; Py_ssize_t len;
|
char *cstr;
|
||||||
|
Py_ssize_t len;
|
||||||
if (!alloc && cptr) {
|
if (!alloc && cptr) {
|
||||||
return SWIG_RuntimeError;
|
return SWIG_RuntimeError;
|
||||||
}
|
}
|
||||||
|
@ -3314,15 +3271,13 @@ SWIGINTERN void delete_pm3(pm3 *self){
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERNINLINE PyObject *
|
SWIGINTERNINLINE PyObject *
|
||||||
SWIG_From_int (int value)
|
SWIG_From_int(int value) {
|
||||||
{
|
|
||||||
return PyInt_FromLong((long) value);
|
return PyInt_FromLong((long) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERNINLINE PyObject *
|
SWIGINTERNINLINE PyObject *
|
||||||
SWIG_FromCharPtrAndSize(const char* carray, size_t size)
|
SWIG_FromCharPtrAndSize(const char *carray, size_t size) {
|
||||||
{
|
|
||||||
if (carray) {
|
if (carray) {
|
||||||
if (size > INT_MAX) {
|
if (size > INT_MAX) {
|
||||||
swig_type_info *pchar_descriptor = SWIG_pchar_descriptor();
|
swig_type_info *pchar_descriptor = SWIG_pchar_descriptor();
|
||||||
|
@ -3346,8 +3301,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size)
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERNINLINE PyObject *
|
SWIGINTERNINLINE PyObject *
|
||||||
SWIG_FromCharPtr(const char *cptr)
|
SWIG_FromCharPtr(const char *cptr) {
|
||||||
{
|
|
||||||
return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
|
return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3547,7 +3501,8 @@ static swig_cast_info *swig_cast_initial[] = {
|
||||||
/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
|
/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
|
||||||
|
|
||||||
static swig_const_info swig_const_table[] = {
|
static swig_const_info swig_const_table[] = {
|
||||||
{0, 0, 0, 0.0, 0, 0}};
|
{0, 0, 0, 0.0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,15 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 1, "analyse foo" },
|
{ 1, "analyse foo" },
|
||||||
{ 1, "analyse units" },
|
{ 1, "analyse units" },
|
||||||
{ 1, "data help" },
|
{ 1, "data help" },
|
||||||
|
{ 1, "data clear" },
|
||||||
|
{ 1, "data hide" },
|
||||||
|
{ 1, "data load" },
|
||||||
|
{ 1, "data num" },
|
||||||
|
{ 1, "data plot" },
|
||||||
|
{ 1, "data print" },
|
||||||
|
{ 1, "data save" },
|
||||||
|
{ 1, "data setdebugmode" },
|
||||||
|
{ 1, "data xor" },
|
||||||
{ 1, "data biphaserawdecode" },
|
{ 1, "data biphaserawdecode" },
|
||||||
{ 1, "data detectclock" },
|
{ 1, "data detectclock" },
|
||||||
{ 1, "data fsktonrz" },
|
{ 1, "data fsktonrz" },
|
||||||
|
@ -83,43 +92,32 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 1, "data rawdemod" },
|
{ 1, "data rawdemod" },
|
||||||
{ 1, "data askedgedetect" },
|
{ 1, "data askedgedetect" },
|
||||||
{ 1, "data autocorr" },
|
{ 1, "data autocorr" },
|
||||||
|
{ 1, "data convertbitstream" },
|
||||||
|
{ 1, "data cthreshold" },
|
||||||
{ 1, "data dirthreshold" },
|
{ 1, "data dirthreshold" },
|
||||||
{ 1, "data decimate" },
|
{ 1, "data decimate" },
|
||||||
{ 1, "data envelope" },
|
{ 1, "data envelope" },
|
||||||
{ 1, "data undecimate" },
|
{ 1, "data grid" },
|
||||||
{ 1, "data hide" },
|
{ 1, "data getbitstream" },
|
||||||
{ 1, "data hpf" },
|
{ 1, "data hpf" },
|
||||||
{ 1, "data iir" },
|
{ 1, "data iir" },
|
||||||
{ 1, "data grid" },
|
|
||||||
{ 1, "data ltrim" },
|
{ 1, "data ltrim" },
|
||||||
{ 1, "data mtrim" },
|
{ 1, "data mtrim" },
|
||||||
{ 1, "data norm" },
|
{ 1, "data norm" },
|
||||||
{ 1, "data plot" },
|
|
||||||
{ 1, "data cthreshold" },
|
|
||||||
{ 1, "data rtrim" },
|
{ 1, "data rtrim" },
|
||||||
{ 1, "data setgraphmarkers" },
|
{ 1, "data setgraphmarkers" },
|
||||||
{ 1, "data shiftgraphzero" },
|
{ 1, "data shiftgraphzero" },
|
||||||
{ 1, "data timescale" },
|
{ 1, "data timescale" },
|
||||||
|
{ 1, "data undecimate" },
|
||||||
{ 1, "data zerocrossings" },
|
{ 1, "data zerocrossings" },
|
||||||
{ 1, "data convertbitstream" },
|
|
||||||
{ 1, "data getbitstream" },
|
|
||||||
{ 1, "data asn1" },
|
{ 1, "data asn1" },
|
||||||
{ 1, "data atr" },
|
{ 1, "data atr" },
|
||||||
{ 1, "data bin2hex" },
|
|
||||||
{ 0, "data bitsamples" },
|
{ 0, "data bitsamples" },
|
||||||
{ 1, "data bmap" },
|
{ 1, "data bmap" },
|
||||||
{ 1, "data clear" },
|
|
||||||
{ 1, "data crypto" },
|
{ 1, "data crypto" },
|
||||||
{ 1, "data diff" },
|
{ 1, "data diff" },
|
||||||
{ 0, "data hexsamples" },
|
{ 0, "data hexsamples" },
|
||||||
{ 1, "data hex2bin" },
|
|
||||||
{ 1, "data load" },
|
|
||||||
{ 1, "data num" },
|
|
||||||
{ 1, "data print" },
|
|
||||||
{ 0, "data samples" },
|
{ 0, "data samples" },
|
||||||
{ 1, "data save" },
|
|
||||||
{ 1, "data setdebugmode" },
|
|
||||||
{ 1, "data xor" },
|
|
||||||
{ 1, "emv help" },
|
{ 1, "emv help" },
|
||||||
{ 1, "emv list" },
|
{ 1, "emv list" },
|
||||||
{ 1, "emv test" },
|
{ 1, "emv test" },
|
||||||
|
@ -558,11 +556,11 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 0, "lf sniff" },
|
{ 0, "lf sniff" },
|
||||||
{ 0, "lf tune" },
|
{ 0, "lf tune" },
|
||||||
{ 1, "lf awid help" },
|
{ 1, "lf awid help" },
|
||||||
|
{ 0, "lf awid brute" },
|
||||||
|
{ 0, "lf awid clone" },
|
||||||
{ 1, "lf awid demod" },
|
{ 1, "lf awid demod" },
|
||||||
{ 0, "lf awid reader" },
|
{ 0, "lf awid reader" },
|
||||||
{ 0, "lf awid clone" },
|
|
||||||
{ 0, "lf awid sim" },
|
{ 0, "lf awid sim" },
|
||||||
{ 0, "lf awid brute" },
|
|
||||||
{ 0, "lf awid watch" },
|
{ 0, "lf awid watch" },
|
||||||
{ 1, "lf cotag help" },
|
{ 1, "lf cotag help" },
|
||||||
{ 1, "lf cotag demod" },
|
{ 1, "lf cotag demod" },
|
||||||
|
@ -647,16 +645,19 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 1, "lf hitag help" },
|
{ 1, "lf hitag help" },
|
||||||
{ 1, "lf hitag list" },
|
{ 1, "lf hitag list" },
|
||||||
{ 0, "lf hitag info" },
|
{ 0, "lf hitag info" },
|
||||||
|
{ 1, "lf hitag selftest" },
|
||||||
{ 0, "lf hitag dump" },
|
{ 0, "lf hitag dump" },
|
||||||
{ 0, "lf hitag read" },
|
{ 0, "lf hitag read" },
|
||||||
|
{ 0, "lf hitag sniff" },
|
||||||
{ 1, "lf hitag view" },
|
{ 1, "lf hitag view" },
|
||||||
{ 0, "lf hitag wrbl" },
|
{ 0, "lf hitag wrbl" },
|
||||||
{ 0, "lf hitag sniff" },
|
|
||||||
{ 0, "lf hitag cc" },
|
|
||||||
{ 0, "lf hitag ta" },
|
|
||||||
{ 0, "lf hitag eload" },
|
{ 0, "lf hitag eload" },
|
||||||
{ 0, "lf hitag eview" },
|
{ 0, "lf hitag eview" },
|
||||||
{ 0, "lf hitag sim" },
|
{ 0, "lf hitag sim" },
|
||||||
|
{ 0, "lf hitag cc" },
|
||||||
|
{ 0, "lf hitag chk" },
|
||||||
|
{ 1, "lf hitag lookup" },
|
||||||
|
{ 0, "lf hitag ta" },
|
||||||
{ 1, "lf idteck help" },
|
{ 1, "lf idteck help" },
|
||||||
{ 1, "lf idteck demod" },
|
{ 1, "lf idteck demod" },
|
||||||
{ 0, "lf idteck reader" },
|
{ 0, "lf idteck reader" },
|
||||||
|
|
|
@ -16,10 +16,15 @@
|
||||||
// Hitag2 Crypto
|
// Hitag2 Crypto
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "hitag2_crypto.h"
|
#include "hitag2_crypto.h"
|
||||||
|
#include <inttypes.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
#include "ui.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
||||||
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
|
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
|
||||||
|
@ -27,6 +32,7 @@
|
||||||
// No warranties or guarantees of any kind.
|
// No warranties or guarantees of any kind.
|
||||||
// This code is released into the public domain by its author.
|
// This code is released into the public domain by its author.
|
||||||
|
|
||||||
|
|
||||||
// Single bit Hitag2 functions:
|
// Single bit Hitag2 functions:
|
||||||
#ifndef i4
|
#ifndef i4
|
||||||
#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
|
#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
|
||||||
|
@ -36,30 +42,327 @@ static const uint32_t ht2_f4a = 0x2C79; // 0010 1100 0111 1001
|
||||||
static const uint32_t ht2_f4b = 0x6671; // 0110 0110 0111 0001
|
static const uint32_t ht2_f4b = 0x6671; // 0110 0110 0111 0001
|
||||||
static const uint32_t ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
static const uint32_t ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||||
|
|
||||||
static uint32_t ht2_f20(const uint64_t x) {
|
static uint32_t ht2_f20(const uint64_t state) {
|
||||||
uint32_t i5;
|
|
||||||
|
|
||||||
i5 = ((ht2_f4a >> i4(x, 1, 2, 4, 5)) & 1) * 1
|
uint32_t i5 = ((ht2_f4a >> i4(state, 1, 2, 4, 5)) & 1) * 1
|
||||||
+ ((ht2_f4b >> i4(x, 7, 11, 13, 14)) & 1) * 2
|
+ ((ht2_f4b >> i4(state, 7, 11, 13, 14)) & 1) * 2
|
||||||
+ ((ht2_f4b >> i4(x, 16, 20, 22, 25)) & 1) * 4
|
+ ((ht2_f4b >> i4(state, 16, 20, 22, 25)) & 1) * 4
|
||||||
+ ((ht2_f4b >> i4(x, 27, 28, 30, 32)) & 1) * 8
|
+ ((ht2_f4b >> i4(state, 27, 28, 30, 32)) & 1) * 8
|
||||||
+ ((ht2_f4a >> i4(x, 33, 42, 43, 45)) & 1) * 16;
|
+ ((ht2_f4a >> i4(state, 33, 42, 43, 45)) & 1) * 16;
|
||||||
|
|
||||||
return (ht2_f5c >> i5) & 1;
|
return (ht2_f5c >> i5) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ht2_hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t IV) {
|
// return a single bit from a value
|
||||||
uint32_t i;
|
static int ht2_bitn(uint64_t x, int bit) {
|
||||||
|
const uint64_t bitmask = (uint64_t)(1) << bit;
|
||||||
|
return (x & bitmask) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the sub-function R that rollback depends upon
|
||||||
|
int ht2_fnR(uint64_t state) {
|
||||||
|
// renumbered bits because my state is 0-47, not 1-48
|
||||||
|
return (
|
||||||
|
ht2_bitn(state, 1) ^ ht2_bitn(state, 2) ^ ht2_bitn(state, 5) ^
|
||||||
|
ht2_bitn(state, 6) ^ ht2_bitn(state, 7) ^ ht2_bitn(state, 15) ^
|
||||||
|
ht2_bitn(state, 21) ^ ht2_bitn(state, 22) ^ ht2_bitn(state, 25) ^
|
||||||
|
ht2_bitn(state, 29) ^ ht2_bitn(state, 40) ^ ht2_bitn(state, 41) ^
|
||||||
|
ht2_bitn(state, 42) ^ ht2_bitn(state, 45) ^ ht2_bitn(state, 46) ^
|
||||||
|
ht2_bitn(state, 47)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static void ht2_rollback(hitag_state_t *hstate, unsigned int steps) {
|
||||||
|
for (int i = 0; i < steps; i++) {
|
||||||
|
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | ht2_fnR(hstate->shiftreg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// the rollback function that lets us go backwards in time
|
||||||
|
void ht2_rollback(hitag_state_t *hstate, uint32_t steps) {
|
||||||
|
for (uint32_t i = 0; i < steps; i++) {
|
||||||
|
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | ht2_fnR(hstate->shiftreg);
|
||||||
|
hstate->lfsr = LFSR_INV(hstate->lfsr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the three filter sub-functions that feed fnf
|
||||||
|
#define ht2_fa(x) ht2_bitn(0x2C79, (x))
|
||||||
|
#define ht2_fb(x) ht2_bitn(0x6671, (x))
|
||||||
|
#define ht2_fc(x) ht2_bitn(0x7907287B, (x))
|
||||||
|
|
||||||
|
// the filter function that generates a bit of output from the prng state
|
||||||
|
int ht2_fnf(uint64_t state) {
|
||||||
|
|
||||||
|
uint32_t x1 = (ht2_bitn(state, 2) << 0) | (ht2_bitn(state, 3) << 1) | (ht2_bitn(state, 5) << 2) | (ht2_bitn(state, 6) << 3);
|
||||||
|
uint32_t x2 = (ht2_bitn(state, 8) << 0) | (ht2_bitn(state, 12) << 1) | (ht2_bitn(state, 14) << 2) | (ht2_bitn(state, 15) << 3);
|
||||||
|
uint32_t x3 = (ht2_bitn(state, 17) << 0) | (ht2_bitn(state, 21) << 1) | (ht2_bitn(state, 23) << 2) | (ht2_bitn(state, 26) << 3);
|
||||||
|
uint32_t x4 = (ht2_bitn(state, 28) << 0) | (ht2_bitn(state, 29) << 1) | (ht2_bitn(state, 31) << 2) | (ht2_bitn(state, 33) << 3);
|
||||||
|
uint32_t x5 = (ht2_bitn(state, 34) << 0) | (ht2_bitn(state, 43) << 1) | (ht2_bitn(state, 44) << 2) | (ht2_bitn(state, 46) << 3);
|
||||||
|
|
||||||
|
uint32_t x6 = (ht2_fa(x1) << 0) | (ht2_fb(x2) << 1) | (ht2_fb(x3) << 2) | (ht2_fb(x4) << 3) | (ht2_fa(x5) << 4);
|
||||||
|
return ht2_fc(x6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
|
||||||
|
/*
|
||||||
|
static void ht2_buildlfsr(hitag_state_t *hstate) {
|
||||||
|
if (hstate == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t state = hstate->shiftreg;
|
||||||
|
uint64_t temp = state ^ (state >> 1);
|
||||||
|
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||||
|
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||||
|
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||||
|
^ (temp >> 42) ^ (temp >> 46);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint64_t ht2_recoverkey(hitag_state_t *hstate, uint32_t uid, uint32_t nRenc) {
|
||||||
|
|
||||||
|
// hstate->shiftreg = (uint64_t)(((hstate->shiftreg << 1) & 0xffffffffffff) | (uint64_t)ht2_fnR(hstate->shiftreg));
|
||||||
|
// hstate->shiftreg = (uint64_t)(((hstate->shiftreg << 1) & 0xffffffffffff) | (uint64_t)ht2_fnR(hstate->shiftreg));
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
PrintAndLogEx(INFO, "shiftreg.... %" PRIx64, hstate->shiftreg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// key lower 16 bits are lower 16 bits of prng state
|
||||||
|
uint64_t key = hstate->shiftreg & 0xffff;
|
||||||
|
uint32_t nRxork = (hstate->shiftreg >> 16) & 0xffffffff;
|
||||||
|
|
||||||
|
// rollback and extract bits b
|
||||||
|
uint32_t b = 0;
|
||||||
|
for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
hstate->shiftreg = ((hstate->shiftreg) << 1) | ((uid >> (31 - i)) & 0x1);
|
||||||
|
b = (b << 1) | (unsigned int) ht2_fnf(hstate->shiftreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nR = nRenc ^ b;
|
||||||
|
uint64_t keyupper = nRxork ^ nR;
|
||||||
|
key = key | (keyupper << 16);
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "b..... %08" PRIx32 " %08" PRIx32 " %012" PRIx64, b, nRenc, hstate->shiftreg);
|
||||||
|
PrintAndLogEx(INFO, "key... %012" PRIx64 " %012" PRIx64 "\n", key, REV64(key));
|
||||||
|
#endif
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameters:
|
||||||
|
* Hitag_State* pstate - output, internal state after initialisation
|
||||||
|
* uint64_t sharedkey - 48 bit key shared between reader & tag
|
||||||
|
* uint32_t serialnum - 32 bit tag serial number
|
||||||
|
* uint32_t iv - 32 bit random IV from reader, part of tag authentication
|
||||||
|
*/
|
||||||
|
void ht2_hitag2_init_ex(hitag_state_t *hstate, uint64_t sharedkey, uint32_t serialnum, uint32_t iv) {
|
||||||
|
// init state, from serial number and lowest 16 bits of shared key
|
||||||
|
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
|
||||||
|
|
||||||
|
// mix the initialisation vector and highest 32 bits of the shared key
|
||||||
|
iv ^= (uint32_t)(sharedkey >> 16);
|
||||||
|
|
||||||
|
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||||
|
// these will be XORed in turn with output of the crypto function
|
||||||
|
state |= (uint64_t) iv << 48;
|
||||||
|
iv >>= 16;
|
||||||
|
|
||||||
|
// unrolled loop is faster on PIC32 (MIPS), do 32 times
|
||||||
|
// shift register, then calc new bit
|
||||||
|
state >>= 1;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
|
||||||
|
// highest 16 bits of IV XOR Shared Key
|
||||||
|
state |= (uint64_t) iv << 47;
|
||||||
|
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state = (state >> 1) ^ (uint64_t) ht2_f20(state) << 46;
|
||||||
|
state ^= (uint64_t) ht2_f20(state) << 47;
|
||||||
|
|
||||||
|
// LSFR
|
||||||
|
|
||||||
|
hstate->shiftreg = state;
|
||||||
|
/* naive version for reference, LFSR has 16 taps
|
||||||
|
pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6)
|
||||||
|
^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22)
|
||||||
|
^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||||
|
^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47);
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// optimise with one 64-bit intermediate
|
||||||
|
uint64_t temp = state ^ (state >> 1);
|
||||||
|
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||||
|
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||||
|
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||||
|
^ (temp >> 42) ^ (temp >> 46);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return up to 32 crypto bits.
|
||||||
|
* Last bit is in least significant bit, earlier bits are shifted left.
|
||||||
|
* Note that the Hitag transmission protocol is least significant bit,
|
||||||
|
* so we may want to change this, or add a function, that returns the
|
||||||
|
* crypto output bits in the other order.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* Hitag_State* pstate - in/out, internal cipher state after initialisation
|
||||||
|
* uint32_t steps - number of bits requested, (capped at 32)
|
||||||
|
*/
|
||||||
|
uint32_t ht2_hitag2_nstep(hitag_state_t *hstate, uint32_t steps) {
|
||||||
|
uint64_t state = hstate->shiftreg;
|
||||||
|
uint32_t result = 0;
|
||||||
|
uint64_t lfsr = hstate->lfsr;
|
||||||
|
|
||||||
|
if (steps == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
// update shift registers
|
||||||
|
if (lfsr & 1) {
|
||||||
|
state = (state >> 1) | 0x800000000000;
|
||||||
|
lfsr = (lfsr >> 1) ^ 0xB38083220073;
|
||||||
|
// accumulate next bit of crypto
|
||||||
|
result = (result << 1) | ht2_f20(state);
|
||||||
|
} else {
|
||||||
|
state >>= 1;
|
||||||
|
lfsr >>= 1;
|
||||||
|
result = (result << 1) | ht2_f20(state);
|
||||||
|
}
|
||||||
|
} while (--steps);
|
||||||
|
|
||||||
|
hstate->shiftreg = state;
|
||||||
|
hstate->lfsr = lfsr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ht2_hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t iv) {
|
||||||
|
|
||||||
uint64_t x = ((key & 0xFFFF) << 32) + serial;
|
uint64_t x = ((key & 0xFFFF) << 32) + serial;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (uint32_t i = 0; i < 32; i++) {
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
x += (uint64_t)(ht2_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47;
|
x += (uint64_t)(ht2_f20(x) ^ (((iv >> i) ^ (key >> (i + 16))) & 1)) << 47;
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ht2_hitag2_round(uint64_t *state) {
|
int ht2_try_state(uint64_t s, uint32_t uid, uint32_t aR2, uint32_t nR1, uint32_t nR2, uint64_t *key) {
|
||||||
|
|
||||||
|
hitag_state_t hstate;
|
||||||
|
hstate.shiftreg = s;
|
||||||
|
hstate.lfsr = 0;
|
||||||
|
|
||||||
|
hstate.shiftreg = (uint64_t)(((hstate.shiftreg << 1) & 0xffffffffffff) | (uint64_t)ht2_fnR(hstate.shiftreg));
|
||||||
|
hstate.shiftreg = (uint64_t)(((hstate.shiftreg << 1) & 0xffffffffffff) | (uint64_t)ht2_fnR(hstate.shiftreg));
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
hitag_state_t hs2;
|
||||||
|
hs2.shiftreg = s;
|
||||||
|
hs2.lfsr = 0;
|
||||||
|
ht2_rollback(&hs2, 2);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "hstate shiftreg.... %" PRIx64 " lfsr... %" PRIx64, hstate.shiftreg, hstate.lfsr);
|
||||||
|
PrintAndLogEx(INFO, "hstate shiftreg.... %" PRIx64 " lfsr... %" PRIx64, hs2.shiftreg, hs2.lfsr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// recover key
|
||||||
|
uint64_t keyrev = hstate.shiftreg & 0xffff;
|
||||||
|
uint64_t nR1xk = (hstate.shiftreg >> 16) & 0xffffffff;
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
PrintAndLogEx(INFO, "keyrev...... %012" PRIx64 " nR1xk... %08" PRIx64, keyrev, nR1xk);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t b = 0;
|
||||||
|
for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
hstate.shiftreg = ((hstate.shiftreg) << 1) | ((uid >> (31 - i)) & 0x1);
|
||||||
|
b = (b << 1) | (unsigned int) ht2_fnf(hstate.shiftreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
PrintAndLogEx(INFO, "b..... %08" PRIx32 " %08" PRIx32 " %012" PRIx64, b, nR1, hstate.shiftreg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
keyrev |= (nR1xk ^ nR1 ^ b) << 16;
|
||||||
|
|
||||||
|
#ifndef ON_DEVICE
|
||||||
|
PrintAndLogEx(INFO, "key... %012" PRIx64 " %012" PRIx64, keyrev, REV64(keyrev));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// test key
|
||||||
|
ht2_hitag2_init_ex(&hstate, keyrev, uid, nR2);
|
||||||
|
|
||||||
|
if ((aR2 ^ ht2_hitag2_nstep(&hstate, 32)) == 0xFFFFFFFF) {
|
||||||
|
*key = REV64(keyrev);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// "MIKRON" = O N M I K R
|
||||||
|
// Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||||
|
// Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||||
|
// Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||||
|
//~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||||
|
|
||||||
|
// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||||
|
// The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||||
|
// The rest is encrypted by XORing it with the subsequent keystream.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 8 crypto bits.
|
||||||
|
* Last bit is in least significant bit, earlier bits are shifted left.
|
||||||
|
* Note that the Hitag transmission protocol is least significant bit,
|
||||||
|
* so we may want to change this, or add a function, that returns the
|
||||||
|
* crypto output bits in the other order.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* uint64_t *state - in/out, internal cipher state after initialisation
|
||||||
|
*/
|
||||||
|
uint64_t ht2_hitag2_bit(uint64_t *state) {
|
||||||
uint64_t x = *state;
|
uint64_t x = *state;
|
||||||
|
|
||||||
x = (x >> 1) +
|
x = (x >> 1) +
|
||||||
|
@ -72,21 +375,25 @@ uint64_t ht2_hitag2_round(uint64_t *state) {
|
||||||
return ht2_f20(x);
|
return ht2_f20(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "MIKRON" = O N M I K R
|
// Take a state and create one byte (8bits) of crypto
|
||||||
// Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
uint32_t ht2_hitag2_byte(uint64_t *state) {
|
||||||
// Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
uint32_t c = 0;
|
||||||
// Random = 65 6E 45 72 - Random IV, transmitted in clear
|
c += (uint32_t) ht2_hitag2_bit(state) << 7; // 7
|
||||||
//~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
c += (uint32_t) ht2_hitag2_bit(state) << 6; // 6
|
||||||
|
c += (uint32_t) ht2_hitag2_bit(state) << 5; // 5
|
||||||
// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
c += (uint32_t) ht2_hitag2_bit(state) << 4;
|
||||||
// The inverse of the first 4 bytes is sent to the tag to authenticate.
|
c += (uint32_t) ht2_hitag2_bit(state) << 3;
|
||||||
// The rest is encrypted by XORing it with the subsequent keystream.
|
c += (uint32_t) ht2_hitag2_bit(state) << 2;
|
||||||
|
c += (uint32_t) ht2_hitag2_bit(state) << 1;
|
||||||
uint32_t ht2_hitag2_byte(uint64_t *x) {
|
c += (uint32_t) ht2_hitag2_bit(state) << 0;
|
||||||
uint32_t i, c;
|
return c;
|
||||||
for (i = 0, c = 0; i < 8; i++) {
|
|
||||||
c += (uint32_t) ht2_hitag2_round(x) << (i ^ 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ht2_hitag2_word(uint64_t *state, uint32_t steps) {
|
||||||
|
uint32_t c = 0;
|
||||||
|
do {
|
||||||
|
c += (uint32_t) ht2_hitag2_bit(state) << (steps - 1);
|
||||||
|
} while (--steps);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,19 +415,23 @@ void ht2_hitag2_cipher_reset(hitag2_t *tag, const uint8_t *iv) {
|
||||||
tag->cs = ht2_hitag2_init(REV64(key), REV32(uid), REV32(iv_));
|
tag->cs = ht2_hitag2_init(REV64(key), REV32(uid), REV32(iv_));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ht2_hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is) {
|
int ht2_hitag2_cipher_authenticate(uint64_t *state, const uint8_t *authenticator_is) {
|
||||||
uint8_t authenticator_should[4];
|
uint8_t authenticator_should[4];
|
||||||
authenticator_should[0] = ~ht2_hitag2_byte(cs);
|
authenticator_should[0] = ~ht2_hitag2_byte(state);
|
||||||
authenticator_should[1] = ~ht2_hitag2_byte(cs);
|
authenticator_should[1] = ~ht2_hitag2_byte(state);
|
||||||
authenticator_should[2] = ~ht2_hitag2_byte(cs);
|
authenticator_should[2] = ~ht2_hitag2_byte(state);
|
||||||
authenticator_should[3] = ~ht2_hitag2_byte(cs);
|
authenticator_should[3] = ~ht2_hitag2_byte(state);
|
||||||
return (memcmp(authenticator_should, authenticator_is, 4) == 0);
|
return (memcmp(authenticator_should, authenticator_is, 4) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ht2_hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) {
|
void ht2_hitag2_cipher_transcrypt(uint64_t *state, uint8_t *data, uint16_t bytes, uint16_t bits) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < bytes; i++) data[i] ^= ht2_hitag2_byte(cs);
|
for (i = 0; i < bytes; i++) {
|
||||||
for (i = 0; i < bits; i++) data[bytes] ^= ht2_hitag2_round(cs) << (7 - i);
|
data[i] ^= ht2_hitag2_byte(state);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bits; i++) {
|
||||||
|
data[bytes] ^= ht2_hitag2_bit(state) << (7 - i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
#define __HITAG2_CRYPTO_H
|
#define __HITAG2_CRYPTO_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifndef LFSR_INV
|
||||||
|
#define LFSR_INV(state) (((state) << 1) | (__builtin_parityll((state) & ((0xce0044c101cd >> 1) | (1ull << 47)))))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t uid;
|
uint32_t uid;
|
||||||
|
@ -32,11 +38,27 @@ typedef struct {
|
||||||
uint8_t sectors[12][4];
|
uint8_t sectors[12][4];
|
||||||
} hitag2_t;
|
} hitag2_t;
|
||||||
|
|
||||||
uint64_t ht2_hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t IV);
|
typedef struct {
|
||||||
uint64_t ht2_hitag2_round(uint64_t *state);
|
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
|
||||||
uint32_t ht2_hitag2_byte(uint64_t *x);
|
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||||
void ht2_hitag2_cipher_reset(hitag2_t *tag, const uint8_t *iv);
|
} hitag_state_t;
|
||||||
int ht2_hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is);
|
|
||||||
int ht2_hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) ;
|
|
||||||
|
|
||||||
|
void ht2_hitag2_init_ex(hitag_state_t *hstate, uint64_t sharedkey, uint32_t serialnum, const uint32_t iv);
|
||||||
|
void ht2_rollback(hitag_state_t *hstate, uint32_t steps);
|
||||||
|
uint64_t ht2_recoverkey(hitag_state_t *hstate, uint32_t uid, uint32_t nRenc);
|
||||||
|
uint32_t ht2_hitag2_nstep(hitag_state_t *hstate, uint32_t steps);
|
||||||
|
uint32_t ht2_hitag_acid(hitag_state_t *hstate, uint32_t steps);
|
||||||
|
|
||||||
|
int ht2_try_state(uint64_t s, uint32_t uid, uint32_t aR2, uint32_t nR1, uint32_t nR2, uint64_t *key);
|
||||||
|
|
||||||
|
uint32_t ht2_hitag2_word(uint64_t *state, uint32_t steps);
|
||||||
|
uint64_t ht2_hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t iv);
|
||||||
|
uint64_t ht2_hitag2_bit(uint64_t *state);
|
||||||
|
uint32_t ht2_hitag2_byte(uint64_t *state);
|
||||||
|
void ht2_hitag2_cipher_reset(hitag2_t *tag, const uint8_t *iv);
|
||||||
|
int ht2_hitag2_cipher_authenticate(uint64_t *state, const uint8_t *authenticator_is);
|
||||||
|
void ht2_hitag2_cipher_transcrypt(uint64_t *state, uint8_t *data, uint16_t bytes, uint16_t bits) ;
|
||||||
|
|
||||||
|
int ht2_fnf(uint64_t state);
|
||||||
|
int ht2_fnR(uint64_t state);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,10 +42,8 @@ static const uint8_t g_odd_byte_parity[256] = {
|
||||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
//extern const uint8_t OddByteParity[256];
|
#define ODD_PARITY8(x) g_odd_byte_parity[x]
|
||||||
|
#define EVEN_PARITY8(x) !g_odd_byte_parity[x]
|
||||||
#define ODD_PARITY8(x) { g_odd_byte_parity[x] }
|
|
||||||
#define EVEN_PARITY8(x) { !g_odd_byte_parity[x] }
|
|
||||||
|
|
||||||
static inline uint8_t oddparity8(const uint8_t x) {
|
static inline uint8_t oddparity8(const uint8_t x) {
|
||||||
return g_odd_byte_parity[x];
|
return g_odd_byte_parity[x];
|
||||||
|
@ -60,7 +58,7 @@ static inline uint8_t evenparity16(uint16_t x) {
|
||||||
x ^= x >> 8;
|
x ^= x >> 8;
|
||||||
return EVEN_PARITY8(x) ;
|
return EVEN_PARITY8(x) ;
|
||||||
#else
|
#else
|
||||||
return (__builtin_parity(x) & 0xFF);
|
return __builtin_parity(x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +77,7 @@ static inline uint8_t evenparity32(uint32_t x) {
|
||||||
x ^= x >> 8;
|
x ^= x >> 8;
|
||||||
return EVEN_PARITY8(x) ;
|
return EVEN_PARITY8(x) ;
|
||||||
#else
|
#else
|
||||||
return (__builtin_parity(x) & 0xFF);
|
return __builtin_parity(x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,18 +221,21 @@
|
||||||
],
|
],
|
||||||
"usage": "data autocorr [-hg] [-w <dec>]"
|
"usage": "data autocorr [-hg] [-w <dec>]"
|
||||||
},
|
},
|
||||||
"data bin2hex": {
|
"data biphaserawdecode": {
|
||||||
"command": "data bin2hex",
|
"command": "data biphaserawdecode",
|
||||||
"description": "This function converts binary to hexadecimal. It will ignore all characters not 1 or 0 but stop reading on whitespace",
|
"description": "Biphase decode binary stream in DemodBuffer Converts 10 or 01 -> 1 and 11 or 00 -> 0 - must have binary sequence in DemodBuffer (run `data rawdemod --ar` before) - invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester",
|
||||||
"notes": [
|
"notes": [
|
||||||
"data bin2hex -d 0101111001010"
|
"data biphaserawdecode -> decode biphase bitstream from the DemodBuffer",
|
||||||
|
"data biphaserawdecode -oi -> decode biphase bitstream from the DemodBuffer, adjust offset, and invert output"
|
||||||
],
|
],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-d, --data <bin> binary string to convert"
|
"-o, --offset set to adjust decode start position",
|
||||||
|
"-i, --inv invert output",
|
||||||
|
"--err <dec> set max errors tolerated (def 20)"
|
||||||
],
|
],
|
||||||
"usage": "data bin2hex [-h] -d <bin>"
|
"usage": "data biphaserawdecode [-hoi] [--err <dec>]"
|
||||||
},
|
},
|
||||||
"data bitsamples": {
|
"data bitsamples": {
|
||||||
"command": "data bitsamples",
|
"command": "data bitsamples",
|
||||||
|
@ -261,18 +264,6 @@
|
||||||
],
|
],
|
||||||
"usage": "data bmap [-h] [-d <hex>] [-m <str>]"
|
"usage": "data bmap [-h] [-d <hex>] [-m <str>]"
|
||||||
},
|
},
|
||||||
"data clear": {
|
|
||||||
"command": "data clear",
|
|
||||||
"description": "This function clears the bigbuff on deviceside and graph window",
|
|
||||||
"notes": [
|
|
||||||
"data clear"
|
|
||||||
],
|
|
||||||
"offline": true,
|
|
||||||
"options": [
|
|
||||||
"-h, --help This help"
|
|
||||||
],
|
|
||||||
"usage": "data clear [-h]"
|
|
||||||
},
|
|
||||||
"data convertbitstream": {
|
"data convertbitstream": {
|
||||||
"command": "data convertbitstream",
|
"command": "data convertbitstream",
|
||||||
"description": "Convert GraphBuffer's 0|1 values to 127|-127",
|
"description": "Convert GraphBuffer's 0|1 values to 127|-127",
|
||||||
|
@ -444,32 +435,15 @@
|
||||||
},
|
},
|
||||||
"data help": {
|
"data help": {
|
||||||
"command": "data help",
|
"command": "data help",
|
||||||
"description": "----------- ------------------------- General------------------------- help This help ----------- ------------------------- Modulation------------------------- biphaserawdecode Biphase decode bin stream in DemodBuffer detectclock Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer fsktonrz Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk) manrawdecode Manchester decode binary stream in DemodBuffer modulation Identify LF signal for clock and modulation rawdemod Demodulate the data in the GraphBuffer and output binary ----------- ------------------------- Graph------------------------- askedgedetect Adjust Graph for manual ASK demod autocorr Autocorrelation over window dirthreshold Max rising higher up-thres/ Min falling lower down-thres decimate Decimate samples envelope Generate square envelope of samples undecimate Un-decimate samples hide Hide graph window hpf Remove DC offset from trace iir Apply IIR buttersworth filter on plot data grid overlay grid on graph window ltrim Trim samples from left of trace mtrim Trim out samples from the specified start to the specified stop norm Normalize max/min to +/-128 plot Show graph window cthreshold Average out all values between rtrim Trim samples from right of trace setgraphmarkers Set blue and orange marker in graph window shiftgraphzero Shift 0 for Graphed wave + or - shift value timescale Set cursor display timescale zerocrossings Count time between zero-crossings convertbitstream Convert GraphBuffer's 0/1 values to 127 / -127 getbitstream Convert GraphBuffer's >=1 values to 1 and <1 to 0 ----------- ------------------------- Operations------------------------- asn1 ASN1 decoder atr ATR lookup bin2hex Converts binary to hexadecimal bmap Convert hex value according a binary template clear Clears bigbuf on deviceside and graph window crypto Encrypt and decrypt data diff Diff of input files hex2bin Converts hexadecimal to binary load Load contents of file into graph window num Converts dec/hex/bin print Print the data in the DemodBuffer save Save signal trace data ( GraphBuffer ) setdebugmode Set Debugging Level on client side xor Xor a input string --------------------------------------------------------------------------------------- data biphaserawdecode available offline: yes Biphase decode binary stream in DemodBuffer Converts 10 or 01 -> 1 and 11 or 00 -> 0 - must have binary sequence in DemodBuffer (run `data rawdemod --ar` before) - invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester",
|
"description": "help This help ----------- ------------------------- General------------------------- clear Clears various buffers used by the graph window hide Hide the graph window load Load contents of file into graph window num Converts dec/hex/bin plot Show the graph window print Print the data in the DemodBuffer save Save signal trace data setdebugmode Set Debugging Level on client side xor Xor a input string ----------- ------------------------- Modulation------------------------- biphaserawdecode Biphase decode bin stream in DemodBuffer detectclock Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer fsktonrz Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk) manrawdecode Manchester decode binary stream in DemodBuffer modulation Identify LF signal for clock and modulation rawdemod Demodulate the data in the GraphBuffer and output binary ----------- ------------------------- Graph------------------------- askedgedetect Adjust Graph for manual ASK demod autocorr Autocorrelation over window convertbitstream Convert GraphBuffer's 0/1 values to 127 / -127 cthreshold Average out all values between dirthreshold Max rising higher up-thres/ Min falling lower down-thres decimate Decimate samples envelope Generate square envelope of samples grid overlay grid on graph window getbitstream Convert GraphBuffer's >=1 values to 1 and <1 to 0 hpf Remove DC offset from trace iir Apply IIR buttersworth filter on plot data ltrim Trim samples from left of trace mtrim Trim out samples from the specified start to the specified stop norm Normalize max/min to +/-128 rtrim Trim samples from right of trace setgraphmarkers Set the markers in the graph window shiftgraphzero Shift 0 for Graphed wave + or - shift value timescale Set cursor display timescale undecimate Un-decimate samples zerocrossings Count time between zero-crossings ----------- ------------------------- Operations------------------------- asn1 ASN1 decoder atr ATR lookup bmap Convert hex value according a binary template crypto Encrypt and decrypt data diff Diff of input files --------------------------------------------------------------------------------------- data clear available offline: yes This function clears the BigBuf on device side and graph window ( graphbuffer )",
|
||||||
"notes": [
|
"notes": [
|
||||||
"data biphaserawdecode -> decode biphase bitstream from the DemodBuffer",
|
"data clear"
|
||||||
"data biphaserawdecode -oi -> decode biphase bitstream from the DemodBuffer, adjust offset, and invert output"
|
|
||||||
],
|
],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help"
|
||||||
"-o, --offset set to adjust decode start position",
|
|
||||||
"-i, --inv invert output",
|
|
||||||
"--err <dec> set max errors tolerated (def 20)"
|
|
||||||
],
|
],
|
||||||
"usage": "data biphaserawdecode [-hoi] [--err <dec>]"
|
"usage": "data clear [-h]"
|
||||||
},
|
|
||||||
"data hex2bin": {
|
|
||||||
"command": "data hex2bin",
|
|
||||||
"description": "This function converts hexadecimal to binary. It will ignore all non-hexadecimal characters but stop reading on whitespace",
|
|
||||||
"notes": [
|
|
||||||
"data hex2bin -d 01020304"
|
|
||||||
],
|
|
||||||
"offline": true,
|
|
||||||
"options": [
|
|
||||||
"-h, --help This help",
|
|
||||||
"-d, --data <hex> bytes to convert"
|
|
||||||
],
|
|
||||||
"usage": "data hex2bin [-h] [-d <hex>]"
|
|
||||||
},
|
},
|
||||||
"data hexsamples": {
|
"data hexsamples": {
|
||||||
"command": "data hexsamples",
|
"command": "data hexsamples",
|
||||||
|
@ -735,18 +709,22 @@
|
||||||
},
|
},
|
||||||
"data setgraphmarkers": {
|
"data setgraphmarkers": {
|
||||||
"command": "data setgraphmarkers",
|
"command": "data setgraphmarkers",
|
||||||
"description": "Set blue and orange marker in graph window",
|
"description": "Set the locations of the markers in the graph window",
|
||||||
"notes": [
|
"notes": [
|
||||||
"data setgraphmarkers -> turn off",
|
"data setgraphmarkers -> reset the markers",
|
||||||
"data setgraphmarkers -a 64 -b 50"
|
"data setgraphmarkers -a 64 -> set A, reset the rest",
|
||||||
|
"data setgraphmarkers -d --keep -> set D, keep the rest"
|
||||||
],
|
],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-a <dec> orange marker",
|
"--keep keep the current values of the markers",
|
||||||
"-b <dec> blue marker"
|
"-a <dec> yellow marker",
|
||||||
|
"-b <dec> pink marker",
|
||||||
|
"-c <dec> orange marker",
|
||||||
|
"-d <dec> blue marker"
|
||||||
],
|
],
|
||||||
"usage": "data setgraphmarkers [-h] [-a <dec>] [-b <dec>]"
|
"usage": "data setgraphmarkers [-h] [--keep] [-a <dec>] [-b <dec>] [-c <dec>] [-d <dec>]"
|
||||||
},
|
},
|
||||||
"data shiftgraphzero": {
|
"data shiftgraphzero": {
|
||||||
"command": "data shiftgraphzero",
|
"command": "data shiftgraphzero",
|
||||||
|
@ -1621,14 +1599,16 @@
|
||||||
"command": "hf 15 csetuid",
|
"command": "hf 15 csetuid",
|
||||||
"description": "Set UID for magic Chinese card (only works with such cards)",
|
"description": "Set UID for magic Chinese card (only works with such cards)",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf 15 csetuid -u E011223344556677"
|
"hf 15 csetuid -u E011223344556677 -> use gen1 command",
|
||||||
|
"hf 15 csetuid -u E011223344556677 --v2 -> use gen2 command"
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-u, --uid <hex> UID, 8 hex bytes"
|
"-u, --uid <hex> UID, 8 hex bytes",
|
||||||
|
"-2, --v2 Use gen2 magic command"
|
||||||
],
|
],
|
||||||
"usage": "hf 15 csetuid [-h] -u <hex>"
|
"usage": "hf 15 csetuid [-h2] -u <hex>"
|
||||||
},
|
},
|
||||||
"hf 15 demod": {
|
"hf 15 demod": {
|
||||||
"command": "hf 15 demod",
|
"command": "hf 15 demod",
|
||||||
|
@ -3329,7 +3309,7 @@
|
||||||
},
|
},
|
||||||
"hf iclass help": {
|
"hf iclass help": {
|
||||||
"command": "hf iclass help",
|
"command": "hf iclass help",
|
||||||
"description": "----------- --------------------- General --------------------- help This help list List iclass history view Display content from tag dump file ----------- --------------------- Recovery -------------------- loclass Use loclass to perform bruteforce reader attack lookup Uses authentication trace to check for key in dictionary file ----------- ---------------------- Utils ---------------------- calcnewkey Calc diversified keys (blocks 3 & 4) to write new keys encode Encode binary wiegand to block 7 encrypt Encrypt given block data decrypt Decrypt given block data or tag dump file managekeys Manage keys to use with iclass commands permutekey Permute function from 'heart of darkness' paper --------------------------------------------------------------------------------------- hf iclass list available offline: yes Alias of `trace list -t iclass -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
"description": "help This help list List iclass history view Display content from tag dump file ----------- --------------------- Recovery -------------------- loclass Use loclass to perform bruteforce reader attack lookup Uses authentication trace to check for key in dictionary file ----------- ---------------------- Utils ---------------------- calcnewkey Calc diversified keys (blocks 3 & 4) to write new keys encode Encode binary wiegand to block 7 encrypt Encrypt given block data decrypt Decrypt given block data or tag dump file managekeys Manage keys to use with iclass commands permutekey Permute function from 'heart of darkness' paper --------------------------------------------------------------------------------------- hf iclass list available offline: yes Alias of `trace list -t iclass -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf iclass list --frame -> show frame delay times",
|
"hf iclass list --frame -> show frame delay times",
|
||||||
"hf iclass list -1 -> use trace buffer"
|
"hf iclass list -1 -> use trace buffer"
|
||||||
|
@ -3372,14 +3352,14 @@
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-f, --file <fn> filename with nr/mac data from `hf iclass sim -t 2`",
|
"-f, --file <fn> filename with nr/mac data from `hf iclass sim -t 2`",
|
||||||
"--test Perform self-test",
|
"--test Perform self test",
|
||||||
"--long Perform self-test, including long ones"
|
"--long Perform self test, including long ones"
|
||||||
],
|
],
|
||||||
"usage": "hf iclass loclass [-h] [-f <fn>] [--test] [--long]"
|
"usage": "hf iclass loclass [-h] [-f <fn>] [--test] [--long]"
|
||||||
},
|
},
|
||||||
"hf iclass lookup": {
|
"hf iclass lookup": {
|
||||||
"command": "hf iclass lookup",
|
"command": "hf iclass lookup",
|
||||||
"description": "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file",
|
"description": "This command take sniffed trace data and try to recovery a iCLASS Standard or iCLASS Elite key.",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic",
|
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic",
|
||||||
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite"
|
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite"
|
||||||
|
@ -8219,11 +8199,12 @@
|
||||||
],
|
],
|
||||||
"usage": "lf awid clone [-h] --fmt <dec> --fc <dec> --cn <dec> [--q5] [--em]"
|
"usage": "lf awid clone [-h] --fmt <dec> --fc <dec> --cn <dec> [--q5] [--em]"
|
||||||
},
|
},
|
||||||
"lf awid help": {
|
"lf awid demod": {
|
||||||
"command": "lf awid help",
|
"command": "lf awid demod",
|
||||||
"description": "help this help demod demodulate an AWID FSK tag from the GraphBuffer --------------------------------------------------------------------------------------- lf awid demod available offline: yes Try to find AWID Prox preamble, if found decode / descramble data",
|
"description": "Try to find AWID Prox preamble, if found decode / descramble data",
|
||||||
"notes": [
|
"notes": [
|
||||||
"lf awid demod"
|
"lf awid demod",
|
||||||
|
"lf awid demod --raw"
|
||||||
],
|
],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -8231,6 +8212,25 @@
|
||||||
],
|
],
|
||||||
"usage": "lf awid demod [-h]"
|
"usage": "lf awid demod [-h]"
|
||||||
},
|
},
|
||||||
|
"lf awid help": {
|
||||||
|
"command": "lf awid help",
|
||||||
|
"description": "help this help demod demodulate an AWID FSK tag from the GraphBuffer --------------------------------------------------------------------------------------- lf awid brute available offline: no Enables bruteforce of AWID reader with specified facility-code. This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step if cardnumber is not given, it starts with 1 and goes up to 65535",
|
||||||
|
"notes": [
|
||||||
|
"lf awid brute --fmt 26 --fc 224",
|
||||||
|
"lf awid brute --fmt 50 --fc 2001 --delay 2000",
|
||||||
|
"lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
|
||||||
|
],
|
||||||
|
"offline": true,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"--fmt <dec> format length 26|50",
|
||||||
|
"--fc <dec> 8|16bit value facility code",
|
||||||
|
"--cn <dec> optional - card number to start with, max 65535",
|
||||||
|
"--delay <dec> optional - delay betweens attempts in ms. Default 1000ms",
|
||||||
|
"-v, --verbose verbose output"
|
||||||
|
],
|
||||||
|
"usage": "lf awid brute [-hv] --fmt <dec> --fc <dec> [--cn <dec>] [--delay <dec>]"
|
||||||
|
},
|
||||||
"lf awid reader": {
|
"lf awid reader": {
|
||||||
"command": "lf awid reader",
|
"command": "lf awid reader",
|
||||||
"description": "read a AWID Prox tag",
|
"description": "read a AWID Prox tag",
|
||||||
|
@ -9426,20 +9426,32 @@
|
||||||
],
|
],
|
||||||
"usage": "lf hitag cc [-h] -f <fn>"
|
"usage": "lf hitag cc [-h] -f <fn>"
|
||||||
},
|
},
|
||||||
|
"lf hitag chk": {
|
||||||
|
"command": "lf hitag chk",
|
||||||
|
"description": "Run dictionary key or password recovery against Hitag card.",
|
||||||
|
"notes": [
|
||||||
|
"lf hitag chk",
|
||||||
|
"-> checks for both pwd / crypto keyslf hitag chk --crypto -> use def dictionary",
|
||||||
|
"lf hitag chk --pwd -f my.dic -> pwd mode, custom dictionary"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-f, --file <fn> specify dictionary filename",
|
||||||
|
"--pwd password mode",
|
||||||
|
"--crypto crypto mode"
|
||||||
|
],
|
||||||
|
"usage": "lf hitag chk [-h] [-f <fn>] [--pwd] [--crypto]"
|
||||||
|
},
|
||||||
"lf hitag dump": {
|
"lf hitag dump": {
|
||||||
"command": "lf hitag dump",
|
"command": "lf hitag dump",
|
||||||
"description": "Read all Hitag 2 card memory and save to file Crypto mode key format: ISK high + ISK low",
|
"description": "Read all Hitag 2 card memory and save to file Crypto mode key format: ISK high + ISK low, 4F4E4D494B52 (ONMIKR) Password mode, default key 4D494B52 (MIKR)",
|
||||||
"notes": [
|
"notes": [
|
||||||
"Password mode => use default key 4D494B52 (MIKR)",
|
"lf hitag dump --pwd -> use def pwd",
|
||||||
"lf hitag dump --pwd",
|
"lf hitag dump -k 4D494B52 -> pwd mode",
|
||||||
"Short key = password mode",
|
"lf hitag dump --crypto -> use def crypto",
|
||||||
"lf hitag dump -k 4D494B52",
|
"lf hitag dump -k 4F4E4D494B52 -> crypto mode",
|
||||||
"Challenge mode",
|
"lf hitag dump --nrar 0102030411223344"
|
||||||
"lf hitag dump --nrar 0102030411223344",
|
|
||||||
"Crypto mode => use default key 4F4E4D494B52 (ONMIKR)",
|
|
||||||
"lf hitag dump --crypto",
|
|
||||||
"Long key = crypto mode",
|
|
||||||
"lf hitag dump -k 4F4E4D494B52"
|
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -9485,7 +9497,7 @@
|
||||||
},
|
},
|
||||||
"lf hitag help": {
|
"lf hitag help": {
|
||||||
"command": "lf hitag help",
|
"command": "lf hitag help",
|
||||||
"description": "help This help list List Hitag trace history view Display content from tag dump file --------------------------------------------------------------------------------------- lf hitag list available offline: yes Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
"description": "help This help list List Hitag trace history selftest Perform self test view Display content from tag dump file lookup Uses authentication trace to check for key in dictionary file --------------------------------------------------------------------------------------- lf hitag list available offline: yes Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||||
"notes": [
|
"notes": [
|
||||||
"lf hitag list --frame -> show frame delay times",
|
"lf hitag list --frame -> show frame delay times",
|
||||||
"lf hitag list -1 -> use trace buffer"
|
"lf hitag list -1 -> use trace buffer"
|
||||||
|
@ -9516,29 +9528,41 @@
|
||||||
],
|
],
|
||||||
"usage": "lf hitag info [-h]"
|
"usage": "lf hitag info [-h]"
|
||||||
},
|
},
|
||||||
|
"lf hitag lookup": {
|
||||||
|
"command": "lf hitag lookup",
|
||||||
|
"description": "This command take sniffed trace data and try to recovery a Hitag2 crypto key. You can either - verify that NR/AR matches a known crypto key - verify if NR/AR matches a known 6 byte crypto key in a dictionary",
|
||||||
|
"notes": [
|
||||||
|
"lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -k 010203040506 -> check key",
|
||||||
|
"lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -> use def dictionary",
|
||||||
|
"lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -f my.dic -> use custom dictionary",
|
||||||
|
"lf hitag lookup --uid 11223344 --nrar 73AA5A62EAB8529C"
|
||||||
|
],
|
||||||
|
"offline": true,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-f, --file <fn> specify dictionary filename",
|
||||||
|
"-k, --key <hex> specify known cryptokey as 6 bytes",
|
||||||
|
"-u, --uid <hex> specify UID as 4 hex bytes",
|
||||||
|
"--nr <hex> specify nonce as 4 hex bytes",
|
||||||
|
"--ar <hex> specify answer as 4 hex bytes",
|
||||||
|
"--nrar <hex> specify nonce / answer as 8 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "lf hitag lookup [-h] [-f <fn>] [-k <hex>] -u <hex> [--nr <hex>] [--ar <hex>] [--nrar <hex>]"
|
||||||
|
},
|
||||||
"lf hitag read": {
|
"lf hitag read": {
|
||||||
"command": "lf hitag read",
|
"command": "lf hitag read",
|
||||||
"description": "Read Hitag memory Crypto mode key format: ISK high + ISK low",
|
"description": "Read Hitag memory. It support HitagS and Hitag 2 Password mode: - default key 4D494B52 (MIKR) Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)",
|
||||||
"notes": [
|
"notes": [
|
||||||
"Hitag S, plain mode",
|
"lf hitag read --hts -> HitagS, plain mode",
|
||||||
"lf hitag read --hts",
|
"lf hitag read --hts --nrar 0102030411223344 -> HitagS, challenge mode",
|
||||||
"Hitag S, challenge mode",
|
"lf hitag read --hts --crypto -> HitagS, crypto mode, def key",
|
||||||
"lf hitag read --hts --nrar 0102030411223344",
|
"lf hitag read --hts -k 4F4E4D494B52 -> HitagS, crypto mode",
|
||||||
"Hitag S, crypto mode => use default key 4F4E4D494B52 (ONMIKR)",
|
|
||||||
"lf hitag read --hts --crypto",
|
|
||||||
"Hitag S, long key = crypto mode",
|
|
||||||
"lf hitag read --hts -k 4F4E4D494B52",
|
|
||||||
"",
|
"",
|
||||||
"Hitag 2, password mode => use default key 4D494B52 (MIKR)",
|
"lf hitag read --ht2 --pwd -> Hitag 2, pwd mode, def key",
|
||||||
"lf hitag read --ht2 --pwd",
|
"lf hitag read --ht2 -k 4D494B52 -> Hitag 2, pwd mode",
|
||||||
"Hitag 2, providing a short key = password mode",
|
"lf hitag read --ht2 --nrar 0102030411223344 -> Hitag 2, challenge mode",
|
||||||
"lf hitag read --ht2 -k 4D494B52",
|
"lf hitag read --ht2 --crypto -> Hitag 2, crypto mode, def key",
|
||||||
"Hitag 2, challenge mode",
|
"lf hitag read --ht2 -k 4F4E4D494B52 -> Hitag 2, crypto mode"
|
||||||
"lf hitag read --ht2 --nrar 0102030411223344",
|
|
||||||
"Hitag 2, crypto mode => use default key 4F4E4D494B52 (ONMIKR)",
|
|
||||||
"lf hitag read --ht2 --crypto",
|
|
||||||
"Hitag 2, providing a long key = crypto mode",
|
|
||||||
"lf hitag read --ht2 -k 4F4E4D494B52"
|
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -9552,6 +9576,18 @@
|
||||||
],
|
],
|
||||||
"usage": "lf hitag read [-hs2] [--pwd] [--nrar <hex>] [--crypto] [-k <hex>]"
|
"usage": "lf hitag read [-hs2] [--pwd] [--nrar <hex>] [--crypto] [-k <hex>]"
|
||||||
},
|
},
|
||||||
|
"lf hitag selftest": {
|
||||||
|
"command": "lf hitag selftest",
|
||||||
|
"description": "Perform selftest of Hitag crypto engine",
|
||||||
|
"notes": [
|
||||||
|
"lf hitag selftest"
|
||||||
|
],
|
||||||
|
"offline": true,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help"
|
||||||
|
],
|
||||||
|
"usage": "lf hitag selftest [-h]"
|
||||||
|
},
|
||||||
"lf hitag sim": {
|
"lf hitag sim": {
|
||||||
"command": "lf hitag sim",
|
"command": "lf hitag sim",
|
||||||
"description": "Simulate Hitag transponder You need to `lf hitag eload` first",
|
"description": "Simulate Hitag transponder You need to `lf hitag eload` first",
|
||||||
|
@ -9595,27 +9631,18 @@
|
||||||
},
|
},
|
||||||
"lf hitag wrbl": {
|
"lf hitag wrbl": {
|
||||||
"command": "lf hitag wrbl",
|
"command": "lf hitag wrbl",
|
||||||
"description": "Write a page in Hitag memory Crypto mode key format: ISK high + ISK low",
|
"description": "Write a page in Hitag memory. It support HitagS and Hitag 2 Password mode: - default key 4D494B52 (MIKR) Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)",
|
||||||
"notes": [
|
"notes": [
|
||||||
"Hitag S, plain mode",
|
"lf hitag wrbl --hts -p 6 -d 01020304 -> HitagS, plain mode",
|
||||||
"lf hitag wrbl --hts -p 6 -d 01020304",
|
"lf hitag wrbl --hts -p 6 -d 01020304 --nrar 0102030411223344 -> HitagS, challenge mode",
|
||||||
"Hitag S, challenge mode",
|
"lf hitag wrbl --hts -p 6 -d 01020304 --crypto -> HitagS, crypto mode, def key",
|
||||||
"lf hitag wrbl --hts --nrar 0102030411223344 -p 6 -d 01020304",
|
"lf hitag wrbl --hts -p 6 -d 01020304 -k 4F4E4D494B52 -> HitagS, crypto mode",
|
||||||
"Hitag S, crypto mode => use default key 4F4E4D494B52 (ONMIKR)",
|
|
||||||
"lf hitag wrbl --hts --crypto -p 6 -d 01020304",
|
|
||||||
"Hitag S, long key = crypto mode",
|
|
||||||
"lf hitag wrbl --hts -k 4F4E4D494B52 -p 6 -d 01020304",
|
|
||||||
"",
|
"",
|
||||||
"Hitag 2, password mode => use default key 4D494B52 (MIKR)",
|
"lf hitag wrbl --ht2 -p 6 -d 01020304 --pwd -> Hitag 2, pwd mode, def key",
|
||||||
"lf hitag wrbl --ht2 --pwd -p 6 -d 01020304",
|
"lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4D494B52 -> Hitag 2, pwd mode",
|
||||||
"Hitag 2, providing a short key = password mode",
|
"lf hitag wrbl --ht2 -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag 2, challenge mode",
|
||||||
"lf hitag wrbl --ht2 -k 4D494B52 -p 6 -d 01020304",
|
"lf hitag wrbl --ht2 -p 6 -d 01020304 --crypto -> Hitag 2, crypto mode, def key",
|
||||||
"Hitag 2, challenge mode",
|
"lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag 2, crypto mode"
|
||||||
"lf hitag wrbl --ht2 --nrar 0102030411223344 -p 6 -d 01020304",
|
|
||||||
"Hitag 2, crypto mode => use default key 4F4E4D494B52 (ONMIKR)",
|
|
||||||
"lf hitag wrbl --ht2 --crypto -p 6 -d 01020304",
|
|
||||||
"Hitag 2, providing a long key = crypto mode",
|
|
||||||
"lf hitag wrbl --ht2 -k 4F4E4D494B52 -p 6 -d 01020304"
|
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -12595,8 +12622,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 727,
|
"commands_extracted": 729,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2024-04-07T09:37:51"
|
"extracted_on": "2024-04-22T14:35:02"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,15 @@ Check column "offline" for their availability.
|
||||||
|command |offline |description
|
|command |offline |description
|
||||||
|------- |------- |-----------
|
|------- |------- |-----------
|
||||||
|`data help `|Y |`This help`
|
|`data help `|Y |`This help`
|
||||||
|
|`data clear `|Y |`Clears various buffers used by the graph window`
|
||||||
|
|`data hide `|Y |`Hide the graph window`
|
||||||
|
|`data load `|Y |`Load contents of file into graph window`
|
||||||
|
|`data num `|Y |`Converts dec/hex/bin`
|
||||||
|
|`data plot `|Y |`Show the graph window`
|
||||||
|
|`data print `|Y |`Print the data in the DemodBuffer`
|
||||||
|
|`data save `|Y |`Save signal trace data`
|
||||||
|
|`data setdebugmode `|Y |`Set Debugging Level on client side`
|
||||||
|
|`data xor `|Y |`Xor a input string`
|
||||||
|`data biphaserawdecode `|Y |`Biphase decode bin stream in DemodBuffer`
|
|`data biphaserawdecode `|Y |`Biphase decode bin stream in DemodBuffer`
|
||||||
|`data detectclock `|Y |`Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer`
|
|`data detectclock `|Y |`Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer`
|
||||||
|`data fsktonrz `|Y |`Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)`
|
|`data fsktonrz `|Y |`Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk)`
|
||||||
|
@ -102,43 +111,32 @@ Check column "offline" for their availability.
|
||||||
|`data rawdemod `|Y |`Demodulate the data in the GraphBuffer and output binary`
|
|`data rawdemod `|Y |`Demodulate the data in the GraphBuffer and output binary`
|
||||||
|`data askedgedetect `|Y |`Adjust Graph for manual ASK demod`
|
|`data askedgedetect `|Y |`Adjust Graph for manual ASK demod`
|
||||||
|`data autocorr `|Y |`Autocorrelation over window`
|
|`data autocorr `|Y |`Autocorrelation over window`
|
||||||
|
|`data convertbitstream `|Y |`Convert GraphBuffer's 0/1 values to 127 / -127`
|
||||||
|
|`data cthreshold `|Y |`Average out all values between`
|
||||||
|`data dirthreshold `|Y |`Max rising higher up-thres/ Min falling lower down-thres`
|
|`data dirthreshold `|Y |`Max rising higher up-thres/ Min falling lower down-thres`
|
||||||
|`data decimate `|Y |`Decimate samples`
|
|`data decimate `|Y |`Decimate samples`
|
||||||
|`data envelope `|Y |`Generate square envelope of samples`
|
|`data envelope `|Y |`Generate square envelope of samples`
|
||||||
|`data undecimate `|Y |`Un-decimate samples`
|
|`data grid `|Y |`overlay grid on graph window`
|
||||||
|`data hide `|Y |`Hide graph window`
|
|`data getbitstream `|Y |`Convert GraphBuffer's >=1 values to 1 and <1 to 0`
|
||||||
|`data hpf `|Y |`Remove DC offset from trace`
|
|`data hpf `|Y |`Remove DC offset from trace`
|
||||||
|`data iir `|Y |`Apply IIR buttersworth filter on plot data`
|
|`data iir `|Y |`Apply IIR buttersworth filter on plot data`
|
||||||
|`data grid `|Y |`overlay grid on graph window`
|
|
||||||
|`data ltrim `|Y |`Trim samples from left of trace`
|
|`data ltrim `|Y |`Trim samples from left of trace`
|
||||||
|`data mtrim `|Y |`Trim out samples from the specified start to the specified stop`
|
|`data mtrim `|Y |`Trim out samples from the specified start to the specified stop`
|
||||||
|`data norm `|Y |`Normalize max/min to +/-128`
|
|`data norm `|Y |`Normalize max/min to +/-128`
|
||||||
|`data plot `|Y |`Show graph window`
|
|
||||||
|`data cthreshold `|Y |`Average out all values between`
|
|
||||||
|`data rtrim `|Y |`Trim samples from right of trace`
|
|`data rtrim `|Y |`Trim samples from right of trace`
|
||||||
|`data setgraphmarkers `|Y |`Set blue and orange marker in graph window`
|
|`data setgraphmarkers `|Y |`Set the markers in the graph window`
|
||||||
|`data shiftgraphzero `|Y |`Shift 0 for Graphed wave + or - shift value`
|
|`data shiftgraphzero `|Y |`Shift 0 for Graphed wave + or - shift value`
|
||||||
|`data timescale `|Y |`Set cursor display timescale`
|
|`data timescale `|Y |`Set cursor display timescale`
|
||||||
|
|`data undecimate `|Y |`Un-decimate samples`
|
||||||
|`data zerocrossings `|Y |`Count time between zero-crossings`
|
|`data zerocrossings `|Y |`Count time between zero-crossings`
|
||||||
|`data convertbitstream `|Y |`Convert GraphBuffer's 0/1 values to 127 / -127`
|
|
||||||
|`data getbitstream `|Y |`Convert GraphBuffer's >=1 values to 1 and <1 to 0`
|
|
||||||
|`data asn1 `|Y |`ASN1 decoder`
|
|`data asn1 `|Y |`ASN1 decoder`
|
||||||
|`data atr `|Y |`ATR lookup`
|
|`data atr `|Y |`ATR lookup`
|
||||||
|`data bin2hex `|Y |`Converts binary to hexadecimal`
|
|
||||||
|`data bitsamples `|N |`Get raw samples as bitstring`
|
|`data bitsamples `|N |`Get raw samples as bitstring`
|
||||||
|`data bmap `|Y |`Convert hex value according a binary template`
|
|`data bmap `|Y |`Convert hex value according a binary template`
|
||||||
|`data clear `|Y |`Clears bigbuf on deviceside and graph window`
|
|
||||||
|`data crypto `|Y |`Encrypt and decrypt data`
|
|`data crypto `|Y |`Encrypt and decrypt data`
|
||||||
|`data diff `|Y |`Diff of input files`
|
|`data diff `|Y |`Diff of input files`
|
||||||
|`data hexsamples `|N |`Dump big buffer as hex bytes`
|
|`data hexsamples `|N |`Dump big buffer as hex bytes`
|
||||||
|`data hex2bin `|Y |`Converts hexadecimal to binary`
|
|
||||||
|`data load `|Y |`Load contents of file into graph window`
|
|
||||||
|`data num `|Y |`Converts dec/hex/bin`
|
|
||||||
|`data print `|Y |`Print the data in the DemodBuffer`
|
|
||||||
|`data samples `|N |`Get raw samples for graph window ( GraphBuffer )`
|
|`data samples `|N |`Get raw samples for graph window ( GraphBuffer )`
|
||||||
|`data save `|Y |`Save signal trace data ( GraphBuffer )`
|
|
||||||
|`data setdebugmode `|Y |`Set Debugging Level on client side`
|
|
||||||
|`data xor `|Y |`Xor a input string`
|
|
||||||
|
|
||||||
|
|
||||||
### emv
|
### emv
|
||||||
|
@ -857,9 +855,10 @@ Check column "offline" for their availability.
|
||||||
|command |offline |description
|
|command |offline |description
|
||||||
|------- |------- |-----------
|
|------- |------- |-----------
|
||||||
|`lf awid help `|Y |`this help`
|
|`lf awid help `|Y |`this help`
|
||||||
|
|`lf awid brute `|N |`bruteforce card number against reader`
|
||||||
|
|`lf awid clone `|N |`clone AWID tag to T55x7, Q5/T5555 or EM4305/4469`
|
||||||
|`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer`
|
|`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer`
|
||||||
|`lf awid reader `|N |`attempt to read and extract tag data`
|
|`lf awid reader `|N |`attempt to read and extract tag data`
|
||||||
|`lf awid clone `|N |`clone AWID tag to T55x7, Q5/T5555 or EM4305/4469`
|
|
||||||
|`lf awid sim `|N |`simulate AWID tag`
|
|`lf awid sim `|N |`simulate AWID tag`
|
||||||
|`lf awid brute `|N |`bruteforce card number against reader`
|
|`lf awid brute `|N |`bruteforce card number against reader`
|
||||||
|`lf awid watch `|N |`continuously watch for cards. Reader mode`
|
|`lf awid watch `|N |`continuously watch for cards. Reader mode`
|
||||||
|
@ -923,7 +922,7 @@ Check column "offline" for their availability.
|
||||||
|`lf em 4x05 help `|Y |`This help`
|
|`lf em 4x05 help `|Y |`This help`
|
||||||
|`lf em 4x05 clonehelp `|N |`Shows the available clone commands`
|
|`lf em 4x05 clonehelp `|N |`Shows the available clone commands`
|
||||||
|`lf em 4x05 brute `|N |`Bruteforce password`
|
|`lf em 4x05 brute `|N |`Bruteforce password`
|
||||||
|`lf em 4x05 chk `|N |`Check passwords from dictionary`
|
|`lf em 4x05 chk `|N |`Check passwords`
|
||||||
|`lf em 4x05 config `|Y |`Create common configuration words`
|
|`lf em 4x05 config `|Y |`Create common configuration words`
|
||||||
|`lf em 4x05 demod `|Y |`Demodulate a EM4x05/EM4x69 tag from the GraphBuffer`
|
|`lf em 4x05 demod `|Y |`Demodulate a EM4x05/EM4x69 tag from the GraphBuffer`
|
||||||
|`lf em 4x05 dump `|N |`Dump EM4x05/EM4x69 tag`
|
|`lf em 4x05 dump `|N |`Dump EM4x05/EM4x69 tag`
|
||||||
|
@ -944,7 +943,7 @@ Check column "offline" for their availability.
|
||||||
|------- |------- |-----------
|
|------- |------- |-----------
|
||||||
|`lf em 4x50 help `|Y |`This help`
|
|`lf em 4x50 help `|Y |`This help`
|
||||||
|`lf em 4x50 brute `|N |`Bruteforce attack to find password`
|
|`lf em 4x50 brute `|N |`Bruteforce attack to find password`
|
||||||
|`lf em 4x50 chk `|N |`Check passwords from dictionary`
|
|`lf em 4x50 chk `|N |`Check passwords`
|
||||||
|`lf em 4x50 dump `|N |`Dump EM4x50 tag`
|
|`lf em 4x50 dump `|N |`Dump EM4x50 tag`
|
||||||
|`lf em 4x50 info `|N |`Tag information`
|
|`lf em 4x50 info `|N |`Tag information`
|
||||||
|`lf em 4x50 login `|N |`Login into EM4x50 tag`
|
|`lf em 4x50 login `|N |`Login into EM4x50 tag`
|
||||||
|
@ -1042,16 +1041,19 @@ Check column "offline" for their availability.
|
||||||
|`lf hitag help `|Y |`This help`
|
|`lf hitag help `|Y |`This help`
|
||||||
|`lf hitag list `|Y |`List Hitag trace history`
|
|`lf hitag list `|Y |`List Hitag trace history`
|
||||||
|`lf hitag info `|N |`Hitag 2 tag information`
|
|`lf hitag info `|N |`Hitag 2 tag information`
|
||||||
|
|`lf hitag selftest `|Y |`Perform self test`
|
||||||
|`lf hitag dump `|N |`Dump Hitag 2 tag`
|
|`lf hitag dump `|N |`Dump Hitag 2 tag`
|
||||||
|`lf hitag read `|N |`Read Hitag memory`
|
|`lf hitag read `|N |`Read Hitag memory`
|
||||||
|
|`lf hitag sniff `|N |`Eavesdrop Hitag communication`
|
||||||
|`lf hitag view `|Y |`Display content from tag dump file`
|
|`lf hitag view `|Y |`Display content from tag dump file`
|
||||||
|`lf hitag wrbl `|N |`Write a block (page) in Hitag memory`
|
|`lf hitag wrbl `|N |`Write a block (page) in Hitag memory`
|
||||||
|`lf hitag sniff `|N |`Eavesdrop Hitag communication`
|
|
||||||
|`lf hitag cc `|N |`Hitag S: test all provided challenges`
|
|
||||||
|`lf hitag ta `|N |`Hitag 2: test all recorded authentications`
|
|
||||||
|`lf hitag eload `|N |`Upload file into emulator memory`
|
|`lf hitag eload `|N |`Upload file into emulator memory`
|
||||||
|`lf hitag eview `|N |`View emulator memory`
|
|`lf hitag eview `|N |`View emulator memory`
|
||||||
|`lf hitag sim `|N |`Simulate Hitag transponder`
|
|`lf hitag sim `|N |`Simulate Hitag transponder`
|
||||||
|
|`lf hitag cc `|N |`Hitag S: test all provided challenges`
|
||||||
|
|`lf hitag chk `|N |`Check keys`
|
||||||
|
|`lf hitag lookup `|Y |`Uses authentication trace to check for key in dictionary file`
|
||||||
|
|`lf hitag ta `|N |`Hitag 2: test all recorded authentications`
|
||||||
|
|
||||||
|
|
||||||
### lf idteck
|
### lf idteck
|
||||||
|
@ -1285,7 +1287,7 @@ Check column "offline" for their availability.
|
||||||
|`lf t55xx wakeup `|N |`Send AOR wakeup command`
|
|`lf t55xx wakeup `|N |`Send AOR wakeup command`
|
||||||
|`lf t55xx write `|N |`Write T55xx block data`
|
|`lf t55xx write `|N |`Write T55xx block data`
|
||||||
|`lf t55xx bruteforce `|N |`Simple bruteforce attack to find password`
|
|`lf t55xx bruteforce `|N |`Simple bruteforce attack to find password`
|
||||||
|`lf t55xx chk `|N |`Check passwords from dictionary/flash`
|
|`lf t55xx chk `|N |`Check passwords`
|
||||||
|`lf t55xx protect `|N |`Password protect tag`
|
|`lf t55xx protect `|N |`Password protect tag`
|
||||||
|`lf t55xx recoverpw `|N |`Try to recover from bad password write from a cloner`
|
|`lf t55xx recoverpw `|N |`Try to recover from bad password write from a cloner`
|
||||||
|`lf t55xx sniff `|Y |`Attempt to recover T55xx commands from sample buffer`
|
|`lf t55xx sniff `|Y |`Attempt to recover T55xx commands from sample buffer`
|
||||||
|
|
|
@ -127,6 +127,17 @@ extern bool g_tearoff_enabled;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// endian change for 48bit
|
||||||
|
#ifndef BSWAP_48
|
||||||
|
#define BSWAP_48(x) \
|
||||||
|
(((uint64_t)(x) << 40) & 0x0000ff0000000000ULL) | \
|
||||||
|
(((uint64_t)(x) << 24) & 0x000000ff00000000ULL) | \
|
||||||
|
(((uint64_t)(x) << 8) & 0x00000000ff000000ULL) | \
|
||||||
|
(((uint64_t)(x) >> 8) & 0x000000000ff0000ULL) | \
|
||||||
|
(((uint64_t)(x) >> 24) & 0x00000000000ff00ULL) | \
|
||||||
|
(((uint64_t)(x) >> 40) & 0x0000000000000ffULL)
|
||||||
|
#endif
|
||||||
|
|
||||||
// endian change for 32bit
|
// endian change for 32bit
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#ifndef BSWAP_32
|
#ifndef BSWAP_32
|
||||||
|
|
|
@ -39,37 +39,28 @@ typedef enum {
|
||||||
RHT2F_UID_ONLY = 26,
|
RHT2F_UID_ONLY = 26,
|
||||||
WHT2F_PASSWORD = 27,
|
WHT2F_PASSWORD = 27,
|
||||||
HT2_LAST_CMD = WHT2F_PASSWORD,
|
HT2_LAST_CMD = WHT2F_PASSWORD,
|
||||||
} hitag_function;
|
} PACKED hitag_function;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t password[4];
|
|
||||||
} PACKED rht2d_password;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
hitag_function cmd;
|
||||||
|
int16_t page;
|
||||||
|
uint8_t data[4];
|
||||||
uint8_t NrAr[8];
|
uint8_t NrAr[8];
|
||||||
uint8_t data[4];
|
|
||||||
} PACKED rht2d_authenticate;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t key[6];
|
uint8_t key[6];
|
||||||
uint8_t data[4];
|
uint8_t pwd[4];
|
||||||
} PACKED rht2d_crypto;
|
|
||||||
|
|
||||||
typedef struct {
|
// Hitag 1 section.
|
||||||
|
// will reuse pwd or key field.
|
||||||
uint8_t key_no;
|
uint8_t key_no;
|
||||||
uint8_t logdata_0[4];
|
uint8_t logdata_0[4];
|
||||||
uint8_t logdata_1[4];
|
uint8_t logdata_1[4];
|
||||||
uint8_t nonce[4];
|
uint8_t nonce[4];
|
||||||
uint8_t key[4];
|
} PACKED lf_hitag_data_t;
|
||||||
} PACKED rht1d_authenticate;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
rht2d_password pwd;
|
|
||||||
rht1d_authenticate ht1auth;
|
|
||||||
rht2d_authenticate auth;
|
|
||||||
rht2d_crypto crypto;
|
|
||||||
} hitag_data;
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int status;
|
||||||
|
uint8_t data[48];
|
||||||
|
} PACKED lf_hitag_crack_response_t;
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Hitag S
|
// Hitag S
|
||||||
|
|
|
@ -81,6 +81,7 @@ def lfsr_feedback(state):
|
||||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||||
^ (state >> 42) ^ (state >> 43) ^ (state >> 46)
|
^ (state >> 42) ^ (state >> 43) ^ (state >> 46)
|
||||||
^ (state >> 47)) & 1)
|
^ (state >> 47)) & 1)
|
||||||
|
|
||||||
def lfsr(state):
|
def lfsr(state):
|
||||||
return (state >> 1) + (lfsr_feedback(state) << 47)
|
return (state >> 1) + (lfsr_feedback(state) << 47)
|
||||||
|
|
||||||
|
@ -99,9 +100,11 @@ def hitag2(state, length=48):
|
||||||
c = 0
|
c = 0
|
||||||
for i in range(0, length):
|
for i in range(0, length):
|
||||||
c = (c << 1) | f20(state)
|
c = (c << 1) | f20(state)
|
||||||
#print '%012x' % state
|
#print ('%012x' % state)
|
||||||
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
|
|
||||||
state = lfsr(state)
|
state = lfsr(state)
|
||||||
|
#print ('%012x' % (int("{0:048b}".format(state)[::-1],2)))
|
||||||
|
#print('%08X %08X' % (c, state))
|
||||||
|
#print('final: %08X %08X' % (c, state))
|
||||||
return c
|
return c
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -111,8 +114,15 @@ if __name__ == "__main__":
|
||||||
uid = int(sys.argv[2], 16)
|
uid = int(sys.argv[2], 16)
|
||||||
n = int(sys.argv[3])
|
n = int(sys.argv[3])
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
nonce = random.randrange(2**32)
|
nonceA = random.randrange(2**32)
|
||||||
state = hitag2_init(key, uid, nonce)
|
stateA = hitag2_init(key, uid, nonceA)
|
||||||
print('%08X %08X' % (nonce, hitag2(state, 32)^0xffffffff))
|
csA = hitag2(stateA, 32) ^ 0xffffffff
|
||||||
|
# print('%08X %08X' % (nonceA, csA))
|
||||||
|
|
||||||
|
nonceB = random.randrange(2**32)
|
||||||
|
stateB = hitag2_init(key, uid, nonceB)
|
||||||
|
csB = hitag2(stateB, 32) ^ 0xffffffff
|
||||||
|
print('./ht2crack5opencl %08X %08X %08X %08X %08X' % (uid, nonceA, csA, nonceB, csB))
|
||||||
|
print('lf hitag lookup --uid %08X --nr %08X --ar %08X --key %012X' % (uid, nonceA, csA, key))
|
||||||
else:
|
else:
|
||||||
print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys.argv[0])
|
print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys.argv[0])
|
||||||
|
|
|
@ -414,6 +414,7 @@ while true; do
|
||||||
if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi
|
if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi
|
||||||
|
|
||||||
echo -e "\n${C_BLUE}Testing LF:${C_NC}"
|
echo -e "\n${C_BLUE}Testing LF:${C_NC}"
|
||||||
|
if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi
|
||||||
if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \
|
if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \
|
||||||
"COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi
|
"COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi
|
||||||
if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi
|
if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue