mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-28 01:53:11 +08:00
Legic: Implemented setup phase for card simulation
This commit is contained in:
parent
2c6c4e5bc6
commit
cd78b00815
2 changed files with 90 additions and 9 deletions
|
@ -302,8 +302,8 @@ static void init_reader(bool clear_mem) {
|
||||||
// The setup consists of a three way handshake:
|
// The setup consists of a three way handshake:
|
||||||
// - Transmit initialisation vector 7 bits
|
// - Transmit initialisation vector 7 bits
|
||||||
// - Receive card type 6 bits
|
// - Receive card type 6 bits
|
||||||
// - Acknowledge frame 6 bits
|
// - Transmit Acknowledge 6 bits
|
||||||
static uint32_t setup_phase_reader(uint8_t iv) {
|
static uint32_t setup_phase(uint8_t iv) {
|
||||||
// init coordination timestamp
|
// init coordination timestamp
|
||||||
last_frame_end = GET_TICKS;
|
last_frame_end = GET_TICKS;
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ void LegicRfInfo(void) {
|
||||||
init_reader(false);
|
init_reader(false);
|
||||||
|
|
||||||
// establish shared secret and detect card type
|
// establish shared secret and detect card type
|
||||||
uint8_t card_type = setup_phase_reader(0x01);
|
uint8_t card_type = setup_phase(0x01);
|
||||||
if(init_card(card_type, &card) != 0) {
|
if(init_card(card_type, &card) != 0) {
|
||||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -435,7 +435,7 @@ void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) {
|
||||||
init_reader(false);
|
init_reader(false);
|
||||||
|
|
||||||
// establish shared secret and detect card type
|
// establish shared secret and detect card type
|
||||||
uint8_t card_type = setup_phase_reader(iv);
|
uint8_t card_type = setup_phase(iv);
|
||||||
if(init_card(card_type, &card) != 0) {
|
if(init_card(card_type, &card) != 0) {
|
||||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -474,7 +474,7 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// establish shared secret and detect card type
|
// establish shared secret and detect card type
|
||||||
uint8_t card_type = setup_phase_reader(iv);
|
uint8_t card_type = setup_phase(iv);
|
||||||
if(init_card(card_type, &card) != 0) {
|
if(init_card(card_type, &card) != 0) {
|
||||||
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
|
@ -321,6 +321,78 @@ static void init_tag() {
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup reader to card connection
|
||||||
|
//
|
||||||
|
// The setup consists of a three way handshake:
|
||||||
|
// - Receive initialisation vector 7 bits
|
||||||
|
// - Transmit card type 6 bits
|
||||||
|
// - Receive Acknowledge 6 bits
|
||||||
|
static int32_t setup_phase(legic_card_select_t *p_card) {
|
||||||
|
uint8_t len = 0;
|
||||||
|
|
||||||
|
// init coordination timestamp
|
||||||
|
last_frame_end = GetCountSspClk();
|
||||||
|
|
||||||
|
// reset prng
|
||||||
|
legic_prng_init(0);
|
||||||
|
|
||||||
|
// wait for iv
|
||||||
|
int32_t iv = rx_frame(&len);
|
||||||
|
if((len != 7) || (iv < 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure prng
|
||||||
|
legic_prng_init(iv);
|
||||||
|
|
||||||
|
// reply with card type
|
||||||
|
switch(p_card->tagtype) {
|
||||||
|
case 0:
|
||||||
|
tx_frame(0x0D, 6);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
tx_frame(0x1D, 6);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
tx_frame(0x3D, 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for ack
|
||||||
|
int32_t ack = rx_frame(&len);
|
||||||
|
if((len != 6) || (ack < 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate data
|
||||||
|
switch(p_card->tagtype) {
|
||||||
|
case 0:
|
||||||
|
if(ack != 0x19) return -1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(ack != 0x39) return -1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(ack != 0x39) return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// During rx the prng is clocked using the variable reader period.
|
||||||
|
// Since rx_frame detects end of frame by detecting a code violation,
|
||||||
|
// the prng is off by one bit period after each rx phase. Hence, tx
|
||||||
|
// code advances the prng by (TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1).
|
||||||
|
// This is not possible for back to back rx, so this quirk reduces
|
||||||
|
// the gap by one period.
|
||||||
|
last_frame_end += TAG_BIT_PERIOD;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Commands are left as an exercise to the reader
|
||||||
|
static int32_t connected_phase(legic_card_select_t *p_card) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Command Line Interface
|
// Command Line Interface
|
||||||
//
|
//
|
||||||
|
@ -342,11 +414,20 @@ void LegicRfSimulate(uint8_t cardtype) {
|
||||||
while(!BUTTON_PRESS()) {
|
while(!BUTTON_PRESS()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// init coordination timestamp
|
// wait for carrier, restart after timeout
|
||||||
last_frame_end = GetCountSspClk();
|
if(!wait_for(RWD_PULSE, GetCountSspClk() + TAG_BIT_PERIOD)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// reset prng
|
// wait for connection, restart on error
|
||||||
legic_prng_init(0);
|
if(setup_phase(&card)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// conection is established, process commands until one fails
|
||||||
|
while(!connected_phase(&card)) {
|
||||||
|
WDT_HIT();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OUT:
|
OUT:
|
||||||
|
|
Loading…
Reference in a new issue