CHG: a select_legic function with structs and stuff and

This commit is contained in:
iceman1001 2016-09-29 12:23:09 +02:00
commit a39944216d
7 changed files with 132 additions and 95 deletions

View file

@ -10,7 +10,7 @@
#include "legicrf.h" #include "legicrf.h"
static struct legic_frame { static struct legic_frame {
int bits; uint8_t bits;
uint32_t data; uint32_t data;
} current_frame; } current_frame;
@ -426,7 +426,7 @@ static uint32_t legic4Crc(uint8_t legicCmd, uint16_t byte_index, uint8_t value,
int legic_read_byte(int byte_index, int cmd_sz) { int legic_read_byte(int byte_index, int cmd_sz) {
uint8_t byte = 0, crc = 0, calcCrc = 0; uint8_t byte = 0; //, crc = 0, calcCrc = 0;
uint32_t cmd = (byte_index << 1) | LEGIC_READ; uint32_t cmd = (byte_index << 1) | LEGIC_READ;
// (us)| ticks // (us)| ticks
@ -440,13 +440,13 @@ int legic_read_byte(int byte_index, int cmd_sz) {
byte = BYTEx(current_frame.data, 0); byte = BYTEx(current_frame.data, 0);
calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); // calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz);
crc = BYTEx(current_frame.data, 1); // crc = BYTEx(current_frame.data, 1);
if( calcCrc != crc ) { // if( calcCrc != crc ) {
Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); // Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc);
return -1; // return -1;
} // }
legic_prng_forward(4); legic_prng_forward(4);
WaitTicks(40); WaitTicks(40);
@ -526,56 +526,37 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) {
int LegicRfReader(int offset, int bytes, int iv) { int LegicRfReader(int offset, int bytes, int iv) {
uint16_t byte_index = 0; uint16_t byte_index = 0;
uint8_t cmd_sz = 0, isOK = 1; uint8_t isOK = 1;
int card_sz = 0; legic_card_select_t card;
LegicCommonInit();
uint32_t tag_type = setup_phase_reader(iv);
LegicCommonInit();
if ( legic_select_card(&card) ) {
isOK = 0;
goto OUT;
}
switch_off_tag_rwd(); switch_off_tag_rwd();
switch(tag_type) {
case 0x0d:
if ( MF_DBGLEVEL >= 2) DbpString("MIM22 card found, reading card");
cmd_sz = 6;
card_sz = 22;
break;
case 0x1d:
if ( MF_DBGLEVEL >= 2) DbpString("MIM256 card found, reading card");
cmd_sz = 9;
card_sz = 256;
break;
case 0x3d:
if ( MF_DBGLEVEL >= 2) DbpString("MIM1024 card found, reading card");
cmd_sz = 11;
card_sz = 1024;
break;
default:
if ( MF_DBGLEVEL >= 1) Dbprintf("Unknown card format: %x", tag_type);
isOK = 0;
goto OUT;
break;
}
if (bytes == -1) if (bytes == -1)
bytes = card_sz; bytes = card.cardsize;
if (bytes + offset >= card_sz) if (bytes + offset >= card.cardsize)
bytes = card_sz - offset; bytes = card.cardsize - offset;
// Start setup and read bytes. // Start setup and read bytes.
setup_phase_reader(iv); setup_phase_reader(iv);
LED_B_ON(); LED_B_ON();
while (byte_index < bytes) { while (byte_index < bytes) {
int r = legic_read_byte(byte_index + offset, cmd_sz); int r = legic_read_byte(byte_index + offset, card.cmdsize);
if (r == -1 || BUTTON_PRESS()) { if (r == -1 || BUTTON_PRESS()) {
if ( MF_DBGLEVEL >= 3) DbpString("operation aborted"); if ( MF_DBGLEVEL >= 3) DbpString("operation aborted");
isOK = 0; isOK = 0;
goto OUT; goto OUT;
} }
cardmem[++byte_index] = r; cardmem[byte_index++] = r;
WDT_HIT(); WDT_HIT();
} }
@ -765,47 +746,61 @@ void LegicRfRawWriter(int address, int byte, int iv) {
if ( MF_DBGLEVEL >= 1) DbpString("write successful"); if ( MF_DBGLEVEL >= 1) DbpString("write successful");
} }
void LegicRfInfo(void){ int legic_select_card(legic_card_select_t *p_card){
LegicCommonInit(); if ( p_card == NULL ) return 1;
uint32_t tag_type = setup_phase_reader(0x1);
uint8_t cmd_sz = 0;
uint16_t card_sz = 0;
switch(tag_type) { p_card->tagtype = setup_phase_reader(0x1);
switch(p_card->tagtype) {
case 0x0d: case 0x0d:
cmd_sz = 6; p_card->cmdsize = 6;
card_sz = 22; p_card->cardsize = 22;
break; break;
case 0x1d: case 0x1d:
cmd_sz = 9; p_card->cmdsize = 9;
card_sz = 256; p_card->cardsize = 256;
break; break;
case 0x3d: case 0x3d:
cmd_sz = 11; p_card->cmdsize = 11;
card_sz = 1024; p_card->cardsize = 1024;
break; break;
default: default:
cmd_send(CMD_ACK,0,0,0,0,0); p_card->cmdsize = 0;
goto OUT; p_card->cardsize = 0;
return 2;
break;
}
return 0;
}
void LegicRfInfo(void){
uint8_t buf[sizeof(legic_card_select_t)] = {0x00};
legic_card_select_t *card = (legic_card_select_t*) buf;
LegicCommonInit();
if ( legic_select_card(card) ) {
cmd_send(CMD_ACK,0,0,0,0,0);
goto OUT;
} }
// read UID bytes. // read UID bytes.
uint8_t uid[] = {0,0,0,0}; for ( uint8_t i = 0; i < sizeof(card->uid); ++i) {
for ( uint8_t i = 0; i < sizeof(uid); ++i) { int r = legic_read_byte(i, card->cmdsize);
int r = legic_read_byte(i, cmd_sz);
if ( r == -1 ) { if ( r == -1 ) {
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
goto OUT; goto OUT;
} }
uid[i] = r & 0xFF; card->uid[i] = r & 0xFF;
} }
cmd_send(CMD_ACK,1,card_sz,0,uid,sizeof(uid)); cmd_send(CMD_ACK, 1 ,0 , 0, buf, sizeof(legic_card_select_t));
OUT:
OUT:
switch_off_tag_rwd(); switch_off_tag_rwd();
LEDsoff(); LEDsoff();
} }
/* Handle (whether to respond) a frame in tag mode /* Handle (whether to respond) a frame in tag mode

View file

@ -1,4 +1,4 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch> // (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
// //
// This code is licensed to you under the terms of the GNU GPL, version 2 or, // This code is licensed to you under the terms of the GNU GPL, version 2 or,
@ -18,6 +18,7 @@
#include "legic_prng.h" // legic PRNG impl #include "legic_prng.h" // legic PRNG impl
#include "crc.h" // legic crc-4 #include "crc.h" // legic crc-4
#include "ticks.h" // timers #include "ticks.h" // timers
#include "legic.h" // legic_card_select_t struct
extern void LegicRfSimulate(int phase, int frame, int reqresp); extern void LegicRfSimulate(int phase, int frame, int reqresp);
extern int LegicRfReader(int offset, int bytes, int iv); extern int LegicRfReader(int offset, int bytes, int iv);
@ -29,7 +30,7 @@ uint32_t get_key_stream(int skip, int count);
void frame_send_tag(uint16_t response, uint8_t bits, uint8_t crypt); void frame_send_tag(uint16_t response, uint8_t bits, uint8_t crypt);
void frame_sendAsReader(uint32_t data, uint8_t bits); void frame_sendAsReader(uint32_t data, uint8_t bits);
int ice_legic_select_card(); int legic_select_card(legic_card_select_t *p_card);
void ice_legic_setup(); void ice_legic_setup();
#endif /* __LEGICRF_H */ #endif /* __LEGICRF_H */

View file

@ -11,7 +11,6 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
#define SESSION_IV 0x55
#define MAX_LENGTH 1024 #define MAX_LENGTH 1024
int usage_legic_calccrc8(void){ int usage_legic_calccrc8(void){
@ -400,16 +399,21 @@ int CmdLegicRFRead(const char *Cmd) {
sscanf(Cmd, "%x %x %x", &offset, &len, &IV); sscanf(Cmd, "%x %x %x", &offset, &len, &IV);
// OUT-OF-BOUNDS check // OUT-OF-BOUNDS check
if(len + offset > MAX_LENGTH) len = MAX_LENGTH - offset; if ( len + offset > MAX_LENGTH ) {
len = MAX_LENGTH - offset;
PrintAndLog("Out-of-bound, shorten len to %d",len);
}
if ( (IV & 0x7F) != IV ){ if ( (IV & 0x7F) != IV ){
IV &= 0x7F; IV &= 0x7F;
PrintAndLog("Truncating IV to 7bits"); PrintAndLog("Truncating IV to 7bits");
} }
if ( (IV & 1) == 0 ){ if ( (IV & 1) == 0 ){
IV |= 0x01; // IV must be odd IV |= 0x01;
PrintAndLog("LSB of IV must be SET"); PrintAndLog("LSB of IV must be SET");
} }
PrintAndLog("Using IV: 0x%02x", IV); PrintAndLog("Using IV: 0x%02x", IV);
UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}}; UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}};
@ -818,28 +822,31 @@ int HFLegicInfo(const char *Cmd, bool verbose) {
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 500)) {
uint8_t isOK = resp.arg[0] & 0xFF;
uint16_t tagtype = resp.arg[1] & 0xFFF;
if ( isOK ) {
PrintAndLog(" UID : %s", sprint_hex(resp.d.asBytes, 4));
switch(tagtype) {
case 22: PrintAndLog("MIM22 card (22bytes)"); break;
case 256: PrintAndLog("MIM256 card (256bytes)"); break;
case 1024: PrintAndLog("MIM1024 card (1024bytes)"); break;
default: {
PrintAndLog("Unknown card format: %x", tagtype);
return 1;
}
}
} else {
if ( verbose ) PrintAndLog("legic card select failed");
return 1;
}
} else {
if ( verbose ) PrintAndLog("command execution time out"); if ( verbose ) PrintAndLog("command execution time out");
return 1; return 1;
} }
uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) {
if ( verbose ) PrintAndLog("legic card select failed");
return 1;
}
legic_card_select_t card;
memcpy(&card, (legic_card_select_t *)resp.d.asBytes, sizeof(legic_card_select_t));
PrintAndLog(" UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
switch(card.cardsize) {
case 22:
case 256:
case 1024:
PrintAndLog(" TYPE : MIM%d card (%d bytes)", card.cardsize, card.cardsize); break;
default: {
PrintAndLog("Unknown card format: %d", card.cardsize);
return 1;
}
}
return 0; return 0;
} }
int CmdLegicInfo(const char *Cmd){ int CmdLegicInfo(const char *Cmd){

View file

@ -21,6 +21,7 @@
#include "util.h" #include "util.h"
#include "crc.h" #include "crc.h"
#include "legic_prng.h" #include "legic_prng.h"
#include "legic.h" // legic_card_select_t struct
int CmdHFLegic(const char *Cmd); int CmdHFLegic(const char *Cmd);

View file

@ -29,6 +29,7 @@ void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, u
} }
void crc_clear(crc_t *crc) { void crc_clear(crc_t *crc) {
crc->state = crc->initial_value & crc->mask; crc->state = crc->initial_value & crc->mask;
if (crc->refin) if (crc->refin)
crc->state = reflect(crc->state, crc->order); crc->state = reflect(crc->state, crc->order);
@ -36,26 +37,33 @@ void crc_clear(crc_t *crc) {
void crc_update(crc_t *crc, uint32_t indata, int data_width){ void crc_update(crc_t *crc, uint32_t indata, int data_width){
uint32_t poly = crc->polynom;
// if requested, return the initial CRC */
if (indata == 0)
return crc->initial_value;
//reflected //reflected
if (crc->refin) indata = reflect(indata, data_width); if (crc->refin)
indata = reflect(indata, data_width);
// Bring the next byte into the remainder. // Bring the next byte into the remainder.
crc->state ^= indata << (crc->order - data_width); crc->state ^= indata << (crc->order - data_width);
for( uint8_t bit = data_width; bit > 0; --bit) { for( uint8_t bit = data_width; bit > 0; --bit) {
// Try to divide the current data bit. // Try to divide the current data bit.
if (crc->state & crc->topbit) if (crc->state & crc->topbit)
crc->state = (crc->state << 1) ^ crc->polynom; crc->state = (crc->state << 1) ^ poly;
else else
crc->state = (crc->state << 1); crc->state = (crc->state << 1);
} }
return crc ^ model->xorout;
} }
void crc_update2(crc_t *crc, uint32_t data, int data_width) void crc_update2(crc_t *crc, uint32_t data, int data_width)
{ {
if (crc->refin) data = reflect(data, data_width); if (crc->refin)
data = reflect(data, data_width);
int i; int i;
for(i=0; i<data_width; i++) { for(i=0; i<data_width; i++) {

View file

@ -31,7 +31,7 @@ typedef struct {
uint8_t mem_config; //[13] uint8_t mem_config; //[13]
uint8_t eas; //[14] uint8_t eas; //[14]
uint8_t fuses; //[15] uint8_t fuses; //[15]
}picopass_conf_block; } picopass_conf_block;
typedef struct { typedef struct {
@ -41,8 +41,7 @@ typedef struct {
uint8_t key_d[8]; uint8_t key_d[8];
uint8_t key_c[8]; uint8_t key_c[8];
uint8_t app_issuer_area[8]; uint8_t app_issuer_area[8];
} picopass_hdr;
}picopass_hdr;
uint8_t isset(uint8_t val, uint8_t mask) { uint8_t isset(uint8_t val, uint8_t mask) {
return (val & mask); return (val & mask);

26
include/legic.h Normal file
View file

@ -0,0 +1,26 @@
//-----------------------------------------------------------------------------
// (c) 2016 Iceman
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// LEGIC type prototyping
//-----------------------------------------------------------------------------
#ifndef _LEGIC_H_
#define _LEGIC_H_
#include "common.h"
//-----------------------------------------------------------------------------
// LEGIC
//-----------------------------------------------------------------------------
typedef struct {
uint8_t uid[4];
uint32_t tagtype;
uint8_t cmdsize;
uint16_t cardsize;
} legic_card_select_t;
#endif // _LEGIC_H_