mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge pull request #2402 from secore-ly/hf-14b-sim
Fix ISO 14443-B tag simulation
This commit is contained in:
commit
76b18f944a
3 changed files with 98 additions and 79 deletions
|
@ -7,6 +7,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Changed `intertic.py` - updated and code clean up (@gentilkiwi)
|
- Changed `intertic.py` - updated and code clean up (@gentilkiwi)
|
||||||
- Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier
|
- Added `pm3_tears_for_fears.py` - a ISO14443b tear off script by Pierre Granier
|
||||||
- Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp)
|
- Added new t55xx password (002BCFCF) sniffed from cheap cloner (@davidbeauchamp)
|
||||||
|
- Fixed 'hf 14b sim' - now works (@michi-jung)
|
||||||
|
|
||||||
## [Aurora.4.18589][2024-05-28]
|
## [Aurora.4.18589][2024-05-28]
|
||||||
- Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001)
|
- Fixed the pm3 regressiontests for Hitag2Crack (@iceman1001)
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 4sample
|
// 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_timeout(uint32_t timeout_etu);
|
||||||
static void iso14b_set_maxframesize(uint16_t size);
|
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
|
// Signal field is off with the appropriate LED
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
|
// TR0: min - 1024 cycles = 75.52 us - max 4096 cycles = 302.08 us
|
||||||
|
SpinDelayUs(76);
|
||||||
|
|
||||||
// Modulate BPSK
|
// Modulate BPSK
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_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.
|
// Transmit the response.
|
||||||
for (uint16_t i = 0; i < len;) {
|
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
|
// Put byte into tx holding register as soon as it is ready
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||||
AT91C_BASE_SSC->SSC_THR = response[i++];
|
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};
|
static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
|
||||||
|
|
||||||
uint16_t len, cmdsReceived = 0;
|
uint16_t len, cmdsReceived = 0;
|
||||||
int cardSTATE = SIM_NOFIELD;
|
int cardSTATE = SIM_POWER_OFF;
|
||||||
int vHf = 0; // in mV
|
int vHf = 0; // in mV
|
||||||
|
|
||||||
const tosend_t *ts = get_tosend();
|
const tosend_t *ts = get_tosend();
|
||||||
|
@ -801,16 +807,18 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find reader field
|
// find reader field
|
||||||
if (cardSTATE == SIM_NOFIELD) {
|
|
||||||
|
|
||||||
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
if (vHf > MF_MINFIELDV) {
|
if (vHf > MF_MINFIELDV) {
|
||||||
|
if (cardSTATE == SIM_POWER_OFF) {
|
||||||
cardSTATE = SIM_IDLE;
|
cardSTATE = SIM_IDLE;
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cardSTATE = SIM_POWER_OFF;
|
||||||
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cardSTATE == SIM_NOFIELD) {
|
if (cardSTATE == SIM_POWER_OFF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,75 +828,87 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||||
break;
|
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 )
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && (receivedCmd[2] & 0x08)) {
|
||||||
|
// WUPB
|
||||||
switch (cardSTATE) {
|
switch (cardSTATE) {
|
||||||
//case SIM_NOFIELD:
|
case SIM_IDLE:
|
||||||
case SIM_HALTED:
|
case SIM_READY:
|
||||||
case SIM_IDLE: {
|
case SIM_HALT: {
|
||||||
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SIM_SELECTING: {
|
|
||||||
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||||
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||||
cardSTATE = SIM_WORK;
|
cardSTATE = SIM_READY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIM_HALTING: {
|
case SIM_ACTIVE:
|
||||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
default: {
|
||||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||||
cardSTATE = SIM_HALTED;
|
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIM_ACKNOWLEDGE: {
|
}
|
||||||
TransmitFor14443b_AsTag(encodedOK, encodedOKLen);
|
} else if ((len == 5) && (receivedCmd[0] == ISO14443B_REQB) && !(receivedCmd[2] & 0x08)) {
|
||||||
LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false);
|
// REQB
|
||||||
cardSTATE = SIM_IDLE;
|
switch (cardSTATE) {
|
||||||
|
case SIM_IDLE:
|
||||||
|
case SIM_READY: {
|
||||||
|
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||||
|
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||||
|
cardSTATE = SIM_READY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SIM_WORK: {
|
case SIM_ACTIVE: {
|
||||||
if (len == 7 && receivedCmd[0] == ISO14443B_HALT) {
|
TransmitFor14443b_AsTag(encodedATQB, encodedATQBLen);
|
||||||
cardSTATE = SIM_HALTED;
|
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false);
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SIM_HALT:
|
||||||
default: {
|
default: {
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++cmdsReceived;
|
++cmdsReceived;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,10 @@ void SniffIso14443b(void);
|
||||||
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
|
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
|
||||||
|
|
||||||
// States for 14B SIM command
|
// States for 14B SIM command
|
||||||
#define SIM_NOFIELD 0
|
#define SIM_POWER_OFF 0
|
||||||
#define SIM_IDLE 1
|
#define SIM_IDLE 1
|
||||||
#define SIM_HALTED 2
|
#define SIM_READY 2
|
||||||
#define SIM_SELECTING 3
|
#define SIM_HALT 3
|
||||||
#define SIM_HALTING 4
|
#define SIM_ACTIVE 4
|
||||||
#define SIM_ACKNOWLEDGE 5
|
|
||||||
#define SIM_WORK 6
|
|
||||||
|
|
||||||
#endif /* __ISO14443B_H */
|
#endif /* __ISO14443B_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue