mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-14 02:26:59 -07:00
iclass additions
multiple contributors - thanks!
This commit is contained in:
parent
d5810937bd
commit
aa53efc340
13 changed files with 1580 additions and 415 deletions
|
@ -860,11 +860,26 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
ReaderIClass(c->arg[0]);
|
||||
break;
|
||||
case CMD_READER_ICLASS_REPLAY:
|
||||
ReaderIClass_Replay(c->arg[0], c->d.asBytes);
|
||||
ReaderIClass_Replay(c->arg[0], c->d.asBytes);
|
||||
break;
|
||||
case CMD_ICLASS_EML_MEMSET:
|
||||
case CMD_ICLASS_EML_MEMSET:
|
||||
emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_ICLASS_WRITEBLOCK:
|
||||
iClass_WriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
case CMD_ICLASS_READBLOCK:
|
||||
iClass_ReadBlk(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_ICLASS_AUTHENTICATION:
|
||||
iClass_Authentication(c->d.asBytes);
|
||||
break;
|
||||
case CMD_ICLASS_DUMP:
|
||||
iClass_Dump(c->arg[0], c->arg[1], c->arg[2]);
|
||||
break;
|
||||
case CMD_ICLASS_CLONE:
|
||||
iClass_Clone(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CMD_BUFF_CLEAR:
|
||||
|
|
|
@ -149,9 +149,6 @@ void OnSuccess();
|
|||
void OnError(uint8_t reason);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// iso15693.h
|
||||
void RecordRawAdcSamplesIso15693(void);
|
||||
void AcquireRawAdcSamplesIso15693(void);
|
||||
|
@ -167,6 +164,12 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
|||
void ReaderIClass(uint8_t arg0);
|
||||
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
|
||||
void IClass_iso14443A_GetPublic(uint8_t arg0);
|
||||
void iClass_Authentication(uint8_t *MAC);
|
||||
void iClass_WriteBlock(uint8_t blockNo, uint8_t keyType, uint8_t *data);
|
||||
void iClass_ReadBlk(uint8_t blockNo, uint8_t keyType);
|
||||
bool iClass_ReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *readdata);
|
||||
void iClass_Dump(uint8_t blockno, uint8_t numblks, uint8_t keyType);
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t keyType, uint8_t *data);
|
||||
|
||||
// hitag2.h
|
||||
void SnoopHitag(uint32_t type);
|
||||
|
|
285
armsrc/iclass.c
285
armsrc/iclass.c
|
@ -1601,16 +1601,16 @@ void setupIclassReader()
|
|||
|
||||
}
|
||||
|
||||
size_t sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries)
|
||||
bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries)
|
||||
{
|
||||
while(retries-- > 0)
|
||||
{
|
||||
ReaderTransmitIClass(command, cmdsize);
|
||||
if(expected_size == ReaderReceiveIClass(resp)){
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 1;//Error
|
||||
return false;//Error
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1620,14 +1620,17 @@ size_t sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t*
|
|||
* 1 = Got CSN
|
||||
* 2 = Got CSN and CC
|
||||
*/
|
||||
uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||
uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key)
|
||||
{
|
||||
static uint8_t act_all[] = { 0x0a };
|
||||
static uint8_t identify[] = { 0x0c };
|
||||
//static uint8_t identify[] = { 0x0c };
|
||||
static uint8_t identify[] = { 0x0c, 0x00, 0x73, 0x33 };
|
||||
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
static uint8_t readcheck_cc[]= { 0x88, 0x02,};
|
||||
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
if (use_credit_key)
|
||||
readcheck_cc[0] = 0x18;
|
||||
else
|
||||
readcheck_cc[0] = 0x88;
|
||||
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
|
||||
|
@ -1668,6 +1671,9 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
|
|||
|
||||
return read_status;
|
||||
}
|
||||
uint8_t handshakeIclassTag(uint8_t *card_data){
|
||||
return handshakeIclassTag_ext(card_data, false);
|
||||
}
|
||||
|
||||
|
||||
// Reader iClass Anticollission
|
||||
|
@ -1687,6 +1693,9 @@ void ReaderIClass(uint8_t arg0) {
|
|||
uint8_t result_status = 0;
|
||||
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
||||
bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
|
||||
bool use_credit_key = false;
|
||||
if (arg0 & FLAG_ICLASS_READER_CEDITKEY)
|
||||
use_credit_key = true;
|
||||
set_tracing(TRUE);
|
||||
setupIclassReader();
|
||||
|
||||
|
@ -1701,7 +1710,7 @@ void ReaderIClass(uint8_t arg0) {
|
|||
}
|
||||
WDT_HIT();
|
||||
|
||||
read_status = handshakeIclassTag(card_data);
|
||||
read_status = handshakeIclassTag_ext(card_data, use_credit_key);
|
||||
|
||||
if(read_status == 0) continue;
|
||||
if(read_status == 1) result_status = FLAG_ICLASS_READER_CSN;
|
||||
|
@ -1715,11 +1724,10 @@ void ReaderIClass(uint8_t arg0) {
|
|||
if(arg0 & FLAG_ICLASS_READER_CONF)
|
||||
{
|
||||
if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf),card_data+8, 10, 10))
|
||||
{
|
||||
Dbprintf("Failed to dump config block");
|
||||
}else
|
||||
{
|
||||
result_status |= FLAG_ICLASS_READER_CONF;
|
||||
} else {
|
||||
Dbprintf("Failed to dump config block");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1727,10 +1735,9 @@ void ReaderIClass(uint8_t arg0) {
|
|||
if(arg0 & FLAG_ICLASS_READER_AA){
|
||||
if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA),card_data+(8*4), 10, 10))
|
||||
{
|
||||
// Dbprintf("Failed to dump AA block");
|
||||
}else
|
||||
{
|
||||
result_status |= FLAG_ICLASS_READER_AA;
|
||||
} else {
|
||||
//Dbprintf("Failed to dump AA block");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1814,7 +1821,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
|||
//for now replay captured auth (as cc not updated)
|
||||
memcpy(check+5,MAC,4);
|
||||
|
||||
if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
|
||||
if(!sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
|
||||
{
|
||||
Dbprintf("Error: Authentication Fail!");
|
||||
continue;
|
||||
|
@ -1826,7 +1833,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
|||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
|
||||
if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
|
||||
if(!sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
|
||||
{
|
||||
Dbprintf("Dump config (block 1) failed");
|
||||
continue;
|
||||
|
@ -1853,7 +1860,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
|||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
|
||||
if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
|
||||
if(sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
|
||||
{
|
||||
Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
block, resp[0], resp[1], resp[2],
|
||||
|
@ -1904,130 +1911,130 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
|||
LED_A_OFF();
|
||||
}
|
||||
|
||||
//2. Create Read method (cut-down from above) based off responses from 1.
|
||||
// Since we have the MAC could continue to use replay function.
|
||||
//3. Create Write method
|
||||
/*
|
||||
void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_t *MAC) {
|
||||
uint8_t act_all[] = { 0x0a };
|
||||
uint8_t identify[] = { 0x0c };
|
||||
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
|
||||
uint8_t write[] = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uint16_t crc = 0;
|
||||
|
||||
uint8_t* resp = (((uint8_t *)BigBuf) + 3560);
|
||||
void iClass_Authentication(uint8_t *MAC) {
|
||||
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
memcpy(check+5,MAC,4);
|
||||
bool isOK;
|
||||
isOK = sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5);
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
//Dbprintf("isOK %d, Tag response : %02x%02x%02x%02x",isOK,resp[0],resp[1],resp[2],resp[3]);
|
||||
}
|
||||
bool iClass_ReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *readdata) {
|
||||
uint8_t readcmd[] = {keyType, blockNo}; //0x88, 0x00
|
||||
uint8_t resp[8];
|
||||
size_t isOK = 1;
|
||||
|
||||
// Reset trace buffer
|
||||
memset(trace, 0x44, RECV_CMD_OFFSET);
|
||||
traceLen = 0;
|
||||
readcmd[1] = blockNo;
|
||||
isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd),resp, 8, 5);
|
||||
memcpy(readdata,resp,sizeof(resp));
|
||||
|
||||
// Setup SSC
|
||||
FpgaSetupSsc();
|
||||
// Start from off (no field generated)
|
||||
// Signal field is off with the appropriate LED
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
return isOK;
|
||||
}
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
void iClass_ReadBlk(uint8_t blockno, uint8_t keyType) {
|
||||
uint8_t readblockdata[8];
|
||||
bool isOK = false;
|
||||
isOK = iClass_ReadBlock(blockno, keyType, readblockdata);
|
||||
//Dbprintf("read block [%02x] [%02x%02x%02x%02x%02x%02x%02x%02x]",blockNo,readblockdata[0],readblockdata[1],readblockdata[2],readblockdata[3],readblockdata[4],readblockdata[5],readblockdata[6],readblockdata[7]);
|
||||
cmd_send(CMD_ACK,isOK,0,0,readblockdata,8);
|
||||
}
|
||||
|
||||
// Now give it time to spin up.
|
||||
// Signal field is on with the appropriate LED
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||
SpinDelay(200);
|
||||
void iClass_Dump(uint8_t blockno, uint8_t numblks, uint8_t keyType) {
|
||||
uint8_t readblockdata[8];
|
||||
bool isOK = false;
|
||||
uint8_t blkCnt = 0;
|
||||
|
||||
LED_A_ON();
|
||||
|
||||
for(int i=0;i<1;i++) {
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS()) break;
|
||||
|
||||
// Send act_all
|
||||
ReaderTransmitIClass(act_all, 1);
|
||||
// Card present?
|
||||
if(ReaderReceiveIClass(resp)) {
|
||||
ReaderTransmitIClass(identify, 1);
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
// Select card
|
||||
memcpy(&select[1],resp,8);
|
||||
ReaderTransmitIClass(select, sizeof(select));
|
||||
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}
|
||||
// Card selected
|
||||
Dbprintf("Readcheck on Sector 2");
|
||||
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||
if(ReaderReceiveIClass(resp) == 8) {
|
||||
Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}else return;
|
||||
Dbprintf("Authenticate");
|
||||
//for now replay captured auth (as cc not updated)
|
||||
memcpy(check+5,MAC,4);
|
||||
Dbprintf(" AA: %02x %02x %02x %02x",
|
||||
check[5], check[6], check[7],check[8]);
|
||||
ReaderTransmitIClass(check, sizeof(check));
|
||||
if(ReaderReceiveIClass(resp) == 4) {
|
||||
Dbprintf(" AR: %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],resp[3]);
|
||||
}else {
|
||||
Dbprintf("Error: Authentication Fail!");
|
||||
return;
|
||||
}
|
||||
Dbprintf("Write Block");
|
||||
|
||||
//read configuration for max block number
|
||||
read_success=false;
|
||||
read[1]=1;
|
||||
uint8_t *blockno=&read[1];
|
||||
crc = iclass_crc16((char *)blockno,1);
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
while(!read_success){
|
||||
ReaderTransmitIClass(read, sizeof(read));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
read_success=true;
|
||||
mem=resp[5];
|
||||
memory.k16= (mem & 0x80);
|
||||
memory.book= (mem & 0x20);
|
||||
memory.k2= (mem & 0x8);
|
||||
memory.lockauth= (mem & 0x2);
|
||||
memory.keyaccess= (mem & 0x1);
|
||||
|
||||
}
|
||||
}
|
||||
if (memory.k16){
|
||||
cardsize=255;
|
||||
}else cardsize=32;
|
||||
//check card_size
|
||||
|
||||
memcpy(write+1,blockNo,1);
|
||||
memcpy(write+2,data,8);
|
||||
memcpy(write+10,mac,4);
|
||||
while(!send_success){
|
||||
ReaderTransmitIClass(write, sizeof(write));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
write_success=true;
|
||||
}
|
||||
}//
|
||||
}
|
||||
WDT_HIT();
|
||||
BigBuf_free();
|
||||
uint8_t *dataout = BigBuf_malloc(255*8);
|
||||
memset(dataout,0xFF,255*8);
|
||||
if (dataout == NULL){
|
||||
Dbprintf("out of memory");
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
}*/
|
||||
|
||||
for (;blkCnt < numblks; blkCnt++) {
|
||||
isOK = iClass_ReadBlock(blockno+blkCnt, keyType, readblockdata);
|
||||
if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0x33 || readblockdata[2] == 0xBB)) { //try again
|
||||
isOK = iClass_ReadBlock(blockno+blkCnt, keyType, readblockdata);
|
||||
if (!isOK) {
|
||||
Dbprintf("Block %02X failed to read", blkCnt+blockno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(dataout+(blkCnt*8),readblockdata,8);
|
||||
/*Dbprintf("| %02x | %02x%02x%02x%02x%02x%02x%02x%02x |",
|
||||
blockno+blkCnt, readblockdata[0], readblockdata[1], readblockdata[2],
|
||||
readblockdata[3], readblockdata[4], readblockdata[5],
|
||||
readblockdata[6], readblockdata[7]);
|
||||
*/
|
||||
}
|
||||
//return pointer to dump memory in arg3
|
||||
cmd_send(CMD_ACK,isOK,blkCnt,BigBuf_max_traceLen(),0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
BigBuf_free();
|
||||
}
|
||||
|
||||
bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t keyType, uint8_t *data) {
|
||||
uint8_t write[] = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t readblockdata[8];
|
||||
write[1] = blockNo;
|
||||
memcpy(write+2, data, 12); // data + mac
|
||||
uint8_t resp[10];
|
||||
bool isOK;
|
||||
isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),5);
|
||||
//Dbprintf("reply [%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x]",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
|
||||
if (isOK) {
|
||||
isOK = iClass_ReadBlock(blockNo, keyType, readblockdata);
|
||||
//try again
|
||||
if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB))
|
||||
isOK = iClass_ReadBlock(blockNo, keyType, readblockdata);
|
||||
}
|
||||
if (isOK) {
|
||||
//Dbprintf("read block [%02x] [%02x%02x%02x%02x%02x%02x%02x%02x]",blockNo,readblockdata[0],readblockdata[1],readblockdata[2],readblockdata[3],readblockdata[4],readblockdata[5],readblockdata[6],readblockdata[7]);
|
||||
if (memcmp(write+2,readblockdata,sizeof(readblockdata)) != 0){
|
||||
isOK=false;
|
||||
}
|
||||
}
|
||||
return isOK;
|
||||
}
|
||||
|
||||
void iClass_WriteBlock(uint8_t blockNo, uint8_t keyType, uint8_t *data) {
|
||||
bool isOK = iClass_WriteBlock_ext(blockNo, keyType, data);
|
||||
if (isOK){
|
||||
Dbprintf("Write block [%02x] successful",blockNo);
|
||||
} else {
|
||||
Dbprintf("Write block [%02x] failed",blockNo);
|
||||
}
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
}
|
||||
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t keyType, uint8_t *data) {
|
||||
int i;
|
||||
int written = 0;
|
||||
int total_block = (endblock - startblock) + 1;
|
||||
for (i = 0; i < total_block;i++){
|
||||
// block number
|
||||
if (iClass_WriteBlock_ext(i+startblock, keyType, data+(i*12))){
|
||||
Dbprintf("Write block [%02x] successful",i + startblock);
|
||||
written++;
|
||||
} else {
|
||||
if (iClass_WriteBlock_ext(i+startblock, keyType, data+(i*12))){
|
||||
Dbprintf("Write block [%02x] successful",i + startblock);
|
||||
written++;
|
||||
} else {
|
||||
Dbprintf("Write block [%02x] failed",i + startblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (written == total_block)
|
||||
Dbprintf("Clone complete");
|
||||
else
|
||||
Dbprintf("Clone incomplete");
|
||||
|
||||
cmd_send(CMD_ACK,1,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
|
|
@ -557,16 +557,16 @@ int CmdHFSearch(const char *Cmd){
|
|||
PrintAndLog("\nValid ISO14443A Tag Found - Quiting Search\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HF14BInfo(false);
|
||||
if (ans) {
|
||||
PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HFiClassReader("", false, false);
|
||||
if (ans) {
|
||||
PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HF14BInfo(false);
|
||||
if (ans) {
|
||||
PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HF15Reader("", false);
|
||||
if (ans) {
|
||||
PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
|
||||
|
|
1590
client/cmdhficlass.c
1590
client/cmdhficlass.c
File diff suppressed because it is too large
Load diff
|
@ -20,5 +20,11 @@ int CmdHFiClassList(const char *Cmd);
|
|||
int HFiClassReader(const char *Cmd, bool loop, bool verbose);
|
||||
int CmdHFiClassReader(const char *Cmd);
|
||||
int CmdHFiClassReader_Replay(const char *Cmd);
|
||||
int CmdHFiClassReadKeyFile(const char *filename);
|
||||
int CmdHFiClassWriteKeyFile(const char *Cmd);
|
||||
int CmdHFiClass_ReadBlock(const char *Cmd);
|
||||
int CmdHFiClass_WriteBlock(const char *Cmd);
|
||||
int CmdHFiClassCalcEKey(const char *Cmd);
|
||||
int CmdHFiClass_TestMac(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1136,7 +1136,7 @@ static command_t CommandTable[] =
|
|||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
|
|
|
@ -114,9 +114,16 @@ typedef struct {
|
|||
#define CMD_WRITER_LEGIC_RF 0x0389
|
||||
#define CMD_EPA_PACE_COLLECT_NONCE 0x038A
|
||||
|
||||
#define CMD_ICLASS_CLONE 0x0390
|
||||
#define CMD_ICLASS_DUMP 0x0391
|
||||
#define CMD_SNOOP_ICLASS 0x0392
|
||||
#define CMD_SIMULATE_TAG_ICLASS 0x0393
|
||||
#define CMD_READER_ICLASS 0x0394
|
||||
#define CMD_READER_ICLASS_REPLAY 0x0395
|
||||
#define CMD_ICLASS_READBLOCK 0x0396
|
||||
#define CMD_ICLASS_WRITEBLOCK 0x0397
|
||||
#define CMD_ICLASS_EML_MEMSET 0x0398
|
||||
#define CMD_ICLASS_AUTHENTICATION 0x0399
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
|
||||
|
|
|
@ -241,6 +241,27 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
|
|||
//free(cc_nr);
|
||||
return;
|
||||
}
|
||||
void doMAC_N(uint8_t *cc_nr_p,uint8_t cc_nr_size, uint8_t *div_key_p, uint8_t mac[4])
|
||||
{
|
||||
uint8_t *cc_nr;
|
||||
uint8_t div_key[8];
|
||||
cc_nr = (uint8_t*) malloc(cc_nr_size);
|
||||
|
||||
memcpy(cc_nr,cc_nr_p,cc_nr_size);
|
||||
memcpy(div_key,div_key_p,8);
|
||||
|
||||
reverse_arraybytes(cc_nr,cc_nr_size);
|
||||
BitstreamIn bitstream = {cc_nr,cc_nr_size * 8,0};
|
||||
uint8_t dest []= {0,0,0,0,0,0,0,0};
|
||||
BitstreamOut out = { dest, sizeof(dest)*8, 0 };
|
||||
MAC(div_key,bitstream, out);
|
||||
//The output MAC must also be reversed
|
||||
reverse_arraybytes(dest, sizeof(dest));
|
||||
memcpy(mac, dest, 4);
|
||||
free(cc_nr);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
int testMAC()
|
||||
{
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]);
|
||||
void doMAC_N(uint8_t *cc_nr_p,uint8_t cc_nr_size, uint8_t *div_key_p, uint8_t mac[4]);
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
int testMAC();
|
||||
#endif
|
||||
|
|
|
@ -86,11 +86,16 @@ local _commands = {
|
|||
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
|
||||
--//CMD_EPA_ = 0x038B,
|
||||
|
||||
CMD_ICLASS_CLONE = 0x0390,
|
||||
CMD_ICLASS_DUMP = 0x0391,
|
||||
CMD_SNOOP_ICLASS = 0x0392,
|
||||
CMD_SIMULATE_TAG_ICLASS = 0x0393,
|
||||
CMD_READER_ICLASS = 0x0394,
|
||||
CMD_READER_ICLASS_REPLAY = 0x0395,
|
||||
CMD_ICLASS_ISO14443A_WRITE = 0x0397,
|
||||
CMD_READER_ICLASS_REPLAY = 0x0395,
|
||||
CMD_ICLASS_READBLOCK = 0x0396,
|
||||
CMD_ICLASS_WRITEBLOCK = 0x0397,
|
||||
CMD_ICLASS_EML_MEMSET = 0x0398,
|
||||
CMD_ICLASS_AUTHENTICATION = 0x0399,
|
||||
|
||||
--// For measurements of the antenna tuning
|
||||
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
|
||||
|
|
|
@ -74,24 +74,30 @@ void fuse_config(const picopass_hdr *hdr)
|
|||
if( isset( fuses, FUSE_RA)) prnt(" RA: Read access enabled");
|
||||
else prnt(" RA: Read access not enabled");
|
||||
}
|
||||
void mem_config(const picopass_hdr *hdr)
|
||||
void mem_app_config(const picopass_hdr *hdr)
|
||||
{
|
||||
uint8_t mem = hdr->conf.mem_config;
|
||||
if( isset (mem, 0x80)) prnt(" Mem: 16KBits (255 * 8 bytes)");
|
||||
else prnt(" Mem: 2 KBits ( 32 * 8 bytes)");
|
||||
|
||||
}
|
||||
void applimit_config(const picopass_hdr *hdr)
|
||||
{
|
||||
uint8_t applimit = hdr->conf.app_limit;
|
||||
prnt(" AA1: blocks 6-%d", applimit);
|
||||
prnt(" AA2: blocks %d-", (applimit+1));
|
||||
if (applimit < 6) applimit = 26;
|
||||
uint8_t kb=2;
|
||||
uint8_t maxBlk = 32;
|
||||
if( isset(mem, 0x10) && notset(mem, 0x80)){
|
||||
// 2kb default
|
||||
} else if( isset(mem, 0x80) && notset(mem, 0x10)){
|
||||
kb = 16;
|
||||
maxBlk = 255; //16kb
|
||||
} else {
|
||||
kb = 32;
|
||||
maxBlk = 255;
|
||||
}
|
||||
prnt(" Mem: %u KBits ( %u * 8 bytes) [%02X]", kb, maxBlk, mem);
|
||||
prnt(" AA1: blocks 06-%02X", applimit);
|
||||
prnt(" AA2: blocks %02X-%02X", (applimit+1), (hdr->conf.mem_config));
|
||||
}
|
||||
void print_picopass_info(const picopass_hdr *hdr)
|
||||
{
|
||||
fuse_config(hdr);
|
||||
mem_config(hdr);
|
||||
applimit_config(hdr);
|
||||
mem_app_config(hdr);
|
||||
}
|
||||
void printIclassDumpInfo(uint8_t* iclass_dump)
|
||||
{
|
||||
|
|
|
@ -128,12 +128,16 @@ typedef struct{
|
|||
#define CMD_EPA_PACE_COLLECT_NONCE 0x038A
|
||||
#define CMD_EPA_PACE_REPLAY 0x038B
|
||||
|
||||
#define CMD_ICLASS_CLONE 0x0390
|
||||
#define CMD_ICLASS_DUMP 0x0391
|
||||
#define CMD_SNOOP_ICLASS 0x0392
|
||||
#define CMD_SIMULATE_TAG_ICLASS 0x0393
|
||||
#define CMD_READER_ICLASS 0x0394
|
||||
#define CMD_READER_ICLASS_REPLAY 0x0395
|
||||
#define CMD_ICLASS_ISO14443A_WRITE 0x0397
|
||||
#define CMD_ICLASS_READBLOCK 0x0396
|
||||
#define CMD_ICLASS_WRITEBLOCK 0x0397
|
||||
#define CMD_ICLASS_EML_MEMSET 0x0398
|
||||
#define CMD_ICLASS_AUTHENTICATION 0x0399
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
|
||||
|
@ -204,6 +208,7 @@ typedef struct{
|
|||
#define FLAG_ICLASS_READER_CONF 0x08
|
||||
#define FLAG_ICLASS_READER_AA 0x10
|
||||
#define FLAG_ICLASS_READER_ONE_TRY 0x20
|
||||
#define FLAG_ICLASS_READER_CEDITKEY 0x40
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue