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"
static struct legic_frame {
int bits;
uint8_t bits;
uint32_t data;
} 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) {
uint8_t byte = 0, crc = 0, calcCrc = 0;
uint8_t byte = 0; //, crc = 0, calcCrc = 0;
uint32_t cmd = (byte_index << 1) | LEGIC_READ;
// (us)| ticks
@ -440,13 +440,13 @@ int legic_read_byte(int byte_index, int cmd_sz) {
byte = BYTEx(current_frame.data, 0);
calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz);
crc = BYTEx(current_frame.data, 1);
// calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz);
// crc = BYTEx(current_frame.data, 1);
if( calcCrc != crc ) {
Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc);
return -1;
}
// if( calcCrc != crc ) {
// Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc);
// return -1;
// }
legic_prng_forward(4);
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) {
uint16_t byte_index = 0;
uint8_t cmd_sz = 0, isOK = 1;
int card_sz = 0;
uint8_t isOK = 1;
legic_card_select_t card;
LegicCommonInit();
uint32_t tag_type = setup_phase_reader(iv);
if ( legic_select_card(&card) ) {
isOK = 0;
goto OUT;
}
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)
bytes = card_sz;
bytes = card.cardsize;
if (bytes + offset >= card_sz)
bytes = card_sz - offset;
if (bytes + offset >= card.cardsize)
bytes = card.cardsize - offset;
// Start setup and read bytes.
setup_phase_reader(iv);
LED_B_ON();
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 ( MF_DBGLEVEL >= 3) DbpString("operation aborted");
isOK = 0;
goto OUT;
}
cardmem[++byte_index] = r;
cardmem[byte_index++] = r;
WDT_HIT();
}
@ -765,47 +746,61 @@ void LegicRfRawWriter(int address, int byte, int iv) {
if ( MF_DBGLEVEL >= 1) DbpString("write successful");
}
void LegicRfInfo(void){
int legic_select_card(legic_card_select_t *p_card){
LegicCommonInit();
uint32_t tag_type = setup_phase_reader(0x1);
uint8_t cmd_sz = 0;
uint16_t card_sz = 0;
if ( p_card == NULL ) return 1;
switch(tag_type) {
p_card->tagtype = setup_phase_reader(0x1);
switch(p_card->tagtype) {
case 0x0d:
cmd_sz = 6;
card_sz = 22;
p_card->cmdsize = 6;
p_card->cardsize = 22;
break;
case 0x1d:
cmd_sz = 9;
card_sz = 256;
p_card->cmdsize = 9;
p_card->cardsize = 256;
break;
case 0x3d:
cmd_sz = 11;
card_sz = 1024;
p_card->cmdsize = 11;
p_card->cardsize = 1024;
break;
default:
p_card->cmdsize = 0;
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.
uint8_t uid[] = {0,0,0,0};
for ( uint8_t i = 0; i < sizeof(uid); ++i) {
int r = legic_read_byte(i, cmd_sz);
for ( uint8_t i = 0; i < sizeof(card->uid); ++i) {
int r = legic_read_byte(i, card->cmdsize);
if ( r == -1 ) {
cmd_send(CMD_ACK,0,0,0,0,0);
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:
switch_off_tag_rwd();
LEDsoff();
}
/* Handle (whether to respond) a frame in tag mode

View file

@ -1,4 +1,4 @@
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
//
// 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 "crc.h" // legic crc-4
#include "ticks.h" // timers
#include "legic.h" // legic_card_select_t struct
extern void LegicRfSimulate(int phase, int frame, int reqresp);
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_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();
#endif /* __LEGICRF_H */

View file

@ -11,7 +11,6 @@
static int CmdHelp(const char *Cmd);
#define SESSION_IV 0x55
#define MAX_LENGTH 1024
int usage_legic_calccrc8(void){
@ -400,16 +399,21 @@ int CmdLegicRFRead(const char *Cmd) {
sscanf(Cmd, "%x %x %x", &offset, &len, &IV);
// 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 ){
IV &= 0x7F;
PrintAndLog("Truncating IV to 7bits");
}
if ( (IV & 1) == 0 ){
IV |= 0x01; // IV must be odd
IV |= 0x01;
PrintAndLog("LSB of IV must be SET");
}
PrintAndLog("Using IV: 0x%02x", IV);
UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}};
@ -818,28 +822,31 @@ int HFLegicInfo(const char *Cmd, bool verbose) {
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
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);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 500)) {
if ( verbose ) PrintAndLog("command execution time out");
return 1;
}
}
} else {
uint8_t isOK = resp.arg[0] & 0xFF;
if ( !isOK ) {
if ( verbose ) PrintAndLog("legic card select failed");
return 1;
}
} else {
if ( verbose ) PrintAndLog("command execution time out");
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;
}
int CmdLegicInfo(const char *Cmd){

View file

@ -21,6 +21,7 @@
#include "util.h"
#include "crc.h"
#include "legic_prng.h"
#include "legic.h" // legic_card_select_t struct
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) {
crc->state = crc->initial_value & crc->mask;
if (crc->refin)
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){
uint32_t poly = crc->polynom;
// if requested, return the initial CRC */
if (indata == 0)
return crc->initial_value;
//reflected
if (crc->refin) indata = reflect(indata, data_width);
if (crc->refin)
indata = reflect(indata, data_width);
// Bring the next byte into the remainder.
crc->state ^= indata << (crc->order - data_width);
for( uint8_t bit = data_width; bit > 0; --bit) {
// Try to divide the current data bit.
if (crc->state & crc->topbit)
crc->state = (crc->state << 1) ^ crc->polynom;
crc->state = (crc->state << 1) ^ poly;
else
crc->state = (crc->state << 1);
}
return crc ^ model->xorout;
}
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;
for(i=0; i<data_width; i++) {

View file

@ -41,7 +41,6 @@ typedef struct {
uint8_t key_d[8];
uint8_t key_c[8];
uint8_t app_issuer_area[8];
} picopass_hdr;
uint8_t isset(uint8_t val, uint8_t 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_