mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'master' into patch-1
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
+11
-1
@@ -3,7 +3,17 @@ 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...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Change `lf hitag info` - now tries to identify different key fob emulators (@iceman1001)
|
||||
- Fixed a bad memory erase (@iceman1001)
|
||||
- Fixed BT serial comms (@iceman1001)
|
||||
- Changed `intertic.py` - updated and code clean up (@gentilkiwi)
|
||||
- Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier
|
||||
- Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp)
|
||||
- Fixed 'hf 14b sim' - now works (@michi-jung)
|
||||
|
||||
## [Aurora.4.18589][2024-05-28]
|
||||
- Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001)
|
||||
- Changed `mem spiffs tree` - adapted to bigbuff and show if empty (@iceman1001)
|
||||
- Changed `lf hitag info` - now tries to identify different key fob emulators (@iceman1001)
|
||||
- Added `lf hitag reader` - act as a Hitag2 reader (@iceman1001)
|
||||
- Fixed `lf hitag crack2` - now works. (@iceman1001)
|
||||
- Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001)
|
||||
|
||||
@@ -41,7 +41,7 @@ void ModInfo(void) {
|
||||
DbpString(" LF EM4100 simulator standalone mode");
|
||||
}
|
||||
|
||||
static uint64_t rev_quads(uint64_t bits) {
|
||||
static uint64_t em4100emul_rev_quads(uint64_t bits) {
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
|
||||
@@ -49,7 +49,7 @@ static uint64_t rev_quads(uint64_t bits) {
|
||||
return result >> 24;
|
||||
}
|
||||
|
||||
static void fill_buff(uint8_t bit) {
|
||||
static void em4100emul_fill_buff(uint8_t bit) {
|
||||
uint8_t *bba = BigBuf_get_addr();
|
||||
memset(bba + em4100emul_buflen, bit, LF_CLOCK / 2);
|
||||
em4100emul_buflen += (LF_CLOCK / 2);
|
||||
@@ -57,7 +57,7 @@ static void fill_buff(uint8_t bit) {
|
||||
em4100emul_buflen += (LF_CLOCK / 2);
|
||||
}
|
||||
|
||||
static void construct_EM410x_emul(uint64_t id) {
|
||||
static void em4100emul_construct_EM410x_emul(uint64_t id) {
|
||||
|
||||
int i, j;
|
||||
int binary[4] = {0, 0, 0, 0};
|
||||
@@ -65,24 +65,24 @@ static void construct_EM410x_emul(uint64_t id) {
|
||||
em4100emul_buflen = 0;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
fill_buff(1);
|
||||
em4100emul_fill_buff(1);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 3; j >= 0; j--, id /= 2)
|
||||
binary[j] = id % 2;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
fill_buff(binary[j]);
|
||||
em4100emul_fill_buff(binary[j]);
|
||||
|
||||
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
|
||||
em4100emul_fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
|
||||
for (j = 0; j < 4; j++)
|
||||
parity[j] ^= binary[j];
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
fill_buff(parity[j]);
|
||||
em4100emul_fill_buff(parity[j]);
|
||||
|
||||
fill_buff(0);
|
||||
em4100emul_fill_buff(0);
|
||||
}
|
||||
|
||||
static void LED_Slot(int i) {
|
||||
@@ -108,8 +108,18 @@ void RunMod(void) {
|
||||
SpinDelay(100);
|
||||
SpinUp(100);
|
||||
LED_Slot(selected);
|
||||
construct_EM410x_emul(rev_quads(em4100emul_low[selected]));
|
||||
Dbprintf("Emulating 0x%010llX", em4100emul_low[selected]);
|
||||
em4100emul_construct_EM410x_emul(em4100emul_rev_quads(em4100emul_low[selected]));
|
||||
SimulateTagLowFrequency(em4100emul_buflen, 0, true);
|
||||
|
||||
//Exit! Button hold break
|
||||
int button_pressed = BUTTON_HELD(500);
|
||||
if (button_pressed == BUTTON_HOLD) {
|
||||
Dbprintf("Button hold, Break!");
|
||||
LEDsoff();
|
||||
Dbprintf("[=] >> LF EM4100 simulator stopped due to button hold <<");
|
||||
return; // RunMod end
|
||||
}
|
||||
selected = (selected + 1) % em4100emul_slots_count;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -101,9 +101,10 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
||||
d += 16;
|
||||
}
|
||||
#endif
|
||||
}void print_result(const char *name, const uint8_t *d, size_t
|
||||
}
|
||||
void print_result(const char *name, const uint8_t *d, size_t
|
||||
|
||||
n) {
|
||||
n) {
|
||||
|
||||
const uint8_t *p = d;
|
||||
uint16_t tmp = n & 0xFFF0;
|
||||
|
||||
+1
-1
@@ -1257,7 +1257,7 @@ static int em4x50_sim_read_bit(void) {
|
||||
|
||||
// wait 16 cycles to make sure there is no field when reading a "0" bit
|
||||
uint32_t waitval = GetTicks();
|
||||
while(GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS);
|
||||
while (GetTicks() - waitval < EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2TICKS);
|
||||
|
||||
while (cycles < EM4X50_T_TAG_THREE_QUARTER_PERIOD) {
|
||||
|
||||
|
||||
+38
-38
@@ -32,47 +32,47 @@ static bool command_parity = true;
|
||||
|
||||
|
||||
#if 1 // Calculation of ticks for timing functions
|
||||
// Conversion from Ticks to RF periods
|
||||
// 1 us = 1.5 ticks
|
||||
// 1RF Period = 8us = 12 Ticks
|
||||
#define TICKS_PER_FC 12
|
||||
// Conversion from Ticks to RF periods
|
||||
// 1 us = 1.5 ticks
|
||||
// 1RF Period = 8us = 12 Ticks
|
||||
#define TICKS_PER_FC 12
|
||||
|
||||
// Chip timing from datasheet
|
||||
// Converted into Ticks for timing functions
|
||||
#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period
|
||||
#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time
|
||||
#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time
|
||||
#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time
|
||||
#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time
|
||||
#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits
|
||||
#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0
|
||||
#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW
|
||||
// Chip timing from datasheet
|
||||
// Converted into Ticks for timing functions
|
||||
#define EM4X70_T_TAG_QUARTER_PERIOD (8 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_HALF_PERIOD (16 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_THREE_QUARTER_PERIOD (24 * TICKS_PER_FC)
|
||||
#define EM4X70_T_TAG_FULL_PERIOD (32 * TICKS_PER_FC) // 1 Bit Period
|
||||
#define EM4X70_T_TAG_TWA (128 * TICKS_PER_FC) // Write Access Time
|
||||
#define EM4X70_T_TAG_DIV (224 * TICKS_PER_FC) // Divergency Time
|
||||
#define EM4X70_T_TAG_AUTH (4224 * TICKS_PER_FC) // Authentication Time
|
||||
#define EM4X70_T_TAG_WEE (3072 * TICKS_PER_FC) // EEPROM write Time
|
||||
#define EM4X70_T_TAG_TWALB (672 * TICKS_PER_FC) // Write Access Time of Lock Bits
|
||||
#define EM4X70_T_TAG_BITMOD (4 * TICKS_PER_FC) // Initial time to stop modulation when sending 0
|
||||
#define EM4X70_T_TAG_TOLERANCE (8 * TICKS_PER_FC) // Tolerance in RF periods for receive/LIW
|
||||
|
||||
#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this
|
||||
#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window
|
||||
#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods)
|
||||
#define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this
|
||||
#define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window
|
||||
#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods)
|
||||
|
||||
#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command
|
||||
#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command
|
||||
#define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command
|
||||
#define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command
|
||||
#endif // Calculation of ticks for timing functions
|
||||
|
||||
#if 1 // EM4x70 Command IDs
|
||||
/**
|
||||
* These IDs are from the EM4170 datasheet.
|
||||
* Some versions of the chip require a
|
||||
* (even) parity bit, others do not.
|
||||
* The command is thus stored only in the
|
||||
* three least significant bits (mask 0x07).
|
||||
*/
|
||||
#define EM4X70_COMMAND_ID 0x01
|
||||
#define EM4X70_COMMAND_UM1 0x02
|
||||
#define EM4X70_COMMAND_AUTH 0x03
|
||||
#define EM4X70_COMMAND_PIN 0x04
|
||||
#define EM4X70_COMMAND_WRITE 0x05
|
||||
#define EM4X70_COMMAND_UM2 0x07
|
||||
/**
|
||||
* These IDs are from the EM4170 datasheet.
|
||||
* Some versions of the chip require a
|
||||
* (even) parity bit, others do not.
|
||||
* The command is thus stored only in the
|
||||
* three least significant bits (mask 0x07).
|
||||
*/
|
||||
#define EM4X70_COMMAND_ID 0x01
|
||||
#define EM4X70_COMMAND_UM1 0x02
|
||||
#define EM4X70_COMMAND_AUTH 0x03
|
||||
#define EM4X70_COMMAND_PIN 0x04
|
||||
#define EM4X70_COMMAND_WRITE 0x05
|
||||
#define EM4X70_COMMAND_UM2 0x07
|
||||
#endif // EM4x70 Command IDs
|
||||
|
||||
// Constants used to determine high/low state of signal
|
||||
@@ -309,7 +309,7 @@ static bool check_ack(void) {
|
||||
// ACK 64 + 64
|
||||
// NAK 64 + 48
|
||||
if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) &&
|
||||
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||
// ACK
|
||||
return true;
|
||||
}
|
||||
@@ -549,8 +549,8 @@ static bool find_listen_window(bool command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// *bits == array of bytes, each byte storing a single bit.
|
||||
// *out == array of bytes, storing converted bits --> bytes.
|
||||
// *bits == array of bytes, each byte storing a single bit.
|
||||
// *out == array of bytes, storing converted bits --> bytes.
|
||||
//
|
||||
// [in, bcount(count_of_bits) ] const uint8_t *bits
|
||||
// [out, bcount(count_of_bits/8)] uint8_t *out
|
||||
|
||||
@@ -380,7 +380,7 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
// We got 42 bits of keystream in c2->keybits.
|
||||
// using the 40 bits of keystream in keybits, sending commands with ever
|
||||
// increasing lengths to acquire 2048 bits of key stream.
|
||||
// increasing lengths to acquire 2048 bits of key stream.
|
||||
int kslen = 40;
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
@@ -409,17 +409,17 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
uint8_t resp[4] = {0};
|
||||
res = ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false);
|
||||
if (res != PM3_SUCCESS) {
|
||||
Dbprintf("tx/rx failed, got %zu (res... %i)", n, res);
|
||||
Dbprintf("tx/rx failed, got %zu (res... %i)", n, res);
|
||||
break;
|
||||
}
|
||||
|
||||
// convert response to binarray
|
||||
// convert response to binarray
|
||||
hex2binarray_n((char *)e_response, (char *)resp, 4);
|
||||
|
||||
// recover keystream from encrypted response
|
||||
hitag2crack_xor(c2->keybits + kslen, e_response, c2->uid, 32);
|
||||
|
||||
// extented with 30 bits or 3 * 10 read_p0_cmds
|
||||
// extented with 30 bits or 3 * 10 read_p0_cmds
|
||||
hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10);
|
||||
kslen += 10;
|
||||
hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10);
|
||||
@@ -437,5 +437,5 @@ void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t));
|
||||
BigBuf_free();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1090,7 +1090,7 @@ static void hitagS_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, ui
|
||||
// Dbprintf("RX0 %i:%02X.. err:%i resptime:%i", *rxlen, rx[0], errorCount, *resptime);
|
||||
}
|
||||
|
||||
static void sendReceiveHitagS( const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) {
|
||||
static void sendReceiveHitagS(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) {
|
||||
|
||||
LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true);
|
||||
|
||||
|
||||
+93
-73
@@ -186,7 +186,7 @@
|
||||
#endif
|
||||
|
||||
// 4sample
|
||||
#define SEND4STUFFBIT(x) tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);tosend_stuffbit(x);
|
||||
#define SEND4STUFFBIT(x) tosend_stuffbit(!(x));tosend_stuffbit(!(x));tosend_stuffbit(!(x));tosend_stuffbit(!(x));
|
||||
|
||||
static void iso14b_set_timeout(uint32_t timeout_etu);
|
||||
static void iso14b_set_maxframesize(uint16_t size);
|
||||
@@ -702,10 +702,11 @@ static void TransmitFor14443b_AsTag(const uint8_t *response, uint16_t len) {
|
||||
// Signal field is off with the appropriate LED
|
||||
LED_D_OFF();
|
||||
|
||||
// TR0: min - 1024 cycles = 75.52 us - max 4096 cycles = 302.08 us
|
||||
SpinDelayUs(76);
|
||||
|
||||
// Modulate BPSK
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
|
||||
AT91C_BASE_SSC->SSC_THR = 0xFF;
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||
|
||||
// Transmit the response.
|
||||
for (uint16_t i = 0; i < len;) {
|
||||
@@ -713,6 +714,11 @@ static void TransmitFor14443b_AsTag(const uint8_t *response, uint16_t len) {
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = response[i++];
|
||||
|
||||
// Start-up SSC once first byte is in SSC_THR
|
||||
if (i == 1) {
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -771,7 +777,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||
static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
|
||||
|
||||
uint16_t len, cmdsReceived = 0;
|
||||
int cardSTATE = SIM_NOFIELD;
|
||||
int cardSTATE = SIM_POWER_OFF;
|
||||
int vHf = 0; // in mV
|
||||
|
||||
const tosend_t *ts = get_tosend();
|
||||
@@ -801,16 +807,18 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||
}
|
||||
|
||||
// find reader field
|
||||
if (cardSTATE == SIM_NOFIELD) {
|
||||
|
||||
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||
if (vHf > MF_MINFIELDV) {
|
||||
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||
if (vHf > MF_MINFIELDV) {
|
||||
if (cardSTATE == SIM_POWER_OFF) {
|
||||
cardSTATE = SIM_IDLE;
|
||||
LED_A_ON();
|
||||
}
|
||||
} else {
|
||||
cardSTATE = SIM_POWER_OFF;
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
if (cardSTATE == SIM_NOFIELD) {
|
||||
if (cardSTATE == SIM_POWER_OFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -820,73 +828,85 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||
break;
|
||||
}
|
||||
|
||||
// ISO14443-B protocol states:
|
||||
// REQ or WUP request in ANY state
|
||||
// WUP in HALTED state
|
||||
if (len == 5) {
|
||||
if (((receivedCmd[0] == ISO14443B_REQB) && ((receivedCmd[2] & 0x08) == 0x08) && (cardSTATE == SIM_HALTED)) ||
|
||||
(receivedCmd[0] == ISO14443B_REQB)) {
|
||||
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
||||
|
||||
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
||||
cardSTATE = SIM_SELECTING;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* How should this flow go?
|
||||
* REQB or WUPB
|
||||
* send response ( waiting for Attrib)
|
||||
* ATTRIB
|
||||
* send response ( waiting for commands 7816)
|
||||
* HALT
|
||||
send halt response ( waiting for wupb )
|
||||
*/
|
||||
|
||||
switch (cardSTATE) {
|
||||
//case SIM_NOFIELD:
|
||||
case SIM_HALTED:
|
||||
case SIM_IDLE: {
|
||||
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
||||
break;
|
||||
}
|
||||
case SIM_SELECTING: {
|
||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_WORK;
|
||||
break;
|
||||
}
|
||||
case SIM_HALTING: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_HALTED;
|
||||
break;
|
||||
}
|
||||
case SIM_ACKNOWLEDGE: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_IDLE;
|
||||
break;
|
||||
}
|
||||
case SIM_WORK: {
|
||||
if (len == 7 && receivedCmd[0] == ISO14443B_HALT) {
|
||||
cardSTATE = SIM_HALTED;
|
||||
} else if (len == 11 && receivedCmd[0] == ISO14443B_ATTRIB) {
|
||||
cardSTATE = SIM_ACKNOWLEDGE;
|
||||
} else {
|
||||
// Todo:
|
||||
// - SLOT MARKER
|
||||
// - ISO7816
|
||||
// - emulate with a memory dump
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived);
|
||||
}
|
||||
|
||||
cardSTATE = SIM_IDLE;
|
||||
if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && (receivedCmd[2] & 0x08)) {
|
||||
// WUPB
|
||||
switch (cardSTATE) {
|
||||
case SIM_IDLE:
|
||||
case SIM_READY:
|
||||
case SIM_HALT: {
|
||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_READY;
|
||||
break;
|
||||
}
|
||||
case SIM_ACTIVE:
|
||||
default: {
|
||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
} else if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && !(receivedCmd[2] & 0x08)) {
|
||||
// REQB
|
||||
switch (cardSTATE) {
|
||||
case SIM_IDLE:
|
||||
case SIM_READY: {
|
||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_READY;
|
||||
break;
|
||||
}
|
||||
case SIM_ACTIVE: {
|
||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||
break;
|
||||
}
|
||||
case SIM_HALT:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ((len == 7) && (receivedCmd[0] == ISO14443B_HALT)) {
|
||||
// HLTB
|
||||
switch (cardSTATE) {
|
||||
case SIM_READY: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_HALT;
|
||||
break;
|
||||
}
|
||||
case SIM_IDLE:
|
||||
case SIM_ACTIVE: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
break;
|
||||
}
|
||||
case SIM_HALT:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (len == 11 && receivedCmd[0] == ISO14443B_ATTRIB) {
|
||||
// ATTRIB
|
||||
switch (cardSTATE) {
|
||||
case SIM_READY: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
cardSTATE = SIM_ACTIVE;
|
||||
break;
|
||||
}
|
||||
case SIM_IDLE:
|
||||
case SIM_ACTIVE: {
|
||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
||||
break;
|
||||
}
|
||||
case SIM_HALT:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -49,12 +49,10 @@ void SniffIso14443b(void);
|
||||
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
|
||||
|
||||
// States for 14B SIM command
|
||||
#define SIM_NOFIELD 0
|
||||
#define SIM_POWER_OFF 0
|
||||
#define SIM_IDLE 1
|
||||
#define SIM_HALTED 2
|
||||
#define SIM_SELECTING 3
|
||||
#define SIM_HALTING 4
|
||||
#define SIM_ACKNOWLEDGE 5
|
||||
#define SIM_WORK 6
|
||||
#define SIM_READY 2
|
||||
#define SIM_HALT 3
|
||||
#define SIM_ACTIVE 4
|
||||
|
||||
#endif /* __ISO14443B_H */
|
||||
|
||||
+23
-9
@@ -134,10 +134,11 @@ void initSampleBuffer(uint32_t *sample_size) {
|
||||
}
|
||||
|
||||
void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
|
||||
|
||||
if (sample_size == NULL) {
|
||||
Dbprintf("initSampleBufferEx, param NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
BigBuf_free_keep_EM();
|
||||
|
||||
// We can't erase the buffer now, it would drastically delay the acquisition
|
||||
@@ -181,14 +182,26 @@ void logSampleSimple(uint8_t sample) {
|
||||
|
||||
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) {
|
||||
|
||||
if (!data.buffer) return;
|
||||
if (!data.buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// keep track of total gather samples regardless how many was discarded.
|
||||
if (samples.counter-- == 0) return;
|
||||
if (samples.counter-- == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bits_per_sample == 0) bits_per_sample = 1;
|
||||
if (bits_per_sample > 8) bits_per_sample = 8;
|
||||
if (decimation == 0) decimation = 1;
|
||||
if (bits_per_sample == 0) {
|
||||
bits_per_sample = 1;
|
||||
}
|
||||
|
||||
if (bits_per_sample > 8) {
|
||||
bits_per_sample = 8;
|
||||
}
|
||||
|
||||
if (decimation == 0) {
|
||||
decimation = 1;
|
||||
}
|
||||
|
||||
if (avg) {
|
||||
samples.sum += sample;
|
||||
@@ -198,7 +211,9 @@ void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool
|
||||
if (decimation > 1) {
|
||||
samples.dec_counter++;
|
||||
|
||||
if (samples.dec_counter < decimation) return;
|
||||
if (samples.dec_counter < decimation) {
|
||||
return;
|
||||
}
|
||||
|
||||
samples.dec_counter = 0;
|
||||
}
|
||||
@@ -538,11 +553,10 @@ int ReadLF_realtime(bool reader_field) {
|
||||
|
||||
return_value = async_usb_write_stop();
|
||||
|
||||
out:
|
||||
out:
|
||||
LED_D_OFF();
|
||||
|
||||
// DoAcquisition() end
|
||||
|
||||
StopTicks();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return return_value;
|
||||
|
||||
+13
-5
@@ -639,24 +639,32 @@ void rdv40_spiffs_safe_print_tree(void) {
|
||||
struct spiffs_dirent e;
|
||||
struct spiffs_dirent *pe = &e;
|
||||
|
||||
char *resolvedlink = (char *)BigBuf_calloc(11 + SPIFFS_OBJ_NAME_LEN);
|
||||
char *linkdest = (char *)BigBuf_calloc(SPIFFS_OBJ_NAME_LEN);
|
||||
bool printed = false;
|
||||
|
||||
SPIFFS_opendir(&fs, "/", &d);
|
||||
while ((pe = SPIFFS_readdir(&d, pe))) {
|
||||
|
||||
char resolvedlink[11 + SPIFFS_OBJ_NAME_LEN];
|
||||
memset(resolvedlink, 0, 11 + SPIFFS_OBJ_NAME_LEN);
|
||||
|
||||
if (rdv40_spiffs_is_symlink((const char *)pe->name)) {
|
||||
char linkdest[SPIFFS_OBJ_NAME_LEN];
|
||||
|
||||
read_from_spiffs((char *)pe->name, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN);
|
||||
sprintf(resolvedlink, "(.lnk) --> %s", linkdest);
|
||||
// Kind of stripping the .lnk extension
|
||||
strtok((char *)pe->name, ".");
|
||||
} else {
|
||||
memset(resolvedlink, 0, sizeof(resolvedlink));
|
||||
}
|
||||
|
||||
Dbprintf("[%04x]\t " _YELLOW_("%i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink);
|
||||
Dbprintf("[%04x] " _YELLOW_("%5i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink);
|
||||
printed = true;
|
||||
}
|
||||
if (printed == false) {
|
||||
DbpString("<empty>");
|
||||
}
|
||||
SPIFFS_closedir(&d);
|
||||
rdv40_spiffs_lazy_mount_rollback(changed);
|
||||
BigBuf_free();
|
||||
}
|
||||
|
||||
void rdv40_spiffs_safe_wipe(void) {
|
||||
|
||||
@@ -307,7 +307,7 @@ E3429281EFC1
|
||||
# EPI Envisionte
|
||||
AAFB06045877
|
||||
#
|
||||
# gym
|
||||
# Gyms / Fitness Clubs / Health Clubs / Wellness Centres
|
||||
#
|
||||
# Fysiken A
|
||||
3E65E4FB65B3
|
||||
@@ -318,8 +318,8 @@ AAFB06045877
|
||||
#
|
||||
# https://mattionline.de/fitnessstudio-armband-reverse-engineering/
|
||||
# https://mattionline.de/milazycracker/
|
||||
# gym wistband A, same as Fysiken A
|
||||
# gym wistband B
|
||||
# Gym Wristband A - Same as Fysiken A
|
||||
# Gym Wristband B
|
||||
81CC25EBBB6A
|
||||
195DC63DB3A3
|
||||
#
|
||||
@@ -330,9 +330,13 @@ A05DBD98E0FC
|
||||
AA4DDA458EBB
|
||||
EAB8066C7479
|
||||
#
|
||||
# Nordic Wellness A, same as Fysiken A
|
||||
# Nordic Wellness A - Same as Fysiken A
|
||||
# Nordic Wellness B
|
||||
E5519E1CC92B
|
||||
#
|
||||
# Jett's 24 Hour Fitness S0 KA/B
|
||||
# 049979614077
|
||||
# 829338771705
|
||||
#
|
||||
# Hotel KeyCard
|
||||
D3B595E9DD63
|
||||
@@ -1110,6 +1114,14 @@ EA0FD73CB149
|
||||
FC0001877BF7
|
||||
FD8705E721B0
|
||||
00ADA2CD516D
|
||||
518108E061E2
|
||||
558AAD64EB5B
|
||||
001122334455
|
||||
6CA761AB6CA7
|
||||
B1C4A8F7F6E3
|
||||
FF75AFDA5A3C
|
||||
FCDDF7767C10
|
||||
A6B3F6C8F1D4
|
||||
#
|
||||
#
|
||||
237A4D0D9119
|
||||
@@ -2345,9 +2357,8 @@ EA0CA627FD06
|
||||
# Hotel key
|
||||
CE0F4F15E909
|
||||
D60DE9436219
|
||||
|
||||
#
|
||||
# ATM Area de Girona, spanish transport card
|
||||
|
||||
A01000000000
|
||||
A02000000000
|
||||
A03000000000
|
||||
@@ -2363,7 +2374,6 @@ A12000000000
|
||||
A13000000000
|
||||
A14000000000
|
||||
A15000000000
|
||||
|
||||
B01000000000
|
||||
B02000000000
|
||||
B03000000000
|
||||
@@ -2379,7 +2389,7 @@ B12000000000
|
||||
B13000000000
|
||||
B14000000000
|
||||
B15000000000
|
||||
|
||||
#
|
||||
# Pittsburgh, PA, USA - Pittsburgh Regional Transit ConnectCard
|
||||
A7AE4A5A33DC
|
||||
6B857B568C10
|
||||
@@ -2413,14 +2423,14 @@ CE8BFF3728EE
|
||||
09938D05DA78
|
||||
EACDA4DBE420
|
||||
EC2B9FD483CA
|
||||
|
||||
#
|
||||
# Hotel Intelier Orange - Benicasim, Spain
|
||||
# block 1 - key A
|
||||
04256CFE0425
|
||||
|
||||
#
|
||||
# InsideWash Membership Card - Portugal
|
||||
C18063858BB9
|
||||
|
||||
#
|
||||
# An apartment building in Sydney Olympic Park
|
||||
13254608D0AB
|
||||
24A2971BC0B2
|
||||
@@ -2454,3 +2464,24 @@ C18063858BB9
|
||||
32B0A529CEC0
|
||||
22345517DFBA
|
||||
33B1A62ACFC1
|
||||
#
|
||||
# Universidade de São Paulo (USP) student card
|
||||
17B50E38F1B0
|
||||
24E311F594CE
|
||||
3794FBFB1A54
|
||||
43B229069F6A
|
||||
4531952F765F
|
||||
4943F2F35E0A
|
||||
4985E681EF88
|
||||
4F56C88E0337
|
||||
710070E92C79
|
||||
8A036C5C35D4
|
||||
A027BD830A06
|
||||
D33673C19243
|
||||
D89A506542F2
|
||||
E5813CD228F1
|
||||
FAB943906E9C
|
||||
#
|
||||
# R.A.T.T transport card key A/B
|
||||
AA034F342A55
|
||||
456776908C48
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
51243648
|
||||
000D8787
|
||||
19920427
|
||||
# White Chinese cloner, circa 2019, firmware v5.04.16.0727 (eBay)
|
||||
002BCFCF
|
||||
# ZX-copy3 T55xx / EM4305
|
||||
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=40662#p40662
|
||||
# default PROX
|
||||
|
||||
@@ -46,6 +46,7 @@ endif()
|
||||
find_package(PkgConfig)
|
||||
|
||||
if (NOT SKIPQT EQUAL 1)
|
||||
|
||||
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||
# Homebrew installs Qt5 (up to at least 5.11.0) in
|
||||
# /usr/local/opt/qt5. Ensure that it can be found by CMake
|
||||
@@ -56,16 +57,17 @@ if (NOT SKIPQT EQUAL 1)
|
||||
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
||||
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
|
||||
endif(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||
if(APPLE AND EXISTS /opt/homebrew/opt/qt5)
|
||||
|
||||
if(APPLE AND EXISTS /opt/homebrew/opt/qt@5)
|
||||
# Homebrew on Apple Silicon installs Qt5 in
|
||||
# /opt/homebrew/opt/qt5. Ensure that it can be found by CMake
|
||||
# /opt/homebrew/opt/qt@5. Ensure that it can be found by CMake
|
||||
# since it is not in the default /usr/local prefix.
|
||||
# Add it to PATHS so that it doesn't override the
|
||||
# CMAKE_PREFIX_PATH environment variable.
|
||||
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
|
||||
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
||||
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /opt/homebrew/opt/qt5)
|
||||
endif(APPLE AND EXISTS /opt/homebrew/opt/qt5)
|
||||
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /opt/homebrew/opt/qt@5)
|
||||
endif(APPLE AND EXISTS /opt/homebrew/opt/qt@5)
|
||||
set(QT_PACKAGELIST
|
||||
Qt5Core
|
||||
Qt5Widgets
|
||||
@@ -262,6 +264,7 @@ set (TARGET_SOURCES
|
||||
${PM3_ROOT}/common/cardhelper.c
|
||||
${PM3_ROOT}/common/generator.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/asn1utils.c
|
||||
${PM3_ROOT}/client/src/crypto/libpcrypto.c
|
||||
@@ -455,7 +458,6 @@ if (APPLE)
|
||||
message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}")
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||
endif()
|
||||
|
||||
endif (APPLE)
|
||||
|
||||
if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||
@@ -675,6 +677,8 @@ if (NOT SKIPPYTHON EQUAL 1)
|
||||
endif (NOT SKIPPYTHON EQUAL 1)
|
||||
message(STATUS "===================================================================")
|
||||
|
||||
add_definitions(-DHAVE_SNPRINTF)
|
||||
|
||||
add_library(pm3rrg_rdv4 SHARED
|
||||
${PM3_ROOT}/client/src/proxmark3.c
|
||||
${TARGET_SOURCES}
|
||||
@@ -733,6 +737,9 @@ target_include_directories(pm3rrg_rdv4 PRIVATE
|
||||
if (NOT APPLE)
|
||||
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
||||
else (NOT APPLE)
|
||||
#set_property(TARGET proxmark3 PROPERTY LINK_FLAGS "-Wl,-undefined dynamic_lookup")
|
||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,-undefined,dynamic_lookup)
|
||||
endif (NOT APPLE)
|
||||
|
||||
if (NOT JANSSON_FOUND)
|
||||
|
||||
@@ -167,12 +167,11 @@ local function help()
|
||||
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
|
||||
print(example)
|
||||
end
|
||||
-- read LEGIC data
|
||||
local function readlegicdata(offset, len, iv)
|
||||
-- read LEGIC info
|
||||
local function readlegicinfo()
|
||||
-- Read data
|
||||
local d0 = ('%04X%04X%02X'):format(offset, len, iv)
|
||||
local c = Command:newNG{cmd = cmds.CMD_HF_LEGIC_READER, data = d0}
|
||||
local result, err = c:sendNG()
|
||||
local c = Command:newNG{cmd = cmds.CMD_HF_LEGIC_INFO, data = nil}
|
||||
local result, err = c:sendNG(false, 2000)
|
||||
if not result then return oops(err) end
|
||||
-- result is a packed data structure, data starts at offset 33
|
||||
return result
|
||||
@@ -404,15 +403,15 @@ local function writeToTag(plainBytes)
|
||||
return
|
||||
end
|
||||
|
||||
readbytes = readlegicdata(0, 4, 0x55)
|
||||
readbytes = readlegicinfo()
|
||||
-- gather MCD & MSN from new Tag - this must be enterd manually
|
||||
print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:")
|
||||
|
||||
-- readbytes is a usbcommandOLD package, hence 32 bytes offset until data.
|
||||
plainBytes[1] = ('%02x'):format(readbytes:byte(33))
|
||||
plainBytes[2] = ('%02x'):format(readbytes:byte(34))
|
||||
plainBytes[3] = ('%02x'):format(readbytes:byte(35))
|
||||
plainBytes[4] = ('%02x'):format(readbytes:byte(36))
|
||||
-- readbytes is a table with uid data as hex string in Data key
|
||||
plainBytes[1] = readbytes.Data:sub(1,2)
|
||||
plainBytes[2] = readbytes.Data:sub(3,4)
|
||||
plainBytes[3] = readbytes.Data:sub(5,6)
|
||||
plainBytes[4] = readbytes.Data:sub(7,8)
|
||||
|
||||
MCD = plainBytes[1]
|
||||
MSN0 = plainBytes[2]
|
||||
|
||||
+290
-136
File diff suppressed because it is too large
Load Diff
+402
-379
File diff suppressed because it is too large
Load Diff
@@ -2284,7 +2284,7 @@
|
||||
"Vendor": "Apple",
|
||||
"Country": "",
|
||||
"Name": "Apple Home Key Framework",
|
||||
"Description": "Home Key configuration applet. Selected after a first transaction on a newely-invited device (allegedly for mailbox sync/attestation exchange)",
|
||||
"Description": "Home Key configuration applet. Used for attestation exchange",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
@@ -2292,7 +2292,39 @@
|
||||
"Vendor": "Apple",
|
||||
"Country": "",
|
||||
"Name": "Apple Home Key",
|
||||
"Description": "NFC Home Key for select HomeKit-compatible locks",
|
||||
"Description": "NFC Home Key for select HomeKit-compatible locks based on Apple UnifiedAccess protocol",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A0000008580202",
|
||||
"Vendor": "Apple",
|
||||
"Country": "",
|
||||
"Name": "Apple Access Key Framework",
|
||||
"Description": "Access Key configuration applet. Used for attestation exchange",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A0000008580201",
|
||||
"Vendor": "Apple",
|
||||
"Country": "",
|
||||
"Name": "Apple Access Key",
|
||||
"Description": "NFC Access Key for commercial properties based on Apple UnifiedAccess protocol",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A000000909ACCE5502",
|
||||
"Vendor": "Connectivity Standards Alliance (CSA)",
|
||||
"Country": "",
|
||||
"Name": "Aliro Framework",
|
||||
"Description": "Used during key provisioning, configuration, attestation exchange",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A000000909ACCE5501",
|
||||
"Vendor": "Connectivity Standards Alliance (CSA)",
|
||||
"Country": "",
|
||||
"Name": "Aliro",
|
||||
"Description": "",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
@@ -2430,5 +2462,13 @@
|
||||
"Name": "CEPAS",
|
||||
"Description": "Transit and e-money card used in Singapore",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A0000004040125",
|
||||
"Vendor": "Ile-de-France Mobilites",
|
||||
"Country": "France",
|
||||
"Name": "Navigo",
|
||||
"Description": "CALYPSO-based transit card",
|
||||
"Type": "transport"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"versions": {
|
||||
"01": {
|
||||
"tci": {
|
||||
"000000": {
|
||||
"id": "tci-vas-or-pay",
|
||||
"name": "VAS or payment",
|
||||
"description": "Used when a reader needs a pass or a payment card. Sometimes called VAS over Payment"
|
||||
},
|
||||
"000001": {
|
||||
"id": "tci-vas-and-pay",
|
||||
"name": "VAS and payment",
|
||||
"description": "Also called single tap mode. Allows reading multiple passes with different ids in one tap"
|
||||
},
|
||||
"000002": {
|
||||
"id": "tci-vas-only",
|
||||
"name": "VAS only",
|
||||
"description": "Used when a reader requests passes only"
|
||||
},
|
||||
"000003": {
|
||||
"id": "tci-pay-only",
|
||||
"name": "VAS only",
|
||||
"description": "Used when a reader requests payment cards only. Also disables express mode for chinese transit cards"
|
||||
},
|
||||
"cf0000": {
|
||||
"id": "tci-ignore",
|
||||
"name": "Ignore",
|
||||
"description": "iPhones before IOS17 emit this frame so that other apple devices don't react to the field"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"02": {
|
||||
"types": {
|
||||
"01": {
|
||||
"id": "terminal-type-transit",
|
||||
"name": "Transit",
|
||||
"description": "Used by express-mode enabled transit terminals",
|
||||
|
||||
"subtypes": {
|
||||
"00": {
|
||||
"id": "terminal-subtype-default",
|
||||
"name": "Default subtype",
|
||||
"description": "",
|
||||
|
||||
"tci": {
|
||||
"030400": {
|
||||
"id": "tci-hop-fastpass",
|
||||
"name": "HOP Fastpass",
|
||||
"description": ""
|
||||
},
|
||||
"030002": {
|
||||
"id": "tci-transit-for-london",
|
||||
"name": "TFL",
|
||||
"description": "First publically known TCI, found by Proxmark community member"
|
||||
},
|
||||
"030001": {
|
||||
"id": "tci-wmata",
|
||||
"name": "SmartTrip",
|
||||
"description": ""
|
||||
},
|
||||
"030005": {
|
||||
"id": "tci-la-tapp",
|
||||
"name": "LA Tap",
|
||||
"description": ""
|
||||
},
|
||||
"030007": {
|
||||
"id": "tci-clipper",
|
||||
"name": "Clipper",
|
||||
"description": ""
|
||||
},
|
||||
"03095a": {
|
||||
"id": "tci-navigo",
|
||||
"name": "Navigo",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
|
||||
"data": {
|
||||
"length": 5,
|
||||
"name": "Fallback EMV payment networks",
|
||||
"description": "Bit mask of allowed EMV open loop payment cards. First byte is responsible for most popular payment networks"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"02": {
|
||||
"id": "terminal-type-access",
|
||||
"name": "Access",
|
||||
"description": "Used by express-mode enabled access and key readers",
|
||||
|
||||
"subtypes": {
|
||||
"00": {
|
||||
"id": "terminal-subtype-venue",
|
||||
"name": "Venue",
|
||||
"description": "Used by following venues: Offices, Parks, Universities",
|
||||
"tci": {
|
||||
"no-info-add-if-found": ""
|
||||
}
|
||||
},
|
||||
"06": {
|
||||
"id": "terminal-subtype-home-key",
|
||||
"name": "Home Key",
|
||||
"description": "Used by home key",
|
||||
"tci": {
|
||||
"021100": {
|
||||
"id": "tci-homekey",
|
||||
"name": "Home Key",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"09": {
|
||||
"id": "terminal-subtype-automotive-pairing",
|
||||
"name": "Automotive",
|
||||
"description": "Used by cars for access and setup",
|
||||
"tci": {
|
||||
"no-info-add-if-found": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,11 @@
|
||||
"name": "Transit: Clipper",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"value": "6a02c8010003095a0000000000",
|
||||
"name": "Transit: Navigo",
|
||||
"description": ""
|
||||
},
|
||||
|
||||
{
|
||||
"value": "6a02c3020002ffff",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user