FIX: increased the timeout, to make 'hf mf chk' work better.
frame_clean(¤t_frame);
frame_receive_rwd(¤t_frame, 6, 1);
frame_clean(¤t_frame);
frame_receive_rwd(¤t_frame, 6, 1);
- legic_prng_forward(1); /* we wait anyways */
+ legic_prng_forward(3); /* we wait anyways */
while(timer->TC_CV < 387) ; /* ~ 258us */
while(timer->TC_CV < 387) ; /* ~ 258us */
- frame_send_rwd(0x19, 6);
+ frame_send_rwd(0x39, 6);
return current_frame.data;
}
return current_frame.data;
}
int legic_read_byte(int byte_index, int cmd_sz) {
int byte;
int legic_read_byte(int byte_index, int cmd_sz) {
int byte;
- legic_prng_forward(4); /* we wait anyways */
while(timer->TC_CV < 387) ; /* ~ 258us + 100us*delay */
frame_send_rwd(1 | (byte_index << 1), cmd_sz);
while(timer->TC_CV < 387) ; /* ~ 258us + 100us*delay */
frame_send_rwd(1 | (byte_index << 1), cmd_sz);
+ legic_prng_forward(4); /* we wait anyways */
|(0x00 <<0)); //CMD = W
uint32_t cmd_sz = addr_sz+1+8+4; //crc+data+cmd
|(0x00 <<0)); //CMD = W
uint32_t cmd_sz = addr_sz+1+8+4; //crc+data+cmd
- legic_prng_forward(4); /* we wait anyways */
+ legic_prng_forward(2); /* we wait anyways */
while(timer->TC_CV < 387) ; /* ~ 258us */
frame_send_rwd(cmd, cmd_sz);
while(timer->TC_CV < 387) ; /* ~ 258us */
frame_send_rwd(cmd, cmd_sz);
int c = t/TAG_TIME_BIT;
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1) ; /* Wait till the clock has reset */
int c = t/TAG_TIME_BIT;
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1) ; /* Wait till the clock has reset */
- legic_prng_forward(c-1);
-int LegicRfReader(int offset, int bytes) {
+int LegicRfReader(int offset, int bytes, int iv) {
// ice_legic_setup();
// ice_legic_select_card();
// ice_legic_setup();
// ice_legic_select_card();
int byte_index=0, cmd_sz=0, card_sz=0;
int byte_index=0, cmd_sz=0, card_sz=0;
+ iv = (iv <= 0 ) ? SESSION_IV : iv;
+
LegicCommonInit();
uint8_t *BigBuf = BigBuf_get_addr();
memset(BigBuf, 0, 1024);
DbpString("setting up legic card");
LegicCommonInit();
uint8_t *BigBuf = BigBuf_get_addr();
memset(BigBuf, 0, 1024);
DbpString("setting up legic card");
- uint32_t tag_type = perform_setup_phase_rwd(SESSION_IV);
+ uint32_t tag_type = perform_setup_phase_rwd(iv);
switch_off_tag_rwd(); //we lose to mutch time with dprintf
switch(tag_type) {
case 0x0d:
switch_off_tag_rwd(); //we lose to mutch time with dprintf
switch(tag_type) {
case 0x0d:
if(bytes+offset >= card_sz)
bytes = card_sz-offset;
if(bytes+offset >= card_sz)
bytes = card_sz-offset;
- perform_setup_phase_rwd(SESSION_IV);
+ perform_setup_phase_rwd(iv);
+
+ legic_prng_forward(2);
LED_B_ON();
while(byte_index < bytes) {
LED_B_ON();
while(byte_index < bytes) {
-/*int _LegicRfWriter(int bytes, int offset, int addr_sz, uint8_t *BigBuf, int RoundBruteforceValue) {
+/*int _LegicRfWriter(int offset, int bytes, int addr_sz, uint8_t *BigBuf, int RoundBruteforceValue) {
int byte_index=0;
LED_B_ON();
int byte_index=0;
LED_B_ON();
-void LegicRfWriter(int bytes, int offset) {
+void LegicRfWriter(int offset, int bytes, int iv) {
+
int byte_index=0, addr_sz=0;
uint8_t *BigBuf = BigBuf_get_addr();
int byte_index=0, addr_sz=0;
uint8_t *BigBuf = BigBuf_get_addr();
+ iv = (iv <=0 ) ? SESSION_IV : iv;
LegicCommonInit();
DbpString("setting up legic card");
LegicCommonInit();
DbpString("setting up legic card");
- uint32_t tag_type = perform_setup_phase_rwd(SESSION_IV);
+ uint32_t tag_type = perform_setup_phase_rwd(iv);
switch_off_tag_rwd();
switch(tag_type) {
case 0x0d:
switch_off_tag_rwd();
switch(tag_type) {
case 0x0d:
- perform_setup_phase_rwd(SESSION_IV);
-
+ perform_setup_phase_rwd(iv);
while(byte_index < bytes) {
int r;
while(byte_index < bytes) {
int r;
-void LegicRfRawWriter(int offset, int byte) {
+void LegicRfRawWriter(int address, int byte, int iv) {
int byte_index=0, addr_sz=0;
int byte_index=0, addr_sz=0;
+
+ iv = (iv <= 0) ? SESSION_IV : iv;
LegicCommonInit();
DbpString("setting up legic card");
LegicCommonInit();
DbpString("setting up legic card");
- uint32_t tag_type = perform_setup_phase_rwd(SESSION_IV);
+ uint32_t tag_type = perform_setup_phase_rwd(iv);
switch_off_tag_rwd();
switch(tag_type) {
case 0x0d:
switch_off_tag_rwd();
switch(tag_type) {
case 0x0d:
- if(offset > 22) {
- Dbprintf("Error: can not write to 0x%03.3x on MIM22", offset);
+ if(address > 22) {
+ Dbprintf("Error: can not write to 0x%03.3x on MIM22", address);
- Dbprintf("MIM22 card found, writing at addr 0x%02.2x - value 0x%02.2x ...", offset, byte);
+ Dbprintf("MIM22 card found, writing at addr 0x%02.2x - value 0x%02.2x ...", address, byte);
- if(offset > 0x100) {
- Dbprintf("Error: can not write to 0x%03.3x on MIM256", offset);
+ if(address > 0x100) {
+ Dbprintf("Error: can not write to 0x%03.3x on MIM256", address);
- Dbprintf("MIM256 card found, writing at addr 0x%02.2x - value 0x%02.2x ...", offset, byte);
+ Dbprintf("MIM256 card found, writing at addr 0x%02.2x - value 0x%02.2x ...", address, byte);
- if(offset > 0x400) {
- Dbprintf("Error: can not write to 0x%03.3x on MIM1024", offset);
+ if(address > 0x400) {
+ Dbprintf("Error: can not write to 0x%03.3x on MIM1024", address);
- Dbprintf("MIM1024 card found, writing at addr 0x%03.3x - value 0x%03.3x ...", offset, byte);
+ Dbprintf("MIM1024 card found, writing at addr 0x%03.3x - value 0x%03.3x ...", address, byte);
break;
default:
Dbprintf("No or unknown card found, aborting");
return;
}
break;
default:
Dbprintf("No or unknown card found, aborting");
return;
}
- Dbprintf("integer value: %d offset: %d addr_sz: %d", byte, offset, addr_sz);
+ Dbprintf("integer value: %d address: %d addr_sz: %d", byte, address, addr_sz);
- perform_setup_phase_rwd(SESSION_IV);
+ perform_setup_phase_rwd(iv);
- int r = legic_write_byte(byte, offset, addr_sz);
+ int r = legic_write_byte(byte, address, addr_sz);
if((r != 0) || BUTTON_PRESS()) {
Dbprintf("operation aborted @ 0x%03.3x (%1d)", byte_index, r);
if((r != 0) || BUTTON_PRESS()) {
Dbprintf("operation aborted @ 0x%03.3x (%1d)", byte_index, r);
/* First Part of Handshake (IV) */
if(f->bits == 7) {
/* First Part of Handshake (IV) */
if(f->bits == 7) {
- if(f->data == SESSION_IV) {
+// if(f->data == SESSION_IV) {
LED_C_ON();
prng_timer->TC_CCR = AT91C_TC_SWTRG;
legic_prng_init(f->data);
LED_C_ON();
prng_timer->TC_CCR = AT91C_TC_SWTRG;
legic_prng_init(f->data);
while(timer->TC_CV > 1);
while(timer->TC_CV < 280);
return;
while(timer->TC_CV > 1);
while(timer->TC_CV < 280);
return;
- } else if((prng_timer->TC_CV % 50) > 40) {
- legic_prng_init(f->data);
- frame_send_tag(0x3d, 6, 1);
- SpinDelay(20);
- return;
- }
+// } else if((prng_timer->TC_CV % 50) > 40) {
+// legic_prng_init(f->data);
+// frame_send_tag(0x3d, 6, 1);
+// SpinDelay(20);
+// return;
+// }
}
/* 0x19==??? */
if(legic_state == STATE_IV) {
}
/* 0x19==??? */
if(legic_state == STATE_IV) {
- if((f->bits == 6) && (f->data == (0x19 ^ get_key_stream(1, 6)))) {
+ int local_key = get_key_stream(3, 6);
+ int xored = 0x39 ^ local_key;
+ if((f->bits == 6) && (f->data == xored)) {
legic_state = STATE_CON;
/* TIMEOUT */
legic_state = STATE_CON;
/* TIMEOUT */
} else {
legic_state = STATE_DISCON;
LED_C_OFF();
} else {
legic_state = STATE_DISCON;
LED_C_OFF();
- Dbprintf("0x19 - Frame: %03.3x", f->data);
+ Dbprintf("iv: %02x frame: %02x key: %02x xored: %02x", legic_prng_iv, f->data, local_key, xored);
/* Read */
if(f->bits == 11) {
if(legic_state == STATE_CON) {
/* Read */
if(f->bits == 11) {
if(legic_state == STATE_CON) {
- int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
+ int key = get_key_stream(2, 11); //legic_phase_drift, 11);
int addr = f->data ^ key; addr = addr >> 1;
int data = BigBuf[addr];
int hash = LegicCRC(addr, data, 11) << 8;
int addr = f->data ^ key; addr = addr >> 1;
int data = BigBuf[addr];
int hash = LegicCRC(addr, data, 11) << 8;
/* SHORT TIMEOUT */
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1);
/* SHORT TIMEOUT */
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1);
- legic_prng_forward(legic_frame_drift);
while(timer->TC_CV < 180);
return;
}
while(timer->TC_CV < 180);
return;
}
* seems to be 300us-ish.
*/
* seems to be 300us-ish.
*/
- if(phase < 0) {
- int i;
- for(i=0; i<=reqresp; i++) {
- legic_prng_init(SESSION_IV);
- Dbprintf("i=%u, key 0x%3.3x", i, get_key_stream(i, frame));
- }
- return;
- }
+// if(phase < 0) {
+// int i;
+// for(i=0; i<=reqresp; i++) {
+// legic_prng_init(SESSION_IV);
+// Dbprintf("i=%u, key 0x%3.3x", i, get_key_stream(i, frame));
+// }
+// return;
+// }
legic_phase_drift = phase;
legic_frame_drift = frame;
legic_phase_drift = phase;
legic_frame_drift = frame;
#define __LEGICRF_H
extern void LegicRfSimulate(int phase, int frame, int reqresp);
#define __LEGICRF_H
extern void LegicRfSimulate(int phase, int frame, int reqresp);
-extern int LegicRfReader(int bytes, int offset);
-extern void LegicRfWriter(int bytes, int offset);
-extern void LegicRfRawWriter(int offset, int bytes);
+extern int LegicRfReader(int offset, int bytes, int iv);
+extern void LegicRfWriter(int offset, int bytes, int iv);
+extern void LegicRfRawWriter(int address, int data, int iv);
int ice_legic_select_card();
void ice_legic_setup();
int ice_legic_select_card();
void ice_legic_setup();
// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on \r
// Computer and Communications Security, 2015\r
//-----------------------------------------------------------------------------\r
// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on \r
// Computer and Communications Security, 2015\r
//-----------------------------------------------------------------------------\r
-#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)\r
+#define AUTHENTICATION_TIMEOUT 1000 //848 // card times out 1ms after wrong authentication (according to NXP documentation)\r
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication \r
\r
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)\r
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication \r
\r
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)\r