mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -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
107
armsrc/legicrf.c
107
armsrc/legicrf.c
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
18
common/crc.c
18
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) {
|
||||
|
||||
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++) {
|
||||
|
|
|
@ -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
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