mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
CHG: a select_legic function with structs and stuff and
This commit is contained in:
parent
d7e24e7c5f
commit
a39944216d
7 changed files with 132 additions and 95 deletions
119
armsrc/legicrf.c
119
armsrc/legicrf.c
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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){
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
20
common/crc.c
20
common/crc.c
|
@ -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++) {
|
||||||
|
|
|
@ -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
26
include/legic.h
Normal 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_
|
Loading…
Add table
Add a link
Reference in a new issue