Merge pull request #101 from marshmellow42/master

hf mfu updates + hf search + bug fixes
This commit is contained in:
Martin Holst Swende 2015-05-22 21:55:34 +02:00
commit 86724c17c9
43 changed files with 3230 additions and 1028 deletions

View file

@ -738,7 +738,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
break; break;
#endif #endif
#ifdef WITH_ISO15693 #ifdef WITH_ISO15693
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693: case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
AcquireRawAdcSamplesIso15693(); AcquireRawAdcSamplesIso15693();
@ -818,25 +818,22 @@ void UsbPacketReceived(uint8_t *packet, int len)
break; break;
case CMD_READER_MIFARE: case CMD_READER_MIFARE:
ReaderMifare(c->arg[0]); ReaderMifare(c->arg[0]);
break; break;
case CMD_MIFARE_READBL: case CMD_MIFARE_READBL:
MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break; break;
case CMD_MIFAREU_READBL: case CMD_MIFAREU_READBL:
MifareUReadBlock(c->arg[0],c->d.asBytes); MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
break; break;
case CMD_MIFAREUC_AUTH1: case CMD_MIFAREUC_AUTH:
MifareUC_Auth1(c->arg[0],c->d.asBytes); MifareUC_Auth(c->arg[0],c->d.asBytes);
break;
case CMD_MIFAREUC_AUTH2:
MifareUC_Auth2(c->arg[0],c->d.asBytes);
break; break;
case CMD_MIFAREU_READCARD: case CMD_MIFAREU_READCARD:
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes); MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break; break;
case CMD_MIFAREUC_READCARD: case CMD_MIFAREUC_SETPWD:
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes); MifareUSetPwd(c->arg[0], c->d.asBytes);
break; break;
case CMD_MIFARE_READSC: case CMD_MIFARE_READSC:
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
@ -846,10 +843,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
break; break;
case CMD_MIFAREU_WRITEBL_COMPAT: case CMD_MIFAREU_WRITEBL_COMPAT:
MifareUWriteBlock(c->arg[0], c->d.asBytes); MifareUWriteBlock(c->arg[0], c->d.asBytes);
break; break;
case CMD_MIFAREU_WRITEBL: case CMD_MIFAREU_WRITEBL:
MifareUWriteBlock_Special(c->arg[0], c->d.asBytes); MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
break; break;
case CMD_MIFARE_NESTED: case CMD_MIFARE_NESTED:
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break; break;

View file

@ -165,10 +165,9 @@ void EPA_PACE_Collect_Nonce(UsbCommand * c);
void ReaderMifare(bool first_try); void ReaderMifare(bool first_try);
int32_t dist_nt(uint32_t nt1, uint32_t nt2); int32_t dist_nt(uint32_t nt1, uint32_t nt2);
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data); void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
void MifareUReadBlock(uint8_t arg0,uint8_t *datain); void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain); void MifareUC_Auth(uint8_t arg0, uint8_t *datain);
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain); void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);
void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain); void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
@ -184,6 +183,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card? void MifareCIdent(); // is "magic chinese" card?
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
//desfire //desfire
void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain); void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);

View file

@ -378,6 +378,60 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
des_dec(out, out, (uint8_t*)key + 0); des_dec(out, out, (uint8_t*)key + 0);
} }
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
if( length % 8 ) return;
uint8_t i;
uint8_t* tin = (uint8_t*) in;
uint8_t* tout = (uint8_t*) out;
while( length > 0 )
{
for ( i = 0; i < 8; i++ )
tout[i] = (unsigned char)(tin[i] ^ iv[i]);
des_enc(tout, tin, (uint8_t*)key + 0);
des_dec(tout, tout, (uint8_t*)key + 8);
des_enc(tout, tout, (uint8_t*)key + 0);
memcpy(iv, tout, 8);
tin += 8;
tout += 8;
length -= 8;
}
}
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
if( length % 8 ) return;
uint8_t i;
unsigned char temp[8];
uint8_t* tin = (uint8_t*) in;
uint8_t* tout = (uint8_t*) out;
while( length > 0 )
{
memcpy(temp, tin, 8);
des_dec(tout, tin, (uint8_t*)key + 0);
des_enc(tout, tout, (uint8_t*)key + 8);
des_dec(tout, tout, (uint8_t*)key + 0);
for (i = 0; i < 8; i++)
tout[i] = (unsigned char)(tout[i] ^ iv[i]);
memcpy(iv, temp, 8);
tin += 8;
tout += 8;
length -= 8;
}
}
/******************************************************************************/ /******************************************************************************/

View file

@ -97,6 +97,9 @@ void tdes_enc(void* out, const void* in, const void* key);
*/ */
void tdes_dec(void* out, const void* in, const void* key); void tdes_dec(void* out, const void* in, const void* key);
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]);
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]);
#endif /*DES_H_*/ #endif /*DES_H_*/
// Copied from des.h in desfire imp. // Copied from des.h in desfire imp.

View file

@ -1677,7 +1677,7 @@ void ReaderIClass(uint8_t arg0) {
uint8_t card_data[6 * 8]={0}; uint8_t card_data[6 * 8]={0};
memset(card_data, 0xFF, sizeof(card_data)); memset(card_data, 0xFF, sizeof(card_data));
uint8_t last_csn[8]={0}; uint8_t last_csn[8]={0};
//Read conf block CRC(0x01) => 0xfa 0x22 //Read conf block CRC(0x01) => 0xfa 0x22
uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22}; uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
@ -1685,16 +1685,18 @@ void ReaderIClass(uint8_t arg0) {
uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64}; uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
int read_status= 0; int read_status= 0;
uint8_t result_status = 0; uint8_t result_status = 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
set_tracing(TRUE); set_tracing(TRUE);
setupIclassReader(); setupIclassReader();
uint16_t tryCnt=0;
while(!BUTTON_PRESS()) while(!BUTTON_PRESS())
{ {
if (try_once && tryCnt > 5) break;
tryCnt++;
if(!tracing) { if(!tracing) {
DbpString("Trace full"); DbpString("Trace full");
break; break;
@ -1761,7 +1763,7 @@ void ReaderIClass(uint8_t arg0) {
} }
LED_B_OFF(); LED_B_OFF();
} }
cmd_send(CMD_ACK,0,0,0,card_data, 0); cmd_send(CMD_ACK,0,0,0,card_data, 0);
LED_A_OFF(); LED_A_OFF();
} }

View file

@ -651,7 +651,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
int ledcontrol = 1; int ledcontrol = 1;
int n=0, i=0; int n=0, i=0;
uint8_t clk = (arg1 >> 8) & 0xFF; uint8_t clk = (arg1 >> 8) & 0xFF;
uint8_t encoding = arg1 & 1; uint8_t encoding = arg1 & 0xFF;
uint8_t separator = arg2 & 1; uint8_t separator = arg2 & 1;
uint8_t invert = (arg2 >> 8) & 1; uint8_t invert = (arg2 >> 8) & 1;

View file

@ -19,6 +19,12 @@
#include "crc.h" #include "crc.h"
// the block number for the ISO14443-4 PCB
uint8_t pcb_blocknum = 0;
// Deselect card by sending a s-block. the crc is precalced for speed
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Select, Authenticate, Read a MIFARE tag. // Select, Authenticate, Read a MIFARE tag.
// read block // read block
@ -86,107 +92,90 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LEDsoff(); LEDsoff();
} }
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){ bool turnOffField = (arg0 == 1);
byte_t isOK = 0; LED_A_ON(); LED_B_OFF(); LED_C_OFF();
byte_t dataoutbuf[16] = {0x00};
uint8_t uid[10] = {0x00};
uint32_t cuid;
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
clear_trace(); clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!iso14443a_select_card(uid, NULL, &cuid)) { if(!iso14443a_select_card(NULL, NULL, NULL)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
Dbprintf("Can't select card"); OnError(0);
//OnError(0);
return; return;
}; };
if(mifare_ultra_auth1(cuid, dataoutbuf)){ if(!mifare_ultra_auth(keybytes)){
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");
Dbprintf("Authentication part1: Fail."); OnError(1);
//OnError(1);
return; return;
} }
isOK = 1; if (turnOffField) {
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
DbpString("AUTH 1 FINISHED"); LEDsoff();
cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);
LEDsoff();
}
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
uint32_t cuid = arg0;
uint8_t key[16] = {0x00};
byte_t isOK = 0;
byte_t dataoutbuf[16] = {0x00};
memcpy(key, datain, 16);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Authentication part2: Fail...");
//OnError(1);
return;
} }
cmd_send(CMD_ACK,1,0,0,0,0);
isOK = 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
DbpString("AUTH 2 FINISHED");
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
} }
void MifareUReadBlock(uint8_t arg0,uint8_t *datain) // Arg0 = BlockNo,
// Arg1 = UsePwd bool
// datain = PWD bytes,
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
{ {
uint8_t blockNo = arg0; uint8_t blockNo = arg0;
byte_t dataout[16] = {0x00}; byte_t dataout[16] = {0x00};
uint8_t uid[10] = {0x00}; bool useKey = (arg1 == 1); //UL_C
uint32_t cuid; bool usePwd = (arg1 == 2); //UL_EV1/NTAG
LEDsoff();
LED_A_ON(); LED_A_ON();
LED_B_OFF();
LED_C_OFF();
clear_trace(); clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid); int len = iso14443a_select_card(NULL, NULL, NULL);
if(!len) { if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
//OnError(1); OnError(1);
return; return;
}; }
len = mifare_ultra_readblock(cuid, blockNo, dataout); // UL-C authentication
if(len) { if ( useKey ) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); uint8_t key[16] = {0x00};
//OnError(2); memcpy(key, datain, sizeof(key) );
if ( !mifare_ultra_auth(key) ) {
OnError(1);
return;
}
}
// UL-EV1 / NTAG authentication
if ( usePwd ) {
uint8_t pwd[4] = {0x00};
memcpy(pwd, datain, 4);
uint8_t pack[4] = {0,0,0,0};
if (!mifare_ul_ev1_auth(pwd, pack)) {
OnError(1);
return;
}
}
if( mifare_ultra_readblock(blockNo, dataout) ) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
OnError(2);
return; return;
}; }
len = mifare_ultra_halt(cuid); if( mifare_ultra_halt() ) {
if(len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); OnError(3);
//OnError(3);
return; return;
}; }
cmd_send(CMD_ACK,1,0,0,dataout,16); cmd_send(CMD_ACK,1,0,0,dataout,16);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }
@ -259,73 +248,98 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LEDsoff(); LEDsoff();
} }
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
{ {
// params // free eventually allocated BigBuf memory
uint8_t sectorNo = arg0; BigBuf_free();
int Pages = arg1; // clear trace
int count_Pages = 0;
byte_t dataout[176] = {0x00};;
uint8_t uid[10] = {0x00};
uint32_t cuid;
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if (MF_DBGLEVEL >= MF_DBG_ALL)
Dbprintf("Pages %d",Pages);
clear_trace(); clear_trace();
// params
uint8_t blockNo = arg0;
uint16_t blocks = arg1;
bool useKey = (arg2 == 1); //UL_C
bool usePwd = (arg2 == 2); //UL_EV1/NTAG
uint32_t countblocks = 0;
uint8_t *dataout = BigBuf_malloc(CARD_MEMORY_SIZE);
if (dataout == NULL){
Dbprintf("out of memory");
OnError(1);
return;
}
LEDsoff();
LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid); int len = iso14443a_select_card(NULL, NULL, NULL);
if (!len) { if (!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
Dbprintf("Can't select card"); OnError(1);
//OnError(1);
return; return;
} }
for (int i = 0; i < Pages; i++){ // UL-C authentication
if ( useKey ) {
len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i); uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key) );
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if ( !mifare_ultra_auth(key) ) {
Dbprintf("Read block %d error",i); OnError(1);
//OnError(2);
return; return;
} else {
count_Pages++;
} }
} }
len = mifare_ultra_halt(cuid); // UL-EV1 / NTAG authentication
if (usePwd) {
uint8_t pwd[4] = {0x00};
memcpy(pwd, datain, sizeof(pwd));
uint8_t pack[4] = {0,0,0,0};
if (!mifare_ul_ev1_auth(pwd, pack)){
OnError(1);
return;
}
}
for (int i = 0; i < blocks; i++){
if ((i*4) + 4 > CARD_MEMORY_SIZE) {
Dbprintf("Data exceeds buffer!!");
break;
}
len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i);
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i);
// if no blocks read - error out
if (i==0){
OnError(2);
return;
} else {
//stop at last successful read block and return what we got
break;
}
} else {
countblocks++;
}
}
len = mifare_ultra_halt();
if (len) { if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
Dbprintf("Halt error"); OnError(3);
//OnError(3);
return; return;
} }
if (MF_DBGLEVEL >= MF_DBG_ALL) {
Dbprintf("Pages read %d", count_Pages);
}
len = 16*4; //64 bytes if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks);
// Read a UL-C
if (Pages == 44 && count_Pages > 16)
len = 176;
cmd_send(CMD_ACK, 1, 0, 0, dataout, len); countblocks *= 4;
cmd_send(CMD_ACK, 1, countblocks, countblocks, 0, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Select, Authenticate, Write a MIFARE tag. // Select, Authenticate, Write a MIFARE tag.
// read block // read block
@ -400,94 +414,143 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
{ {
// params uint8_t blockNo = arg0;
uint8_t blockNo = arg0;
byte_t blockdata[16] = {0x00}; byte_t blockdata[16] = {0x00};
memcpy(blockdata, datain,16); memcpy(blockdata, datain, 16);
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00}; uint8_t uid[10] = {0x00};
uint32_t cuid;
clear_trace(); LED_A_ON(); LED_B_OFF(); LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
cmd_send(CMD_ACK,isOK,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4);
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00};
uint32_t cuid;
clear_trace(); clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON(); if(!iso14443a_select_card(uid, NULL, NULL)) {
LED_B_OFF(); if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
LED_C_OFF(); OnError(0);
return;
};
while (true) { if(mifare_ultra_writeblock(blockNo, blockdata)) {
if(!iso14443a_select_card(uid, NULL, &cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); OnError(0);
break; return; };
};
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) { if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break; OnError(0);
}; return;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
cmd_send(CMD_ACK,isOK,0,0,0,0); cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
uint8_t blockNo = arg0;
byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4);
LEDsoff();
LED_A_ON();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!iso14443a_select_card(NULL, NULL, NULL)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
OnError(0);
return;
};
if(mifare_ultra_special_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(0);
return;
};
if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
OnError(0);
return;
};
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
uint8_t pwd[16] = {0x00};
byte_t blockdata[4] = {0x00};
memcpy(pwd, datain, 16);
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!iso14443a_select_card(NULL, NULL, NULL)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
OnError(0);
return;
};
blockdata[0] = pwd[7];
blockdata[1] = pwd[6];
blockdata[2] = pwd[5];
blockdata[3] = pwd[4];
if(mifare_ultra_special_writeblock( 44, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(44);
return;
};
blockdata[0] = pwd[3];
blockdata[1] = pwd[2];
blockdata[2] = pwd[1];
blockdata[3] = pwd[0];
if(mifare_ultra_special_writeblock( 45, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(45);
return;
};
blockdata[0] = pwd[15];
blockdata[1] = pwd[14];
blockdata[2] = pwd[13];
blockdata[3] = pwd[12];
if(mifare_ultra_special_writeblock( 46, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(46);
return;
};
blockdata[0] = pwd[11];
blockdata[1] = pwd[10];
blockdata[2] = pwd[9];
blockdata[3] = pwd[8];
if(mifare_ultra_special_writeblock( 47, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(47);
return;
};
if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
OnError(0);
return;
};
cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }
@ -1141,21 +1204,18 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
int len = iso14443a_select_card(uid, NULL, &cuid); int len = iso14443a_select_card(uid, NULL, &cuid);
if(!len) { if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
Dbprintf("Can't select card"); OnError(1);
//OnError(1);
return; return;
}; };
if(mifare_desfire_des_auth1(cuid, dataout)){ if(mifare_desfire_des_auth1(cuid, dataout)){
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail.");
Dbprintf("Authentication part1: Fail."); OnError(4);
//OnError(4);
return; return;
} }
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED"); if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout)); cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));
} }
@ -1184,3 +1244,18 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }
void OnSuccess(){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void OnError(uint8_t reason){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
cmd_send(CMD_ACK,0,reason,0,0,0);
LEDsoff();
}

View file

@ -18,6 +18,7 @@
#include "iso14443a.h" #include "iso14443a.h"
#include "crapto1.h" #include "crapto1.h"
#include "mifareutil.h" #include "mifareutil.h"
#include "des.h"
int MF_DBGLEVEL = MF_DBG_ALL; int MF_DBGLEVEL = MF_DBG_ALL;
@ -67,24 +68,24 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
// send commands // send commands
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
{ {
return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing); return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);
} }
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
{ {
uint8_t dcmd[8]; uint8_t dcmd[8];
dcmd[0] = cmd; dcmd[0] = cmd;
dcmd[1] = data[0]; dcmd[1] = data[0];
dcmd[2] = data[1]; dcmd[2] = data[1];
dcmd[3] = data[2]; dcmd[3] = data[2];
dcmd[4] = data[3]; dcmd[4] = data[3];
dcmd[5] = data[4]; dcmd[5] = data[4];
AppendCrc14443a(dcmd, 6); AppendCrc14443a(dcmd, 6);
ReaderTransmit(dcmd, sizeof(dcmd), NULL); ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(answer, answer_parity); int len = ReaderReceive(answer, answer_parity);
if(!len) { if(!len) {
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
return 2; return 2;
} }
return len; return len;
} }
@ -106,13 +107,34 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
if(len==1) { if(len==1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed.");
return 1; return 1;
} }
return len; return len;
} }
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{ {
uint8_t dcmd[4], ecmd[4]; uint8_t dcmd[7];
int len;
dcmd[0] = cmd;
memcpy(dcmd+1,data,4);
AppendCrc14443a(dcmd, 5);
ReaderTransmit(dcmd, sizeof(dcmd), timing);
len = ReaderReceive(answer, answer_parity);
if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
len = ReaderReceive(answer,answer_parity);
}
if(len==1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed.");
return 1;
}
return len;
}
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[4], ecmd[4];
uint16_t pos, res; uint16_t pos, res;
uint8_t par[1]; // 1 Byte parity is enough here uint8_t par[1]; // 1 Byte parity is enough here
dcmd[0] = cmd; dcmd[0] = cmd;
@ -284,97 +306,149 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
} }
memcpy(blockData, receivedAnswer, 16); memcpy(blockData, receivedAnswer, 16);
return 0; return 0;
} }
// mifare ultralight commands // mifare ultralight commands
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){
uint16_t len; uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t resp[4];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t respPar[1];
uint8_t key[4] = {0x00};
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); memcpy(key, keybytes, 4);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);
Dbprintf("Cmd Error: %02x", receivedAnswer[0]); len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL);
return 1; if (len != 4) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);
return 0;
} }
if (len != 11)
return 1; if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0],resp[1],resp[2],resp[3]);
memcpy(pack, resp, 4);
return 1;
}
int mifare_ultra_auth(uint8_t *keybytes){
/// 3des2k
uint8_t random_a[8] = {1,1,1,1,1,1,1,1};
uint8_t random_b[8] = {0x00};
uint8_t enc_random_b[8] = {0x00};
uint8_t rnd_ab[16] = {0x00};
uint8_t IV[8] = {0x00};
uint8_t key[16] = {0x00};
memcpy(key, keybytes, 16);
uint16_t len;
uint8_t resp[19] = {0x00};
uint8_t respPar[3] = {0,0,0};
// REQUEST AUTHENTICATION
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, resp, respPar ,NULL);
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 0;
}
// tag nonce.
memcpy(enc_random_b,resp+1,8);
// decrypt nonce.
tdes_2key_dec(random_b, enc_random_b, sizeof(random_b), key, IV );
rol(random_b,8);
memcpy(rnd_ab ,random_a,8);
memcpy(rnd_ab+8,random_b,8);
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x",
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], enc_random_b[0],enc_random_b[1],enc_random_b[2],enc_random_b[3],enc_random_b[4],enc_random_b[5],enc_random_b[6],enc_random_b[7]);
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
receivedAnswer[10]); Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x",
} random_b[0],random_b[1],random_b[2],random_b[3],random_b[4],random_b[5],random_b[6],random_b[7]);
memcpy(blockData, receivedAnswer, 11);
Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",
rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]);
Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x",
rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15] );
}
// encrypt out, in, length, key, iv
tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b);
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, rnd_ab, resp, respPar, NULL);
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 0;
}
uint8_t enc_resp[8] = { 0,0,0,0,0,0,0,0 };
uint8_t resp_random_a[8] = { 0,0,0,0,0,0,0,0 };
memcpy(enc_resp, resp+1, 8);
// decrypt out, in, length, key, iv
tdes_2key_dec(resp_random_a, enc_resp, 8, key, enc_random_b);
if ( memcmp(resp_random_a, random_a, 8) != 0 ) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("failed authentication");
return 0;
}
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x",
rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],
rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]);
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x",
rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],
rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15]);
Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x",
random_a[0],random_a[1],random_a[2],random_a[3],
random_a[4],random_a[5],random_a[6],random_a[7]);
Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x",
resp_random_a[0],resp_random_a[1],resp_random_a[2],resp_random_a[3],
resp_random_a[4],resp_random_a[5],resp_random_a[6],resp_random_a[7]);
}
return 1;
}
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t bt[2];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 18) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2;
}
memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");
return 3;
}
memcpy(blockData, receivedAnswer, 14);
return 0; return 0;
} }
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
uint16_t len; // variables
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 11)
return 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
receivedAnswer[10]);
}
memcpy(blockData, receivedAnswer, 11);
return 0;
}
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t bt[2];
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 18) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2;
}
memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd CRC response error.");
return 3;
}
memcpy(blockData, receivedAnswer, 14);
return 0;
}
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
uint16_t len, i; uint16_t len, i;
uint32_t pos; uint32_t pos;
uint8_t par[3] = {0}; // enough for 18 Bytes to send uint8_t par[3] = {0}; // enough for 18 Bytes to send
@ -416,65 +490,65 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
return 2; return 2;
} }
return 0; return 0;
} }
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData)
{ {
uint16_t len; uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18] = {0x00}; uint8_t d_block[18] = {0x00};
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
memcpy(d_block, blockData, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
return 0;
}
int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t d_block[8] = {0x00};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK // command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK AppendCrc14443a(d_block, 6);
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1; return 1;
} }
return 0;
memcpy(d_block, blockData, 16); }
AppendCrc14443a(d_block, 16);
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); {
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t d_block[8] = {0x00};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
uint16_t len; uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
@ -486,24 +560,24 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
return 1; return 1;
} }
return 0; return 0;
} }
int mifare_ultra_halt(uint32_t uid) int mifare_ultra_halt()
{ {
uint16_t len; uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) { if (len != 0) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("halt error. response len: %x", len); Dbprintf("halt error. response len: %x", len);
return 1; return 1;
} }
return 0; return 0;
} }
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
// plus evtl. 8 sectors with 16 blocks each (4k cards) // plus evtl. 8 sectors with 16 blocks each (4k cards)
@ -525,9 +599,9 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
} }
// work with emulator memory // work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = BigBuf_get_EM_addr(); uint8_t* emCARD = BigBuf_get_EM_addr();
memcpy(emCARD + blockNum * 16, data, blocksCount * 16); memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
} }
@ -654,8 +728,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
int len; int len;
// load key, keynumber // load key, keynumber
uint8_t data[2]={0x0a, 0x00}; uint8_t data[2]={0x0a, 0x00};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);
if (len == 1) { if (len == 1) {
@ -706,4 +780,4 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
return 0; return 0;
} }
return 1; return 1;
} }

View file

@ -52,33 +52,34 @@ extern int MF_DBGLEVEL;
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF(); #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
//functions //functions
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData); int mifare_ul_ev1_auth(uint8_t *key, uint8_t *pack);
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData); int mifare_ultra_auth(uint8_t *key);
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
int mifare_ultra_halt(uint32_t uid); int mifare_ultra_halt();
// desfire // desfire
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing);
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData); int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData); int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);
// crypto functions // crypto functions
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len); void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par); void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data); uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
@ -93,7 +94,7 @@ void emlGetMem(uint8_t *data, int blockNum, int blocksCount);
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount); void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);
uint64_t emlGetKey(int sectorNum, int keyType); uint64_t emlGetKey(int sectorNum, int keyType);
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum); int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum); int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);
int emlCheckValBl(int blockNum); int emlCheckValBl(int blockNum);
#endif #endif

View file

@ -68,6 +68,7 @@ CMDSRCS = nonce2key/crapto1.c\
mifarehost.c\ mifarehost.c\
crc.c \ crc.c \
crc16.c \ crc16.c \
crc64.c \
iso14443crc.c \ iso14443crc.c \
iso15693tools.c \ iso15693tools.c \
data.c \ data.c \

View file

@ -26,7 +26,7 @@
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode; uint8_t g_debugMode;
int DemodBufferLen; size_t DemodBufferLen;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
//set the demod buffer with given array of binary (one bit per byte) //set the demod buffer with given array of binary (one bit per byte)
@ -1484,7 +1484,7 @@ int CmdIndalaDecode(const char *Cmd)
return 0; return 0;
} }
uint8_t invert=0; uint8_t invert=0;
ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert); ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
if (ans < 1) { if (ans < 1) {
if (g_debugMode==1) if (g_debugMode==1)
PrintAndLog("Error2: %d",ans); PrintAndLog("Error2: %d",ans);
@ -1892,7 +1892,7 @@ int getSamples(const char *Cmd, bool silent)
PrintAndLog("Unpacking..."); PrintAndLog("Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0}; BitstreamOut bout = { got, bits_per_sample * n, 0};
int j =0; int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) { for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
uint8_t sample = getByte(bits_per_sample, &bout); uint8_t sample = getByte(bits_per_sample, &bout);
GraphBuffer[j] = ((int) sample )- 128; GraphBuffer[j] = ((int) sample )- 128;
} }

View file

@ -70,7 +70,7 @@ int getSamples(const char *Cmd, bool silent);
#define MAX_DEMOD_BUF_LEN (1024*128) #define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
extern int DemodBufferLen; extern size_t DemodBufferLen;
extern uint8_t g_debugMode; extern uint8_t g_debugMode;
#define BIGBUF_SIZE 40000 #define BIGBUF_SIZE 40000

View file

@ -71,11 +71,57 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break; case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break;
case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break; case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break; case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break; case MIFARE_AUTH_KEYA:{
if ( cmdsize > 3)
snprintf(exp,size,"AUTH-A(%d)",cmd[1]);
else
// case MIFARE_ULEV1_VERSION : both 0x60.
snprintf(exp,size,"EV1 VERSION");
break;
}
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break; case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
case MIFARE_MAGICWUPC1: snprintf(exp,size,"MAGIC WUPC1"); break; case MIFARE_MAGICWUPC1: snprintf(exp,size,"MAGIC WUPC1"); break;
case MIFARE_MAGICWUPC2: snprintf(exp,size,"MAGIC WUPC2"); break; case MIFARE_MAGICWUPC2: snprintf(exp,size,"MAGIC WUPC2"); break;
case MIFARE_MAGICWIPEC: snprintf(exp,size,"MAGIC WIPEC"); break; case MIFARE_MAGICWIPEC: snprintf(exp,size,"MAGIC WIPEC"); break;
case MIFARE_ULC_AUTH_1: snprintf(exp,size,"AUTH "); break;
case MIFARE_ULC_AUTH_2: snprintf(exp,size,"AUTH_ANSW"); break;
case MIFARE_ULEV1_AUTH:
if ( cmdsize == 7 )
snprintf(exp,size,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd[1], cmd[2], cmd[3], cmd[4] );
else
snprintf(exp,size,"PWD-AUTH");
break;
case MIFARE_ULEV1_FASTREAD:{
if ( cmdsize >=3 && cmd[2] <= 0xE6)
snprintf(exp,size,"READ RANGE (%d-%d)",cmd[1],cmd[2]);
else
snprintf(exp,size,"?");
break;
}
case MIFARE_ULC_WRITE:{
if ( cmd[1] < 0x21 )
snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]);
else
snprintf(exp,size,"?");
break;
}
case MIFARE_ULEV1_READ_CNT:{
if ( cmd[1] < 5 )
snprintf(exp,size,"READ CNT(%d)",cmd[1]);
else
snprintf(exp,size,"?");
break;
}
case MIFARE_ULEV1_INCR_CNT:{
if ( cmd[1] < 5 )
snprintf(exp,size,"INCR(%d)",cmd[1]);
else
snprintf(exp,size,"?");
break;
}
case MIFARE_ULEV1_READSIG: snprintf(exp,size,"READ_SIG"); break;
case MIFARE_ULEV1_CHECKTEAR: snprintf(exp,size,"CHK_TEARING(%d)",cmd[1]); break;
case MIFARE_ULEV1_VCSL: snprintf(exp,size,"VCSL"); break;
default: snprintf(exp,size,"?"); break; default: snprintf(exp,size,"?"); break;
} }
return; return;
@ -503,6 +549,32 @@ int CmdHFList(const char *Cmd)
return 0; return 0;
} }
int CmdHFSearch(const char *Cmd){
int ans = 0;
PrintAndLog("");
ans = CmdHF14AReader("s");
if (ans > 0) {
PrintAndLog("\nValid ISO14443A 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 = HF15Reader("", false);
if (ans) {
PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
return ans;
}
//14b has issues currently...
//ans = CmdHF14BRead(Cmd);
//if (ans > 0) return ans;
return 0;
}
static command_t CommandTable[] = static command_t CommandTable[] =
{ {
@ -513,10 +585,11 @@ static command_t CommandTable[] =
{"epa", CmdHFEPA, 1, "{ German Identification Card... }"}, {"epa", CmdHFEPA, 1, "{ German Identification Card... }"},
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"}, {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
{"list", CmdHFList, 1, "List protocol data in trace buffer"}, {"list", CmdHFList, 1, "List protocol data in trace buffer"},
{"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -23,6 +23,7 @@
#include "common.h" #include "common.h"
#include "cmdmain.h" #include "cmdmain.h"
#include "mifare.h" #include "mifare.h"
#include "cmdhfmfu.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static void waitCmd(uint8_t iLen); static void waitCmd(uint8_t iLen);
@ -143,7 +144,7 @@ int CmdHF14AReader(const char *Cmd)
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
if(select_status == 0) { if(select_status == 0) {
PrintAndLog("iso14443a card select failed"); if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed");
// disconnect // disconnect
c.arg[0] = 0; c.arg[0] = 0;
c.arg[1] = 0; c.arg[1] = 0;
@ -169,6 +170,42 @@ int CmdHF14AReader(const char *Cmd)
switch (card.sak) { switch (card.sak) {
case 0x00: case 0x00:
//***************************************test****************
// disconnect
c.arg[0] = 0;
c.arg[1] = 0;
c.arg[2] = 0;
SendCommand(&c);
uint32_t tagT = GetHF14AMfU_Type();
ul_print_type(tagT, 0);
//reconnect for further tests
c.arg[0] = ISO14A_CONNECT | ISO14A_NO_DISCONNECT;
c.arg[1] = 0;
c.arg[2] = 0;
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
if(select_status == 0) {
//PrintAndLog("iso14443a card select failed");
// disconnect
c.arg[0] = 0;
c.arg[1] = 0;
c.arg[2] = 0;
SendCommand(&c);
return 0;
}
/* orig
// check if the tag answers to GETVERSION (0x60) // check if the tag answers to GETVERSION (0x60)
c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT; c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;
c.arg[1] = 1; c.arg[1] = 1;
@ -187,7 +224,7 @@ int CmdHF14AReader(const char *Cmd)
case 0x01:PrintAndLog("TYPE : NXP MIFARE Ultralight C");break; case 0x01:PrintAndLog("TYPE : NXP MIFARE Ultralight C");break;
case 0x00:PrintAndLog("TYPE : NXP MIFARE Ultralight");break; case 0x00:PrintAndLog("TYPE : NXP MIFARE Ultralight");break;
} }
*/
break; break;
case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break;
case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break; case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;

View file

@ -374,6 +374,20 @@ int CmdHF15Record(const char *Cmd)
return 0; return 0;
} }
int HF15Reader(const char *Cmd, bool verbose)
{
uint8_t uid[8];
if (!getUID(uid)) {
if (verbose) PrintAndLog("No Tag found.");
return 0;
}
PrintAndLog("Tag UID : %s",sprintUID(NULL,uid));
PrintAndLog("Tag Info: %s",getTagInfo(uid));
return 1;
}
int CmdHF15Reader(const char *Cmd) int CmdHF15Reader(const char *Cmd)
{ {
UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}}; UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
@ -469,7 +483,7 @@ int CmdHF15DumpMem(const char*Cmd) {
// PrintAndLog("bn=%i",blocknum); // PrintAndLog("bn=%i",blocknum);
} else { } else {
PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
return 0; return 1;
} }
} // else PrintAndLog("crc"); } // else PrintAndLog("crc");
} // else PrintAndLog("r null"); } // else PrintAndLog("r null");
@ -481,7 +495,7 @@ int CmdHF15DumpMem(const char*Cmd) {
// PrintAndLog("CRC Failed"); // PrintAndLog("CRC Failed");
// else // else
// PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); // PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
return 0; return 1;
} }

View file

@ -15,6 +15,7 @@ int CmdHF15(const char *Cmd);
int CmdHF15Demod(const char *Cmd); int CmdHF15Demod(const char *Cmd);
int CmdHF15Read(const char *Cmd); int CmdHF15Read(const char *Cmd);
int HF15Reader(const char *Cmd, bool verbose);
int CmdHF15Reader(const char *Cmd); int CmdHF15Reader(const char *Cmd);
int CmdHF15Sim(const char *Cmd); int CmdHF15Sim(const char *Cmd);
int CmdHF15Record(const char *Cmd); int CmdHF15Record(const char *Cmd);

View file

@ -165,34 +165,47 @@ int CmdHFiClassSim(const char *Cmd)
return 0; return 0;
} }
int CmdHFiClassReader(const char *Cmd) int HFiClassReader(const char *Cmd, bool loop, bool verbose)
{ {
bool tagFound = false;
UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN| UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}}; FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
if (!loop) c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
while(!ukbhit()){ while(!ukbhit()){
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
uint8_t readStatus = resp.arg[0] & 0xff; uint8_t readStatus = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes; uint8_t *data = resp.d.asBytes;
PrintAndLog("Readstatus:%02x", readStatus); if (verbose)
PrintAndLog("Readstatus:%02x", readStatus);
if( readStatus == 0){ if( readStatus == 0){
//Aborted //Aborted
PrintAndLog("Quitting..."); if (verbose) PrintAndLog("Quitting...");
return 0; return 0;
} }
if( readStatus & FLAG_ICLASS_READER_CSN) PrintAndLog("CSN: %s",sprint_hex(data,8)); if( readStatus & FLAG_ICLASS_READER_CSN){
PrintAndLog("CSN: %s",sprint_hex(data,8));
tagFound = true;
}
if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8)); if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8));
if( readStatus & FLAG_ICLASS_READER_CONF){ if( readStatus & FLAG_ICLASS_READER_CONF){
printIclassDumpInfo(data); printIclassDumpInfo(data);
} }
if (tagFound && !loop) return 1;
} else { } else {
PrintAndLog("Command execute timeout"); if (verbose) PrintAndLog("Command execute timeout");
} }
if (!loop) break;
} }
return 0; return 0;
}
int CmdHFiClassReader(const char *Cmd)
{
return HFiClassReader(Cmd, true, true);
} }
int CmdHFiClassReader_Replay(const char *Cmd) int CmdHFiClassReader_Replay(const char *Cmd)

View file

@ -17,6 +17,7 @@ int CmdHFiClass(const char *Cmd);
int CmdHFiClassSnoop(const char *Cmd); int CmdHFiClassSnoop(const char *Cmd);
int CmdHFiClassSim(const char *Cmd); int CmdHFiClassSim(const char *Cmd);
int CmdHFiClassList(const char *Cmd); int CmdHFiClassList(const char *Cmd);
int HFiClassReader(const char *Cmd, bool loop, bool verbose);
int CmdHFiClassReader(const char *Cmd); int CmdHFiClassReader(const char *Cmd);
int CmdHFiClassReader_Replay(const char *Cmd); int CmdHFiClassReader_Replay(const char *Cmd);

View file

@ -547,7 +547,7 @@ int CmdHF14AMfNested(const char *Cmd)
uint8_t trgKeyType = 0; uint8_t trgKeyType = 0;
uint8_t SectorsCnt = 0; uint8_t SectorsCnt = 0;
uint8_t key[6] = {0, 0, 0, 0, 0, 0}; uint8_t key[6] = {0, 0, 0, 0, 0, 0};
uint8_t keyBlock[13*6]; uint8_t keyBlock[14*6];
uint64_t key64 = 0; uint64_t key64 = 0;
bool transferToEml = false; bool transferToEml = false;
@ -1202,7 +1202,7 @@ int CmdHF14AMfELoad(const char *Cmd)
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
fnameptr += len; fnameptr += len-4;
sprintf(fnameptr, ".eml"); sprintf(fnameptr, ".eml");
@ -1311,7 +1311,7 @@ int CmdHF14AMfESave(const char *Cmd)
for (j = 0; j < 7; j++, fnameptr += 2) for (j = 0; j < 7; j++, fnameptr += 2)
sprintf(fnameptr, "%02X", buf[j]); sprintf(fnameptr, "%02X", buf[j]);
} else { } else {
fnameptr += len; fnameptr += len-4;
} }
// add file extension // add file extension
@ -1575,7 +1575,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len); memcpy(filename, Cmd, len);
fnameptr += len; fnameptr += len-4;
sprintf(fnameptr, ".eml"); sprintf(fnameptr, ".eml");
@ -1592,6 +1592,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), f) == NULL) { if (fgets(buf, sizeof(buf), f) == NULL) {
fclose(f);
PrintAndLog("File reading error."); PrintAndLog("File reading error.");
return 2; return 2;
} }
@ -1600,6 +1601,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
if(strlen(buf) && feof(f)) if(strlen(buf) && feof(f))
break; break;
PrintAndLog("File content error. Block data must include 32 HEX symbols"); PrintAndLog("File content error. Block data must include 32 HEX symbols");
fclose(f);
return 2; return 2;
} }
for (i = 0; i < 32; i += 2) for (i = 0; i < 32; i += 2)

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,9 @@
#include "cmdhfmf.h" #include "cmdhfmf.h"
#include "cmdhf14a.h" #include "cmdhf14a.h"
#ifndef CMDHFMFU_H__
#define CMDHFMFU_H__
//standard ultralight //standard ultralight
int CmdHF14AMfUWrBl(const char *Cmd); int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd); int CmdHF14AMfURdBl(const char *Cmd);
@ -12,8 +15,40 @@ int CmdHF14AMfucAuth(const char *Cmd);
//general stuff //general stuff
int CmdHF14AMfUDump(const char *Cmd); int CmdHF14AMfUDump(const char *Cmd);
void rol (uint8_t *data, const size_t len); int CmdHF14AMfUInfo(const char *Cmd);
uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spacer);
void ul_switch_off_field(void);
int usage_hf_mfu_dump(void);
int usage_hf_mfu_info(void);
int CmdHFMFUltra(const char *Cmd); int CmdHFMFUltra(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);
typedef enum TAGTYPE_UL {
UNKNOWN = 0x000000,
UL = 0x000001,
UL_C = 0x000002,
UL_EV1_48 = 0x000004,
UL_EV1_128 = 0x000008,
NTAG = 0x000010,
NTAG_203 = 0x000020,
NTAG_210 = 0x000040,
NTAG_212 = 0x000080,
NTAG_213 = 0x000100,
NTAG_215 = 0x000200,
NTAG_216 = 0x000400,
MY_D = 0x000800,
MY_D_NFC = 0x001000,
MY_D_MOVE = 0x002000,
MY_D_MOVE_NFC = 0x004000,
NTAG_I2C_1K = 0x008000,
NTAG_I2C_2K = 0x010000,
MAGIC = 0x020000,
UL_MAGIC = UL | MAGIC,
UL_C_MAGIC = UL_C | MAGIC,
UL_ERROR = 0xFFFFFF,
} TagTypeUL_t;
#endif

View file

@ -83,7 +83,7 @@ int CmdList(const char *Cmd)
{ {
while ((ep = readdir (dp)) != NULL) while ((ep = readdir (dp)) != NULL)
{ {
if(ep->d_name != NULL && str_ends_with(ep->d_name, ".lua")) if(str_ends_with(ep->d_name, ".lua"))
PrintAndLog("%-16s %s", ep->d_name, "A script file"); PrintAndLog("%-16s %s", ep->d_name, "A script file");
} }
(void) closedir (dp); (void) closedir (dp);

View file

@ -11,7 +11,7 @@ d3f7d3f7d3f7,
587ee5f9350f, 587ee5f9350f,
a0478cc39091, a0478cc39091,
533cb6c723f6, 533cb6c723f6,
8fd0a4f256e9 8fd0a4f256e9,
# more Keys from mf_default_keys.lua # more Keys from mf_default_keys.lua
000000000001, 000000000001,
000000000002, 000000000002,
@ -42,6 +42,7 @@ a0478cc39091,
47524f555041,--RKFJOJOGROUPKeyA 47524f555041,--RKFJOJOGROUPKeyA
47524f555042,--RKFJOJOGROUPKeyB 47524f555042,--RKFJOJOGROUPKeyB
4AF9D7ADEBE4,--DirectoryandeventlogKeyA 4AF9D7ADEBE4,--DirectoryandeventlogKeyA
4b0b20107ccb,--TNP3xxx
505249564141,--RKFJOJOPRIVAKeyA 505249564141,--RKFJOJOPRIVAKeyA
505249564142,--RKFJOJOPRIVAKeyB 505249564142,--RKFJOJOPRIVAKeyB
505249565441, 505249565441,
@ -49,14 +50,19 @@ a0478cc39091,
54726176656c,--VästtrafikenKeyA 54726176656c,--VästtrafikenKeyA
555555555555, 555555555555,
55f5a5dd38c9, 55f5a5dd38c9,
569369c5a0e5,--kiev
5c598c9c58b5,--RKFSLKeyB 5c598c9c58b5,--RKFSLKeyB
632193be1c3c,--kiev
644672bd4afe,--kiev
666666666666, 666666666666,
722bfcc5375f,--RKFRejskortDanmarkKeyA 722bfcc5375f,--RKFRejskortDanmarkKeyA
776974687573,--VästtrafikenKeyB 776974687573,--VästtrafikenKeyB
777777777777, 777777777777,
888888888888, 888888888888,
8fe644038790,--kiev
999999999999, 999999999999,
99c636334433, 99c636334433,
9de89e070277,--kiev
a00000000000, a00000000000,
a053a292a4af, a053a292a4af,
a64598a77478,--RKFSLKeyA a64598a77478,--RKFSLKeyA
@ -65,6 +71,7 @@ aaaaaaaaaaaa,
abcdef123456,--Keyfromladyada.net abcdef123456,--Keyfromladyada.net
b00000000000, b00000000000,
b127c6f41436, b127c6f41436,
b5ff67cba951,--kiev
bbbbbbbbbbbb, bbbbbbbbbbbb,
bd493a3962b6, bd493a3962b6,
c934fe34d934, c934fe34d934,
@ -73,7 +80,15 @@ dddddddddddd,
e4d2770a89be,--RKFSLKeyB e4d2770a89be,--RKFSLKeyB
ee0042f88840,--VästtrafikenKeyB ee0042f88840,--VästtrafikenKeyB
eeeeeeeeeeee, eeeeeeeeeeee,
eff603e1efe9,--kiev
f14ee7cae863,--kiev
f1a97341a9fc, f1a97341a9fc,
f1d83f964314,--RKFRejskortDanmarkKeyB f1d83f964314,--RKFRejskortDanmarkKeyB
fc00018778f7,--VästtrafikenKeyA fc00018778f7,--VästtrafikenKeyA
fc0001877bf7,--RKFÖstgötaTrafikenKeyA fc0001877bf7,--RKFÖstgötaTrafikenKeyA
44ab09010845,-- hotel system
85fed980ea5a,-- hotel system
314B49474956,--VIGIK1KeyA
564c505f4d41,--VIGIK1KeyB
f4a9ef2afc6d,--BCARD KeyB
a9f953def0a3,--

View file

@ -135,11 +135,9 @@ local _commands = {
CMD_MIFARE_SNIFFER = 0x0630, CMD_MIFARE_SNIFFER = 0x0630,
--//ultralightC --//ultralightC
CMD_MIFAREUC_AUTH1 = 0x0724, CMD_MIFAREUC_AUTH = 0x0724,
CMD_MIFAREUC_AUTH2 = 0x0725, CMD_MIFAREUC_SETPWD = 0x0727,
CMD_MIFAREUC_READCARD = 0x0726, CMD_MIFAREU_SETUID = 0x0728,
CMD_MIFAREUC_SETPWD = 0x0727,
CMD_MIFAREU_SETUID = 0x0728,
--// mifare desfire --// mifare desfire
CMD_MIFARE_DESFIRE_READBL = 0x0728, CMD_MIFARE_DESFIRE_READBL = 0x0728,

View file

@ -24,6 +24,7 @@ local _names = {
{"13", "0d00", "0030", "water", "regular", "Wham Shell"}, {"13", "0d00", "0030", "water", "regular", "Wham Shell"},
{"14", "0e00", "0030", "water", "regular", "Gill Grunt"}, {"14", "0e00", "0030", "water", "regular", "Gill Grunt"},
--{"14", "0e00", "0030", "water", "regular", "Elite Gill Grunt"}, --{"14", "0e00", "0030", "water", "regular", "Elite Gill Grunt"},
--{"14", "0e00", "0030", "water", "regular", "Tidal Wave Gill Grunt"},
{"15", "0f00", "0030", "water", "regular", "Slam Bam"}, {"15", "0f00", "0030", "water", "regular", "Slam Bam"},
--{"15", "0f00", "0030", "water", "regular", "Surfer Slam Bam"}, --{"15", "0f00", "0030", "water", "regular", "Surfer Slam Bam"},
{"16", "1000", "0030", "magic", "regular", "Spyro"}, {"16", "1000", "0030", "magic", "regular", "Spyro"},
@ -43,7 +44,8 @@ local _names = {
{"25", "1900", "0030", "life", "regular", "Zook"}, {"25", "1900", "0030", "life", "regular", "Zook"},
{"26", "1a00", "0030", "life", "regular", "Stealth Elf"}, {"26", "1a00", "0030", "life", "regular", "Stealth Elf"},
--{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"}, --{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"},
--{"26", "1a00", "0030", "life", "regular", "Dark Stealth Elf"}, --{"26", "1a00", "0528", "life", "regular", "Dark Stealth Elf"},
{"26", "1a00", "0528", "life", "swapforce", "Ninja Stealth Elf"},
{"27", "1b00", "0030", "life", "regular", "Stump Smash"}, {"27", "1b00", "0030", "life", "regular", "Stump Smash"},
{"27", "1b00", "0118", "life", "regular", "Stump Smash"}, {"27", "1b00", "0118", "life", "regular", "Stump Smash"},
--{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"}, --{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"},
@ -59,6 +61,7 @@ local _names = {
--{"32", "2000", "0030", "undead", "regular", "Skeletal Cynder"}, --{"32", "2000", "0030", "undead", "regular", "Skeletal Cynder"},
{"100", "6400", "0030", "air", "giant", "Jet Vac"}, {"100", "6400", "0030", "air", "giant", "Jet Vac"},
--{"100", "6400", "0030", "air", "giant", "Full blast Jet Vac"},
{"101", "6500", "0030", "air", "giant", "Swarm"}, {"101", "6500", "0030", "air", "giant", "Swarm"},
{"102", "6600", "0030", "earth", "giant", "Crusher"}, {"102", "6600", "0030", "earth", "giant", "Crusher"},
{"103", "6700", "0030", "earth", "giant", "Flashwing"}, {"103", "6700", "0030", "earth", "giant", "Flashwing"},
@ -73,12 +76,14 @@ local _names = {
--{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"}, --{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"},
{"108", "6c00", "023c", "magic", "giant", "Love Potion Pop Fizz"}, {"108", "6c00", "023c", "magic", "giant", "Love Potion Pop Fizz"},
--{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"}, --{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"},
--{"108", "6c00", "0030", "magic", "giant", "Fizzy Frenzy Pop Fizz"},
{"109", "6d00", "0030", "magic", "giant", "Nin Jini"}, {"109", "6d00", "0030", "magic", "giant", "Nin Jini"},
{"110", "6e00", "0030", "tech", "giant", "Bouncer"}, {"110", "6e00", "0030", "tech", "giant", "Bouncer"},
{"111", "6f00", "0030", "tech", "giant", "Sprocket"}, {"111", "6f00", "0030", "tech", "giant", "Sprocket"},
{"112", "7000", "0030", "life", "giant", "Tree Rex"}, {"112", "7000", "0030", "life", "giant", "Tree Rex"},
--{"112", "7000", "0030", "life", "giant", "Gnarly Tree Rex"}, --{"112", "7000", "0030", "life", "giant", "Gnarly Tree Rex"},
{"113", "7100", "0030", "life", "giant", "Shroomboom"}, --lightcore {"113", "7100", "0030", "life", "giant", "Shroomboom"},
--{"113", "7100", "0030", "life", "giant", "Sure shot Shroomboom"},
{"114", "7200", "0030", "undead", "giant", "Eye Broawl"}, {"114", "7200", "0030", "undead", "giant", "Eye Broawl"},
{"115", "7300", "0030", "undead", "giant", "Fright Rider"}, {"115", "7300", "0030", "undead", "giant", "Fright Rider"},
@ -268,27 +273,35 @@ local _names = {
{"485", "e501", "0030", "dark", "regular", "Blackout"}, {"485", "e501", "0030", "dark", "regular", "Blackout"},
--{"485", "e501", "0234", "dark", "regular", "Special Blackout"}, --{"485", "e501", "0234", "dark", "regular", "Special Blackout"},
-- MINI's
{"502", "f601", "0030", "earth", "mini", "Bop"}, {"502", "f601", "0030", "earth", "mini", "Bop"},
{"503", "f701", "0030", "magic", "mini", "Spry"},
{"504", "f801", "0030", "undead", "mini", "Hijinx"},
{"505", "f901", "0030", "earth", "mini", "Terrabite"}, {"505", "f901", "0030", "earth", "mini", "Terrabite"},
{"506", "fa01", "0030", "air", "mini", "Breeze"}, {"506", "fa01", "0030", "air", "mini", "Breeze"},
{"507", "fb01", "0030", "fire", "mini", "Weeruptor"},
--{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"},
{"508", "fc01", "0030", "air", "mini", "Pet Vac"}, {"508", "fc01", "0030", "air", "mini", "Pet Vac"},
--{"508", "fc01", "0030", "air", "mini", "Power Punch Pet Vac"}, --{"508", "fc01", "0030", "air", "mini", "Power Punch Pet Vac"},
{"507", "fb01", "0030", "fire", "mini", "Weeruptor"},
--{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"},
{"509", "fd01", "0030", "fire", "mini", "Small Fry"}, {"509", "fd01", "0030", "fire", "mini", "Small Fry"},
{"510", "fe01", "0030", "tech", "mini", "Drobit"}, {"510", "fe01", "0030", "tech", "mini", "Drobit"},
{"514", "0202", "0030", "water", "mini", "Gill Runt"},
{"519", "0702", "0030", "tech", "mini", "Trigger Snappy"}, {"519", "0702", "0030", "tech", "mini", "Trigger Snappy"},
{"526", "0e02", "0030", "life", "mini", "Whisper Elf"}, {"526", "0e02", "0030", "life", "mini", "Whisper Elf"},
{"540", "1c02", "0030", "life", "mini", "Barkley"}, {"540", "1c02", "0030", "life", "mini", "Barkley"},
--{"540", "1c02", "0030", "life", "mini", "Gnarly Barkley"}, --{"540", "1c02", "0030", "life", "mini", "Gnarly Barkley"},
{"541", "1d02", "0030", "water", "mini", "Thumpling"}, {"541", "1d02", "0030", "water", "mini", "Thumpling"},
{"514", "0202", "0030", "water", "mini", "Gill Runt"},
{"542", "1e02", "0030", "magic", "mini", "mini Jini"}, {"542", "1e02", "0030", "magic", "mini", "mini Jini"},
{"503", "f701", "0030", "magic", "mini", "Spry"},
{"504", "f801", "0030", "undead", "mini", "Hijinx"},
{"543", "1f02", "0030", "undead", "mini", "Eye Small"}, {"543", "1f02", "0030", "undead", "mini", "Eye Small"},
{"3000", "b80b", "0030", "air", "SWAPFORCE", "Scratch"}, {"3000", "b80b", "0030", "air", "mini", "Scratch", "SWAPFORCE"},
{"3001", "b90b", "0030", "air", "SWAPFORCE", "Pop Thorn"}, {"3001", "b90b", "0030", "air", "SWAPFORCE", "Pop Thorn"},
--{"3001", "b90b", "0030", "air", "SWAPFORCE", "Buttered Pop Thorn"}, --{"3001", "b90b", "0030", "air", "SWAPFORCE", "Buttered Pop Thorn"},
{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Slobber Tooth"}, {"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Slobber Tooth"},
@ -315,6 +328,29 @@ local _names = {
{"3013", "c50b", "0030", "undead", "SWAPFORCE", "Grim Creeper"}, {"3013", "c50b", "0030", "undead", "SWAPFORCE", "Grim Creeper"},
{"3014", "c60b", "0030", "water", "SWAPFORCE", "Rip Tide"}, {"3014", "c60b", "0030", "water", "SWAPFORCE", "Rip Tide"},
{"3015", "c70b", "0030", "water", "SWAPFORCE", "Punk Shock"}, {"3015", "c70b", "0030", "water", "SWAPFORCE", "Punk Shock"},
--{"", "", "0030", "water", "SWAPFORCE", "Hoot Loop"},
--{"", "", "0030", "water", "SWAPFORCE", "Trap Shadow"},
--{"", "", "0030", "water", "SWAPFORCE", "Wash Buckler"},
--{"", "", "0030", "water", "SWAPFORCE", "Freeze Blade"},
--{"", "", "0030", "fire", "SWAPFORCE", "Magna Charge"},
--{"", "", "0030", "fire", "SWAPFORCE", "Spy Rise"},
--{"", "", "0030", "fire", "SWAPFORCE", "Doom Stone"},
--{"", "", "0030", "fire", "SWAPFORCE", "Rubble Rouser"},
--{"", "", "0030", "fire", "SWAPFORCE", "Blast Zone"}
--{"", "", "0030", "fire", "SWAPFORCE", "Fire Kraken"},
--{"", "", "0030", "fire", "SWAPFORCE", "Rattle Shake"},
--{"", "", "0030", "fire", "SWAPFORCE", "Night Shift"},
--{"", "", "0030", "life", "SWAPFORCE", "Stink Bomb"},
--{"", "", "0030", "life", "SWAPFORCE", "Grilla Drilla"},
--{"", "", "0030", "air", "SWAPFORCE", "Free Ranger"},
--{"", "", "0030", "air", "SWAPFORCE", "Boom Jet"},
} }
local function find( main, sub) local function find( main, sub)
@ -327,7 +363,15 @@ local function find( main, sub)
end end
return nil return nil
end end
local function list()
print ("Type\tSub\tElement\tGame Name")
print (string.rep('=', 54))
for k, v in pairs(_names) do
print(("%s\t%s\t%s\t%-9s\t%s"):format(v[2],v[3],v[4], v[5], v[6] ))
end
end
return { return {
Find = find, Find = find,
List = list,
} }

View file

@ -192,7 +192,7 @@ end
return { return {
convert_bin_to_html = convert_bin_to_html, convert_bin_to_html = convert_bin_to_html,
convert_eml_to_html = convert_eml_to_html, convert_eml_to_html = convert_eml_to_html,
convert_eml_to_bin = convert_eml_to_bin, convert_eml_to_bin = convert_eml_to_bin,
SaveAsBinary = save_BIN, SaveAsBinary = save_BIN,
SaveAsText = save_TEXT, SaveAsText = save_TEXT,
} }

384
client/lualibs/md5.lua Normal file
View file

@ -0,0 +1,384 @@
local md5 = {
_VERSION = "md5.lua 0.5.0",
_DESCRIPTION = "MD5 computation in Lua (5.1)",
_URL = "https://github.com/kikito/md5.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
}
-- bit lib implementions
local floor, abs, max = math.floor, math.abs, math.max
local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.sub
local function check_int(n)
-- checking not float
if(n - floor(n) > 0) then
error("trying to use bitwise operation on non-integer!")
end
end
local function tbl2number(tbl)
local n = #tbl
local rslt = 0
local power = 1
for i = 1, n do
rslt = rslt + tbl[i]*power
power = power*2
end
return rslt
end
local function expand(tbl_m, tbl_n)
local big = {}
local small = {}
if(#tbl_m > #tbl_n) then
big = tbl_m
small = tbl_n
else
big = tbl_n
small = tbl_m
end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not
local function bit_not(n)
local tbl = to_bits(n)
local size = max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
check_int(n)
if(n < 0) then
-- negative
return to_bits(bit_not(abs(n)) + 1)
end
-- to bits table
local tbl = {}
local cnt = 1
while (n > 0) do
local last = math.fmod(n,2)
if(last == 1) then
tbl[cnt] = 1
else
tbl[cnt] = 0
end
n = (n-last)/2
cnt = cnt + 1
end
return tbl
end
local function bit_or(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
local function bit_and(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
local function bit_xor(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else
tbl[i] = 0
end
end
return tbl2number(tbl)
end
local function bit_rshift(n, bits)
check_int(n)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
high_bit = 2147483648 -- 0x80000000
end
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
local function bit_lshift(n, bits)
check_int(n)
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 4294967295) -- 0xFFFFFFFF
end
-- convert little-endian 32-bit int to a 4-char string
local function lei2str(i)
local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
return f(0)..f(8)..f(16)..f(24)
end
-- convert raw string to big-endian int
local function str2bei(s)
local v=0
for i=1, #s do
v = v * 256 + byte(s, i)
end
return v
end
-- convert raw string to little-endian int
local function str2lei(s)
local v=0
for i = #s,1,-1 do
v = v*256 + byte(s, i)
end
return v
end
-- cut up a string in little-endian ints of given size
local function cut_le_str(s,...)
local o, r = 1, {}
local args = {...}
for i=1, #args do
table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
o = o + args[i]
end
return r
end
local swap = function (w) return str2bei(lei2str(w)) end
local function hex2binaryaux(hexval)
return char(tonumber(hexval, 16))
end
local function hex2binary(hex)
local result, _ = hex:gsub('..', hex2binaryaux)
return result
end
-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com
local FF = 0xffffffff
local CONSTS = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
}
local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
local z=function (f,a,b,c,d,x,s,ac)
a=bit_and(a+f(b,c,d)+x+ac,FF)
-- be *very* careful that left shift does not cause rounding!
return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b
end
local function transform(A,B,C,D,X)
local a,b,c,d=A,B,C,D
local t=CONSTS
a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
d=z(f,d,a,b,c,X[ 1],12,t[ 2])
c=z(f,c,d,a,b,X[ 2],17,t[ 3])
b=z(f,b,c,d,a,X[ 3],22,t[ 4])
a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
d=z(f,d,a,b,c,X[ 5],12,t[ 6])
c=z(f,c,d,a,b,X[ 6],17,t[ 7])
b=z(f,b,c,d,a,X[ 7],22,t[ 8])
a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
d=z(f,d,a,b,c,X[ 9],12,t[10])
c=z(f,c,d,a,b,X[10],17,t[11])
b=z(f,b,c,d,a,X[11],22,t[12])
a=z(f,a,b,c,d,X[12], 7,t[13])
d=z(f,d,a,b,c,X[13],12,t[14])
c=z(f,c,d,a,b,X[14],17,t[15])
b=z(f,b,c,d,a,X[15],22,t[16])
a=z(g,a,b,c,d,X[ 1], 5,t[17])
d=z(g,d,a,b,c,X[ 6], 9,t[18])
c=z(g,c,d,a,b,X[11],14,t[19])
b=z(g,b,c,d,a,X[ 0],20,t[20])
a=z(g,a,b,c,d,X[ 5], 5,t[21])
d=z(g,d,a,b,c,X[10], 9,t[22])
c=z(g,c,d,a,b,X[15],14,t[23])
b=z(g,b,c,d,a,X[ 4],20,t[24])
a=z(g,a,b,c,d,X[ 9], 5,t[25])
d=z(g,d,a,b,c,X[14], 9,t[26])
c=z(g,c,d,a,b,X[ 3],14,t[27])
b=z(g,b,c,d,a,X[ 8],20,t[28])
a=z(g,a,b,c,d,X[13], 5,t[29])
d=z(g,d,a,b,c,X[ 2], 9,t[30])
c=z(g,c,d,a,b,X[ 7],14,t[31])
b=z(g,b,c,d,a,X[12],20,t[32])
a=z(h,a,b,c,d,X[ 5], 4,t[33])
d=z(h,d,a,b,c,X[ 8],11,t[34])
c=z(h,c,d,a,b,X[11],16,t[35])
b=z(h,b,c,d,a,X[14],23,t[36])
a=z(h,a,b,c,d,X[ 1], 4,t[37])
d=z(h,d,a,b,c,X[ 4],11,t[38])
c=z(h,c,d,a,b,X[ 7],16,t[39])
b=z(h,b,c,d,a,X[10],23,t[40])
a=z(h,a,b,c,d,X[13], 4,t[41])
d=z(h,d,a,b,c,X[ 0],11,t[42])
c=z(h,c,d,a,b,X[ 3],16,t[43])
b=z(h,b,c,d,a,X[ 6],23,t[44])
a=z(h,a,b,c,d,X[ 9], 4,t[45])
d=z(h,d,a,b,c,X[12],11,t[46])
c=z(h,c,d,a,b,X[15],16,t[47])
b=z(h,b,c,d,a,X[ 2],23,t[48])
a=z(i,a,b,c,d,X[ 0], 6,t[49])
d=z(i,d,a,b,c,X[ 7],10,t[50])
c=z(i,c,d,a,b,X[14],15,t[51])
b=z(i,b,c,d,a,X[ 5],21,t[52])
a=z(i,a,b,c,d,X[12], 6,t[53])
d=z(i,d,a,b,c,X[ 3],10,t[54])
c=z(i,c,d,a,b,X[10],15,t[55])
b=z(i,b,c,d,a,X[ 1],21,t[56])
a=z(i,a,b,c,d,X[ 8], 6,t[57])
d=z(i,d,a,b,c,X[15],10,t[58])
c=z(i,c,d,a,b,X[ 6],15,t[59])
b=z(i,b,c,d,a,X[13],21,t[60])
a=z(i,a,b,c,d,X[ 4], 6,t[61])
d=z(i,d,a,b,c,X[11],10,t[62])
c=z(i,c,d,a,b,X[ 2],15,t[63])
b=z(i,b,c,d,a,X[ 9],21,t[64])
return A+a,B+b,C+c,D+d
end
----------------------------------------------------------------
function md5.sumhexa(s)
local msgLen = #s
local padLen = 56 - msgLen % 64
if msgLen % 64 > 56 then padLen = padLen + 64 end
if padLen == 0 then padLen = 64 end
s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0)
assert(#s % 64 == 0)
local t = CONSTS
local a,b,c,d = t[65],t[66],t[67],t[68]
for i=1,#s,64 do
local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
assert(#X == 16)
X[0] = table.remove(X,1) -- zero based!
a,b,c,d = transform(a,b,c,d,X)
end
return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d))
end
function md5.sum(s)
return hex2binary(md5.sumhexa(s))
end
return md5

View file

@ -2,6 +2,7 @@
local _keys = { local _keys = {
--[[ --[[
These keys are from the pm3 c-codebase. These keys are from the pm3 c-codebase.
@ -157,9 +158,30 @@ local _keys = {
'9de89e070277', '9de89e070277',
'eff603e1efe9', 'eff603e1efe9',
'644672bd4afe', '644672bd4afe',
'b5ff67cba951', 'b5ff67cba951',
}
--[[
hotel system cards,
http://www.proxmark.org/forum/viewtopic.php?id=2430
--]]
'44ab09010845',
'85fed980ea5a',
--[[
VIGIK1
--]]
'314B49474956',
'564c505f4d41',
--[[
BCARD keyB
--]]
'f4a9ef2afc6d',
--[[
--]]
'a9f953def0a3',
}
--- ---
-- The keys above have just been pasted in, for completeness sake. They contain duplicates. -- The keys above have just been pasted in, for completeness sake. They contain duplicates.

View file

@ -0,0 +1,94 @@
--[[
This is an experimental lib.
--]]
local utils = require('utils')
-- LOOKUP Tables
local perm = {}
perm [1]= { 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5, 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA }
perm [2]= { 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4, 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB }
perm [3]= { 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7, 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8 }
perm [4]= { 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6, 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9 }
perm [5]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE }
perm [6]= { 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0, 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF }
perm [7]= { 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3, 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC }
perm [8]= { 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD }
perm [9]= { 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD, 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2 }
perm [10]= { 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC, 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3 }
perm [11]= { 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF, 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0 }
perm [12]= { 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE, 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1 }
perm [13]= { 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9, 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6 }
perm [14]= { 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8, 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7 }
perm [15]= { 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB, 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4 }
perm [16]= { 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA, 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5 }
local shifts = {}
shifts[1]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE }
shifts[2]= { 0x4, 0xB, 0xB, 0x4, 0xB, 0x4, 0x4, 0xB, 0xA, 0x5, 0x5, 0xA, 0x5, 0xA, 0xA, 0x5 }
shifts[3]= { 0xB, 0x6, 0x0, 0xD, 0xD, 0x0, 0x6, 0xB, 0x6, 0xB, 0xD, 0x0, 0x0, 0xD, 0xB, 0x6 }
shifts[4]= { 0xE, 0x5, 0x9, 0x2, 0x0, 0xB, 0x7, 0xC, 0x3, 0x8, 0x4, 0xF, 0xD, 0x6, 0xA, 0x1 }
shifts[5]= { 0x4, 0xE, 0x1, 0xB, 0xF, 0x5, 0xA, 0x0, 0x3, 0x9, 0x6, 0xC, 0x8, 0x2, 0xD, 0x7 }
shifts[6]= { 0xA, 0x4, 0x7, 0x9, 0x0, 0xE, 0xD, 0x3, 0xE, 0x0, 0x3, 0xD, 0x4, 0xA, 0x9, 0x7 }
shifts[7]= { 0xE, 0x6, 0xE, 0x6, 0xF, 0x7, 0xF, 0x7, 0xD, 0x5, 0xD, 0x5, 0xC, 0x4, 0xC, 0x4 }
shifts[8]= { 0x7, 0x1, 0xB, 0xD, 0xE, 0x8, 0x2, 0x4, 0x4, 0x2, 0x8, 0xE, 0xD, 0xB, 0x1, 0x7 }
shifts[9]= { 0xD, 0xB, 0x0, 0x6, 0x6, 0x0, 0xB, 0xD, 0xA, 0xC, 0x7, 0x1, 0x1, 0x7, 0xC, 0xA }
shifts[10]= { 0xe, 0x1, 0x1, 0xe, 0x1, 0xe, 0xe, 0x1, 0x1, 0xe, 0xe, 0x1, 0xe, 0x1, 0x1, 0xe }
local function ApplyPermutationAndShifts( pos, value, nibble)
local shiftbytes = shifts[pos]
local shiftElem = shiftbytes[nibble+1] --one indexed
local shiftOne = shiftbytes[1]
local rs = bit32.bxor(value, bit32.bxor(shiftOne, shiftElem))
return rs
end
local function GetOne( uid, block )
if uid == nil then return nil, 'empty uid string' end
if #uid == 0 then return nil, 'empty uid string' end
if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end
if type(block) ~= 'number' then return nil, 'block is not number' end
if block > 16 or block < 0 then return nil, 'block is out-of-range' end
local s = ('%s%02X'):format(uid,block)
local nibble1 = tonumber(s:sub(1,1),16) + 1
local permuted = ''
for i = 1, #s do
local el_row = shifts[i]
local el_value = el_row[nibble1]
j = 1
while j <= i do
if i-j > 0 then
local nibble = tonumber(s:sub(j+1,j+1),16)
el_value = ApplyPermutationAndShifts(i-j, el_value, nibble)
end
j = j+1
end
permuted =('%s%X'):format(permuted,el_value)
end
permuted = 'C2'..permuted
local crc64numStr = utils.Crc64(permuted)
local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true)
local key = utils.ConvertBytesToHex(keybytes)
return key:sub(1,12)
end
local PreCalc =
{
GetAll = function(id)
if id == nil then return nil, 'empty string' end
if #id == 0 then return nil, 'empty string' end
if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end
local list = '4b0b20107ccb'
for i = 1,15 do
local key, err = GetOne(id,i)
if not key then return oops(err) end
list = list..key
end
return list
end,
}
return PreCalc

View file

@ -20,7 +20,9 @@ local ISO14A_COMMAND = {
ISO14A_RAW = 8, ISO14A_RAW = 8,
ISO14A_REQUEST_TRIGGER = 0x10, ISO14A_REQUEST_TRIGGER = 0x10,
ISO14A_APPEND_CRC = 0x20, ISO14A_APPEND_CRC = 0x20,
ISO14A_SET_TIMEOUT = 0x40 ISO14A_SET_TIMEOUT = 0x40,
ISO14A_NO_SELECT = 0x80,
ISO14A_TOPAZMODE = 0x100
} }
local ISO14443a_TYPES = {} local ISO14443a_TYPES = {}

View file

@ -71,8 +71,8 @@ local Utils =
return outResults return outResults
end, end,
------------ CRC-16 ccitt checksums
------------ CRC-16 ccitt checksums
-- Takes a hex string and calculates a crc16 -- Takes a hex string and calculates a crc16
Crc16 = function(s) Crc16 = function(s)
if s == nil then return nil end if s == nil then return nil end
@ -85,7 +85,22 @@ local Utils =
end end
return nil return nil
end, end,
------------ CRC-64 ecma checksums
-- Takes a hex string and calculates a crc64 ecma
Crc64 = function(s)
if s == nil then return nil end
if #s == 0 then return nil end
if type(s) == 'string' then
local utils = require('utils')
local asc = utils.ConvertHexToAscii(s)
local hash = core.crc64(asc)
return hash
end
return nil
end,
-- input parameter is a string -- input parameter is a string
-- Swaps the endianess and returns a number, -- Swaps the endianess and returns a number,
-- IE: 'cd7a' -> '7acd' -> 0x7acd -- IE: 'cd7a' -> '7acd' -> 0x7acd
@ -135,7 +150,7 @@ local Utils =
while IN>0 do while IN>0 do
I=I+1 I=I+1
IN , D = math.floor(IN/B), math.modf(IN,B)+1 IN , D = math.floor(IN/B), math.modf(IN,B)+1
OUT=string.sub(K,D,D)..OUT OUT = string.sub(K,D,D)..OUT
end end
return OUT return OUT
end, end,
@ -147,7 +162,7 @@ local Utils =
end end
local s={} local s={}
for i = 1, #(bytes) do for i = 1, #(bytes) do
s[i] = string.format("%02X",bytes[i]) s[i] = string.format("%02X",bytes[i])
end end
return table.concat(s) return table.concat(s)
end, end,
@ -171,16 +186,28 @@ local Utils =
end end
return t return t
end, end,
ConvertAsciiToBytes = function(s) ConvertAsciiToBytes = function(s, reverse)
local t={} local t = {}
if s == nil then return t end if s == nil then return t end
if #s == 0 then return t end if #s == 0 then return t end
for k in s:gmatch"(.)" do for k in s:gmatch"(.)" do
table.insert(t, string.byte(k)) table.insert(t, string.byte(k))
end end
return t
if not reverse then
return t
end
local rev = {}
if reverse then
for i = #t, 1,-1 do
table.insert(rev, t[i] )
end
end
return rev
end, end,
ConvertHexToAscii = function(s) ConvertHexToAscii = function(s)
local t={} local t={}
if s == nil then return t end if s == nil then return t end
@ -191,6 +218,30 @@ local Utils =
return table.concat(t) return table.concat(t)
end, end,
Chars2num = function(s)
return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4))
end,
-- use length of string to determine 8,16,32,64 bits
bytes_to_int = function(str,endian,signed)
local t={str:byte(1,-1)}
if endian=="big" then --reverse bytes
local tt={}
for k=1,#t do
tt[#t-k+1]=t[k]
end
t=tt
end
local n=0
for k=1,#t do
n=n+t[k]*2^((k-1)*8)
end
if signed then
n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative.
end
return n
end,
-- function convertStringToBytes(str) -- function convertStringToBytes(str)
-- local bytes = {} -- local bytes = {}
-- local strLength = string.len(str) -- local strLength = string.len(str)

View file

@ -354,10 +354,7 @@ int loadTraceCard(uint8_t *tuid) {
FillFileNameByUID(traceFileName, tuid, ".eml", 7); FillFileNameByUID(traceFileName, tuid, ".eml", 7);
f = fopen(traceFileName, "r"); f = fopen(traceFileName, "r");
if (!f) { if (!f) return 1;
fclose(f);
return 1;
}
blockNum = 0; blockNum = 0;
@ -394,10 +391,7 @@ int saveTraceCard(void) {
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;
f = fopen(traceFileName, "w+"); f = fopen(traceFileName, "w+");
if ( !f ) { if ( !f ) return 1;
fclose(f);
return 1;
}
for (int i = 0; i < 64; i++) { // blocks for (int i = 0; i < 64; i++) { // blocks
for (int j = 0; j < 16; j++) // bytes for (int j = 0; j < 16; j++) // bytes

View file

@ -19,6 +19,7 @@
#include "nonce2key/nonce2key.h" #include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h" #include "../common/iso15693tools.h"
#include "../common/crc16.h" #include "../common/crc16.h"
#include "../common/crc64.h"
#include "aes.h" #include "aes.h"
/** /**
* The following params expected: * The following params expected:
@ -29,34 +30,34 @@
*/ */
static int l_SendCommand(lua_State *L){ static int l_SendCommand(lua_State *L){
/* /*
* *
The SendCommand (native) expects the following structure: The SendCommand (native) expects the following structure:
typedef struct { typedef struct {
uint64_t cmd; //8 bytes uint64_t cmd; //8 bytes
uint64_t arg[3]; // 8*3 bytes = 24 bytes uint64_t arg[3]; // 8*3 bytes = 24 bytes
union { union {
uint8_t asBytes[USB_CMD_DATA_SIZE]; // 1 byte * 512 = 512 bytes (OR) uint8_t asBytes[USB_CMD_DATA_SIZE]; // 1 byte * 512 = 512 bytes (OR)
uint32_t asDwords[USB_CMD_DATA_SIZE/4]; // 4 byte * 128 = 512 bytes uint32_t asDwords[USB_CMD_DATA_SIZE/4]; // 4 byte * 128 = 512 bytes
} d; } d;
} PACKED UsbCommand; } PACKED UsbCommand;
==> A 544 byte buffer will do. ==> A 544 byte buffer will do.
**/ **/
//Pop cmd //Pop cmd
size_t size; size_t size;
const char *data = luaL_checklstring(L, 1, &size); const char *data = luaL_checklstring(L, 1, &size);
if(size != sizeof(UsbCommand)) if(size != sizeof(UsbCommand))
{ {
printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand)); printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand));
lua_pushstring(L,"Wrong data size"); lua_pushstring(L,"Wrong data size");
return 1; return 1;
} }
// UsbCommand c = (*data); // UsbCommand c = (*data);
SendCommand((UsbCommand* )data); SendCommand((UsbCommand* )data);
return 0; // no return values return 0; // no return values
} }
/** /**
* @brief The following params expected: * @brief The following params expected:
@ -67,105 +68,105 @@ static int l_SendCommand(lua_State *L){
*/ */
static int l_WaitForResponseTimeout(lua_State *L){ static int l_WaitForResponseTimeout(lua_State *L){
uint32_t cmd = 0; uint32_t cmd = 0;
size_t ms_timeout = -1; size_t ms_timeout = -1;
//Check number of arguments //Check number of arguments
int n = lua_gettop(L); int n = lua_gettop(L);
if(n == 0) if(n == 0)
{ {
//signal error by returning Nil, errorstring //signal error by returning Nil, errorstring
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L,"You need to supply at least command to wait for"); lua_pushstring(L,"You need to supply at least command to wait for");
return 2; // two return values return 2; // two return values
} }
if(n >= 1) if(n >= 1)
{ {
//pop cmd //pop cmd
cmd = luaL_checkunsigned(L,1); cmd = luaL_checkunsigned(L,1);
} }
if(n >= 2) if(n >= 2)
{ {
//Did the user send a timeout ? //Did the user send a timeout ?
//Check if the current top of stack is an integer //Check if the current top of stack is an integer
ms_timeout = luaL_checkunsigned(L,2); ms_timeout = luaL_checkunsigned(L,2);
//printf("Timeout set to %dms\n" , (int) ms_timeout); //printf("Timeout set to %dms\n" , (int) ms_timeout);
} }
UsbCommand response; UsbCommand response;
if(WaitForResponseTimeout(cmd, &response, ms_timeout)) if(WaitForResponseTimeout(cmd, &response, ms_timeout))
{ {
//Push it as a string //Push it as a string
lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand)); lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand));
return 1;// return 1 to signal one return value return 1;// return 1 to signal one return value
}else{ }else{
//Push a Nil instead //Push a Nil instead
lua_pushnil(L); lua_pushnil(L);
return 1;// one return value return 1;// one return value
} }
} }
static int returnToLuaWithError(lua_State *L, const char* fmt, ...) static int returnToLuaWithError(lua_State *L, const char* fmt, ...)
{ {
char buffer[200]; char buffer[200];
va_list args; va_list args;
va_start(args,fmt); va_start(args,fmt);
vsnprintf(buffer, sizeof(buffer), fmt,args); vsnprintf(buffer, sizeof(buffer), fmt,args);
va_end(args); va_end(args);
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L,buffer); lua_pushstring(L,buffer);
return 2; return 2;
} }
static int l_nonce2key(lua_State *L){ static int l_nonce2key(lua_State *L){
size_t size; size_t size;
const char *p_uid = luaL_checklstring(L, 1, &size); const char *p_uid = luaL_checklstring(L, 1, &size);
if(size != 4) return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size); if(size != 4) return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size);
const char *p_nt = luaL_checklstring(L, 2, &size); const char *p_nt = luaL_checklstring(L, 2, &size);
if(size != 4) return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size); if(size != 4) return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size);
const char *p_nr = luaL_checklstring(L, 3, &size); const char *p_nr = luaL_checklstring(L, 3, &size);
if(size != 4) return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size); if(size != 4) return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size);
const char *p_par_info = luaL_checklstring(L, 4, &size); const char *p_par_info = luaL_checklstring(L, 4, &size);
if(size != 8) return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size); if(size != 8) return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size);
const char *p_pks_info = luaL_checklstring(L, 5, &size); const char *p_pks_info = luaL_checklstring(L, 5, &size);
if(size != 8) return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size); if(size != 8) return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size);
uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4); uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4);
uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4); uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4);
uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4); uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4);
uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8); uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8);
uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8); uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8);
uint64_t key = 0; uint64_t key = 0;
int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key); int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key);
//Push the retval on the stack //Push the retval on the stack
lua_pushinteger(L,retval); lua_pushinteger(L,retval);
//Push the key onto the stack
uint8_t dest_key[8];
num_to_bytes(key,sizeof(dest_key),dest_key);
//printf("Pushing to lua stack: %012"llx"\n",key); //Push the key onto the stack
lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key)); uint8_t dest_key[8];
num_to_bytes(key,sizeof(dest_key),dest_key);
return 2; //Two return values //printf("Pushing to lua stack: %012"llx"\n",key);
lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key));
return 2; //Two return values
} }
//static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));} //static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));}
static int l_clearCommandBuffer(lua_State *L){ static int l_clearCommandBuffer(lua_State *L){
clearCommandBuffer(); clearCommandBuffer();
return 0; return 0;
} }
/** /**
* @brief l_foobar is a dummy function to test lua-integration with * @brief l_foobar is a dummy function to test lua-integration with
@ -174,23 +175,23 @@ static int l_clearCommandBuffer(lua_State *L){
*/ */
static int l_foobar(lua_State *L) static int l_foobar(lua_State *L)
{ {
//Check number of arguments //Check number of arguments
int n = lua_gettop(L); int n = lua_gettop(L);
printf("foobar called with %d arguments" , n); printf("foobar called with %d arguments" , n);
lua_settop(L, 0); lua_settop(L, 0);
printf("Arguments discarded, stack now contains %d elements", lua_gettop(L)); printf("Arguments discarded, stack now contains %d elements", lua_gettop(L));
// todo: this is not used, where was it intended for?
// UsbCommand response = {CMD_MIFARE_READBL, {1337, 1338, 1339}};
printf("Now returning a uint64_t as a string");
uint64_t x = 0xDEADBEEF;
uint8_t destination[8];
num_to_bytes(x,sizeof(x),destination);
lua_pushlstring(L,(const char *)&x,sizeof(x));
lua_pushlstring(L,(const char *)destination,sizeof(destination));
return 2; // todo: this is not used, where was it intended for?
// UsbCommand response = {CMD_MIFARE_READBL, {1337, 1338, 1339}};
printf("Now returning a uint64_t as a string");
uint64_t x = 0xDEADBEEF;
uint8_t destination[8];
num_to_bytes(x,sizeof(x),destination);
lua_pushlstring(L,(const char *)&x,sizeof(x));
lua_pushlstring(L,(const char *)destination,sizeof(destination));
return 2;
} }
@ -201,8 +202,8 @@ static int l_foobar(lua_State *L)
*/ */
static int l_ukbhit(lua_State *L) static int l_ukbhit(lua_State *L)
{ {
lua_pushboolean(L,ukbhit() ? true : false); lua_pushboolean(L,ukbhit() ? true : false);
return 1; return 1;
} }
/** /**
* @brief Calls the command line parser to deal with the command. This enables * @brief Calls the command line parser to deal with the command. This enables
@ -212,58 +213,78 @@ static int l_ukbhit(lua_State *L)
*/ */
static int l_CmdConsole(lua_State *L) static int l_CmdConsole(lua_State *L)
{ {
CommandReceived((char *)luaL_checkstring(L, 1)); CommandReceived((char *)luaL_checkstring(L, 1));
return 0; return 0;
} }
static int l_iso15693_crc(lua_State *L) static int l_iso15693_crc(lua_State *L)
{ {
// uint16_t Iso15693Crc(uint8_t *v, int n); // uint16_t Iso15693Crc(uint8_t *v, int n);
size_t size; size_t size;
const char *v = luaL_checklstring(L, 1, &size); const char *v = luaL_checklstring(L, 1, &size);
uint16_t retval = Iso15693Crc((uint8_t *) v, size); uint16_t retval = Iso15693Crc((uint8_t *) v, size);
lua_pushinteger(L, (int) retval); lua_pushinteger(L, (int) retval);
return 1; return 1;
} }
/* /*
Simple AES 128 cbc hook up to OpenSSL. Simple AES 128 cbc hook up to OpenSSL.
params: key, input params: key, input
*/ */
static int l_aes(lua_State *L) static int l_aes128decrypt(lua_State *L)
{ {
//Check number of arguments //Check number of arguments
int i; int i;
size_t size; size_t size;
const char *p_key = luaL_checklstring(L, 1, &size); const char *p_key = luaL_checklstring(L, 1, &size);
if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size); if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
const char *p_encTxt = luaL_checklstring(L, 2, &size);
const char *p_encTxt = luaL_checklstring(L, 2, &size);
unsigned char indata[16] = {0x00}; unsigned char indata[16] = {0x00};
unsigned char outdata[16] = {0x00}; unsigned char outdata[16] = {0x00};
unsigned char aes_key[16] = {0x00}; unsigned char aes_key[16] = {0x00};
unsigned char iv[16] = {0x00}; unsigned char iv[16] = {0x00};
// convert key to bytearray // convert key to bytearray and convert input to bytearray
for (i = 0; i < 32; i += 2) { for (i = 0; i < 32; i += 2) {
sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]); sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
}
// convert input to bytearray
for (i = 0; i < 32; i += 2) {
sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]); sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
} }
//AES_KEY key;
//AES_set_decrypt_key(aes_key, 128, &key);
//AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
aes_context ctx; aes_context ctx;
aes_init(&ctx); aes_init(&ctx);
aes_setkey_dec(&ctx, aes_key, 128); aes_setkey_dec(&ctx, aes_key, 128);
aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata ); aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata );
//Push decrypted array as a string //Push decrypted array as a string
lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
return 1;// return 1 to signal one return value
}
static int l_aes128encrypt(lua_State *L)
{
//Check number of arguments
int i;
size_t size;
const char *p_key = luaL_checklstring(L, 1, &size);
if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
const char *p_txt = luaL_checklstring(L, 2, &size);
unsigned char indata[16] = {0x00};
unsigned char outdata[16] = {0x00};
unsigned char aes_key[16] = {0x00};
unsigned char iv[16] = {0x00};
for (i = 0; i < 32; i += 2) {
sscanf(&p_txt[i], "%02x", (unsigned int *)&indata[i / 2]);
sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
}
aes_context ctx;
aes_init(&ctx);
aes_setkey_enc(&ctx, aes_key, 128);
aes_crypt_cbc(&ctx, AES_ENCRYPT, sizeof(indata), iv, indata, outdata );
//Push encrypted array as a string
lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
return 1;// return 1 to signal one return value return 1;// return 1 to signal one return value
} }
@ -272,10 +293,32 @@ static int l_crc16(lua_State *L)
{ {
size_t size; size_t size;
const char *p_str = luaL_checklstring(L, 1, &size); const char *p_str = luaL_checklstring(L, 1, &size);
uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size); uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
lua_pushinteger(L, (int) retval); lua_pushinteger(L, (int) retval);
return 1; return 1;
}
static int l_crc64(lua_State *L)
{
size_t size;
uint64_t crc = 0;
unsigned char outdata[8] = {0x00};
const char *p_str = luaL_checklstring(L, 1, &size);
crc64( (uint8_t*) p_str, size, &crc);
outdata[0] = (uint8_t)(crc >> 56) & 0xff;
outdata[1] = (uint8_t)(crc >> 48) & 0xff;
outdata[2] = (uint8_t)(crc >> 40) & 0xff;
outdata[3] = (uint8_t)(crc >> 32) & 0xff;
outdata[4] = (uint8_t)(crc >> 24) & 0xff;
outdata[5] = (uint8_t)(crc >> 16) & 0xff;
outdata[6] = (uint8_t)(crc >> 8) & 0xff;
outdata[7] = crc & 0xff;
lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
return 1;
} }
/** /**
@ -288,57 +331,60 @@ static int l_crc16(lua_State *L)
*/ */
int setLuaPath( lua_State* L, const char* path ) int setLuaPath( lua_State* L, const char* path )
{ {
lua_getglobal( L, "package" ); lua_getglobal( L, "package" );
lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1) lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1)
const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack
int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it
char * buf = malloc(requiredLength); char * buf = malloc(requiredLength);
snprintf(buf, requiredLength, "%s;%s", cur_path, path); snprintf(buf, requiredLength, "%s;%s", cur_path, path);
lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5 lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5
lua_pushstring( L, buf ); // push the new one lua_pushstring( L, buf ); // push the new one
lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack
lua_pop( L, 1 ); // get rid of package table from top of stack lua_pop( L, 1 ); // get rid of package table from top of stack
return 0; // all done! free(buf);
return 0; // all done!
} }
int set_pm3_libraries(lua_State *L) int set_pm3_libraries(lua_State *L)
{ {
static const luaL_Reg libs[] = { static const luaL_Reg libs[] = {
{"SendCommand", l_SendCommand}, {"SendCommand", l_SendCommand},
{"WaitForResponseTimeout", l_WaitForResponseTimeout}, {"WaitForResponseTimeout", l_WaitForResponseTimeout},
{"nonce2key", l_nonce2key}, {"nonce2key", l_nonce2key},
//{"PrintAndLog", l_PrintAndLog}, //{"PrintAndLog", l_PrintAndLog},
{"foobar", l_foobar}, {"foobar", l_foobar},
{"ukbhit", l_ukbhit}, {"ukbhit", l_ukbhit},
{"clearCommandBuffer", l_clearCommandBuffer}, {"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole}, {"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc}, {"iso15693_crc", l_iso15693_crc},
{"aes", l_aes}, {"aes128_decrypt", l_aes128decrypt},
{"aes128_encrypt", l_aes128encrypt},
{"crc16", l_crc16}, {"crc16", l_crc16},
{NULL, NULL} {"crc64", l_crc64},
}; {NULL, NULL}
};
lua_pushglobaltable(L); lua_pushglobaltable(L);
// Core library is in this table. Contains ' // Core library is in this table. Contains '
//this is 'pm3' table //this is 'pm3' table
lua_newtable(L); lua_newtable(L);
//Put the function into the hash table. //Put the function into the hash table.
for (int i = 0; libs[i].name; i++) { for (int i = 0; libs[i].name; i++) {
lua_pushcfunction(L, libs[i].func); lua_pushcfunction(L, libs[i].func);
lua_setfield(L, -2, libs[i].name);//set the name, pop stack lua_setfield(L, -2, libs[i].name);//set the name, pop stack
} }
//Name of 'core' //Name of 'core'
lua_setfield(L, -2, "core"); lua_setfield(L, -2, "core");
//-- remove the global environment table from the stack //-- remove the global environment table from the stack
lua_pop(L, 1); lua_pop(L, 1);
//-- Last but not least, add to the LUA_PATH (package.path in lua) //-- Last but not least, add to the LUA_PATH (package.path in lua)
// so we can load libraries from the ./lualib/ - directory // so we can load libraries from the ./lualib/ - directory
setLuaPath(L,"./lualibs/?.lua"); setLuaPath(L,"./lualibs/?.lua");
return 1; return 1;
} }

View file

@ -80,14 +80,14 @@ function GetCardInfo()
core.clearCommandBuffer() core.clearCommandBuffer()
if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k
-- IFARE Classic 4K offers 4096 bytes split into forty sectors, -- IFARE Classic 4K offers 4096 bytes split into forty sectors,
-- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors.
numSectors = 40 numSectors = 40
elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k
-- 1K offers 1024 bytes of data storage, split into 16 sector -- 1K offers 1024 bytes of data storage, split into 16 sector
numSectors = 16 numSectors = 16
elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k
-- MIFARE Classic mini offers 320 bytes split into five sectors. -- MIFARE Classic mini offers 320 bytes split into five sectors.
numSectors = 5 numSectors = 5
elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k

View file

@ -13,6 +13,7 @@ local band = bit32.band
example =[[ example =[[
script run tnp3clone script run tnp3clone
script run tnp3clone -h script run tnp3clone -h
script run tnp3clone -l
script run tnp3clone -t aa00 -s 0030 script run tnp3clone -t aa00 -s 0030
]] ]]
@ -23,7 +24,8 @@ This script will try making a barebone clone of a tnp3 tag on to a magic generat
Arguments: Arguments:
-h : this help -h : this help
-t <data> : toytype id, 4hex symbols. -l : list all known toy tokens
-t <data> : toytype id, 4hex symbols
-s <data> : subtype id, 4hex symbols -s <data> : subtype id, 4hex symbols
For fun, try the following subtype id: For fun, try the following subtype id:
@ -32,7 +34,7 @@ Arguments:
0138 - Series 2 0138 - Series 2
0234 - Special 0234 - Special
023c - Special 023c - Special
0020 - Swapforce
]] ]]
@ -74,7 +76,7 @@ local function readmagicblock( blocknum )
-- Read block 0 -- Read block 0
local CSETBLOCK_SINGLE_OPERATION = 0x1F local CSETBLOCK_SINGLE_OPERATION = 0x1F
cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum} cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum}
err = core.SendCommand(cmd:getBytes()) err = core.SendCommand(cmd:getBytes())
if err then return nil, err end if err then return nil, err end
local block0, err = waitCmd() local block0, err = waitCmd()
if err then return nil, err end if err then return nil, err end
@ -98,12 +100,13 @@ local function main(args)
local DEBUG = true local DEBUG = true
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'ht:s:') do for o, a in getopt.getopt(args, 'ht:s:l') do
if o == "h" then return help() end if o == "h" then return help() end
if o == "t" then toytype = a end if o == "t" then toytype = a end
if o == "s" then subtype = a end if o == "s" then subtype = a end
if o == "l" then return toys.List() end
end end
if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end
if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end
@ -139,8 +142,9 @@ local function main(args)
-- wipe card. -- wipe card.
local cmd = (csetuid..'%s 0004 08 w'):format(result.uid) local cmd = (csetuid..'%s 0004 08 w'):format(result.uid)
core.console(cmd) core.console(cmd)
local b1 = toytype..string.rep('00',10)..subtype
local b1 = toytype..'00000000000000000000'..subtype
local calc = utils.Crc16(b0..b1) local calc = utils.Crc16(b0..b1)
local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8)) local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8))

View file

@ -205,18 +205,19 @@ local function main(args)
if blockNo < 8 then if blockNo < 8 then
-- Block 0-7 not encrypted -- Block 0-7 not encrypted
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
else else
-- blocks with zero not encrypted. -- blocks with zero not encrypted.
if string.find(blockdata, '^0+$') then if string.find(blockdata, '^0+$') then
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
else else
local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo)) local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo))
local key = md5.sumhexa(baseStr) local key = md5.sumhexa(baseStr)
local aestest = core.aes128_decrypt(key, blockdata) local aestest = core.aes128_decrypt(key, blockdata)
local hex = utils.ConvertAsciiToBytes(aestest) local hex = utils.ConvertAsciiToBytes(aestest)
hex = utils.ConvertBytesToHex(hex) hex = utils.ConvertBytesToHex(hex)
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex) blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
io.write(blockNo..',')
end end
end end
else else
@ -273,5 +274,7 @@ local function main(args)
print( (' UID : 0x%s'):format(uid) ) print( (' UID : 0x%s'):format(uid) )
print( (' CARDID : 0x%s'):format(cardid ) ) print( (' CARDID : 0x%s'):format(cardid ) )
print( string.rep('--',20) ) print( string.rep('--',20) )
core.clearCommandBuffer()
end end
main(args) main(args)

View file

@ -23,10 +23,22 @@ Arguments:
-h : this help -h : this help
-m : Maxed out items (experimental) -m : Maxed out items (experimental)
-i : filename for the datadump to read (bin) -i : filename for the datadump to read (bin)
]]
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag local DEBUG = false -- the debug flag
local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
local band = bit32.band
local bor = bit32.bor
local lshift = bit32.lshift
local rshift = bit32.rshift
local byte = string.byte
local char = string.char
local sub = string.sub
local format = string.format
local band = bit32.band local band = bit32.band
@ -197,8 +209,6 @@ local function ValidateCheckSums(blocks)
io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
end end
local function LoadEmulator(blocks)
local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
local cmd local cmd
local blockdata local blockdata
for _,b in pairs(blocks) do for _,b in pairs(blocks) do
@ -207,10 +217,10 @@ local function LoadEmulator(blocks)
if _%4 ~= 3 then if _%4 ~= 3 then
if (_ >= 8 and _<=21) or (_ >= 36 and _<=49) then if (_ >= 8 and _<=21) or (_ >= 36 and _<=49) then
local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT) local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , RANDOM)
local baseStr = utils.ConvertHexToAscii(base) local baseStr = utils.ConvertHexToAscii(base)
local key = md5.sumhexa(baseStr) local key = md5.sumhexa(baseStr)
local enc = core.aes(key, blockdata) local enc = core.aes128_encrypt(key, blockdata)
local hex = utils.ConvertAsciiToBytes(enc) local hex = utils.ConvertAsciiToBytes(enc)
hex = utils.ConvertBytesToHex(hex) hex = utils.ConvertBytesToHex(hex)
@ -346,21 +356,6 @@ local function main(args)
local cmdSetDbgOff = "hf mf dbg 0" local cmdSetDbgOff = "hf mf dbg 0"
core.console( cmdSetDbgOff) core.console( cmdSetDbgOff)
-- if not loadFromDump then
-- -- Look for tag present on reader,
-- result, err = lib14a.read1443a(false)
-- if not result then return oops(err) end
-- core.clearCommandBuffer()
-- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
-- return oops('This is not a TNP3xxx tag. aborting.')
-- end
-- -- Show tag info
-- print((' Found tag : %s'):format(result.name))
-- end
-- Load dump.bin file -- Load dump.bin file
print( (' Load data from %s'):format(inputTemplate)) print( (' Load data from %s'):format(inputTemplate))
hex, err = utils.ReadDumpFile(inputTemplate) hex, err = utils.ReadDumpFile(inputTemplate)
@ -374,7 +369,7 @@ local function main(args)
end end
if DEBUG then if DEBUG then
print('Validating checksums in the loaded datadump') print(' Validating checksums')
ValidateCheckSums(blocks) ValidateCheckSums(blocks)
end end
@ -393,7 +388,7 @@ local function main(args)
local item = toys.Find( toytype, subtype) local item = toys.Find( toytype, subtype)
if item then if item then
local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4]) local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4])
print(' ITEM TYPE :'..itemStr ) print(' ITEM TYPE : '..itemStr )
else else
print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) ) print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) )
end end
@ -407,12 +402,19 @@ local function main(args)
print( string.rep('--',20) ) print( string.rep('--',20) )
-- lets do something. -- Experience should be:
--
local experience = blocks[8]:sub(1,6) local experience = blocks[8]:sub(1,6)
print(('Experience : %d'):format(utils.SwapEndianness(experience,24))) print(('Experience : %d'):format(utils.SwapEndianness(experience,16)))
local money = blocks[8]:sub(7,10) local money = blocks[8]:sub(7,10)
print(('Money : %d'):format(utils.SwapEndianness(money,16))) print(('Money : %d'):format(utils.SwapEndianness(money,16)))
--
-- Sequence number
local seqnum = blocks[8]:sub(18,19)
print(('Sequence number : %d'):format( tonumber(seqnum,16)))
local fairy = blocks[9]:sub(1,8) local fairy = blocks[9]:sub(1,8)
--FD0F = Left, FF0F = Right --FD0F = Left, FF0F = Right
local path = 'not choosen' local path = 'not choosen'
@ -425,6 +427,12 @@ local function main(args)
local hat = blocks[9]:sub(8,11) local hat = blocks[9]:sub(8,11)
print(('Hat : %d'):format(utils.SwapEndianness(hat,16))) print(('Hat : %d'):format(utils.SwapEndianness(hat,16)))
local level = blocks[13]:sub(27,28)
print(('LEVEL : %d'):format( tonumber(level,16)))
--hälsa: 667 029b
--local health = blocks[]:sub();
--print(('Health : %d'):format( tonumber(health,16))
--0x0D 0x29 0x0A 0x02 16-bit hero points value. Maximum 100. --0x0D 0x29 0x0A 0x02 16-bit hero points value. Maximum 100.
local heropoints = blocks[13]:sub(20,23) local heropoints = blocks[13]:sub(20,23)
@ -434,6 +442,11 @@ local function main(args)
local challenges = blocks[16]:sub(25,32) local challenges = blocks[16]:sub(25,32)
print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32))) print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
-- Character Name
local name1 = blocks[10]:sub(1,32)
local name2 = blocks[12]:sub(1,32)
print('Custom name : '..utils.ConvertHexToAscii(name1..name2))
if maxed then if maxed then
print('Lets try to max out some values') print('Lets try to max out some values')
-- max out money, experience -- max out money, experience

View file

@ -112,6 +112,7 @@ char * sprint_hex(const uint8_t * data, const size_t len) {
int maxLen = ( len > 1024/3) ? 1024/3 : len; int maxLen = ( len > 1024/3) ? 1024/3 : len;
static char buf[1024]; static char buf[1024];
memset(buf, 0x00, 1024);
char * tmp = buf; char * tmp = buf;
size_t i; size_t i;
@ -123,8 +124,9 @@ char * sprint_hex(const uint8_t * data, const size_t len) {
char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) { char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) {
int maxLen = ( len > 1024) ? 1024 : len; int maxLen = ( len > 1020) ? 1020 : len;
static char buf[1024]; static char buf[1024];
memset(buf, 0x00, 1024);
char *tmp = buf; char *tmp = buf;
for (size_t i=0; i < maxLen; ++i){ for (size_t i=0; i < maxLen; ++i){
@ -158,6 +160,22 @@ uint64_t bytes_to_num(uint8_t* src, size_t len)
return num; return num;
} }
// aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp
// to
// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii
// up to 64 bytes or 512 bits
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
static uint8_t buf[64];
memset(buf, 0x00, 64);
uint8_t *tmp = buf;
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
for (size_t i = 0; i < blockSize; i++){
tmp[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
}
}
return tmp;
}
//assumes little endian //assumes little endian
char * printBits(size_t const size, void const * const ptr) char * printBits(size_t const size, void const * const ptr)
{ {

View file

@ -44,6 +44,7 @@ char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t bre
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len); uint64_t bytes_to_num(uint8_t* src, size_t len);
char * printBits(size_t const size, void const * const ptr); char * printBits(size_t const size, void const * const ptr);
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
char param_getchar(const char *line, int paramnum); char param_getchar(const char *line, int paramnum);
uint8_t param_get8(const char *line, int paramnum); uint8_t param_get8(const char *line, int paramnum);

85
common/crc64.c Normal file
View file

@ -0,0 +1,85 @@
#include <stdint.h>
#include <stddef.h>
#include "crc64.h"
#define CRC64_ISO_PRESET 0xFFFFFFFFFFFFFFFF
#define CRC64_ECMA_PRESET 0x0000000000000000
const uint64_t crc64_table[] = {
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285,
0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4,
0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B,
0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B,
0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5,
0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A,
0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584,
0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B,
0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A,
0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5,
0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A,
0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645,
0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324,
0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75,
0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA,
0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB,
0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14,
0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B,
0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA,
0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425,
0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB,
0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15,
0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA,
0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78,
0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7,
0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6,
0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19,
0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97,
0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648,
0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329,
0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6,
0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879,
0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18,
0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7,
0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149,
0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96,
0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7,
0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428,
0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57,
0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9,
0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8,
0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767,
0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9,
0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589,
0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37,
0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066,
0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9,
0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8,
0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507
};
void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) {
for (size_t i = 0; i < len; i++)
{
//uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
*crc = crc64_table[tableIndex] ^ (*crc << 8);
}
}
//suint8_t x = (c & 0xFF00000000000000 ) >> 56;

14
common/crc64.h Normal file
View file

@ -0,0 +1,14 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
// CRC64 ECMA
//-----------------------------------------------------------------------------
#ifndef __CRC64_H
#define __CRC64_H
void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) ;
#endif

View file

@ -123,9 +123,21 @@ NXP/Philips CUSTOM COMMANDS
#define MIFARE_CMD_RESTORE 0xC2 #define MIFARE_CMD_RESTORE 0xC2
#define MIFARE_CMD_TRANSFER 0xB0 #define MIFARE_CMD_TRANSFER 0xB0
#define MIFARE_ULC_WRITE 0xA0 #define MIFARE_ULC_WRITE 0xA2
//#define MIFARE_ULC__COMP_WRITE 0xA0
#define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_1 0x1A
#define MIFARE_ULC_AUTH_2 0xAF #define MIFARE_ULC_AUTH_2 0xAF
#define MIFARE_ULEV1_AUTH 0x1B
#define MIFARE_ULEV1_VERSION 0x60
#define MIFARE_ULEV1_FASTREAD 0x3A
//#define MIFARE_ULEV1_WRITE 0xA2
//#define MIFARE_ULEV1_COMP_WRITE 0xA0
#define MIFARE_ULEV1_READ_CNT 0x39
#define MIFARE_ULEV1_INCR_CNT 0xA5
#define MIFARE_ULEV1_READSIG 0x3C
#define MIFARE_ULEV1_CHECKTEAR 0x3E
#define MIFARE_ULEV1_VCSL 0x4B
/** /**
06 00 = INITIATE 06 00 = INITIATE

View file

@ -132,8 +132,8 @@ typedef struct{
#define CMD_SNOOP_ICLASS 0x0392 #define CMD_SNOOP_ICLASS 0x0392
#define CMD_SIMULATE_TAG_ICLASS 0x0393 #define CMD_SIMULATE_TAG_ICLASS 0x0393
#define CMD_READER_ICLASS 0x0394 #define CMD_READER_ICLASS 0x0394
#define CMD_READER_ICLASS_REPLAY 0x0395 #define CMD_READER_ICLASS_REPLAY 0x0395
#define CMD_ICLASS_ISO14443A_WRITE 0x0397 #define CMD_ICLASS_ISO14443A_WRITE 0x0397
#define CMD_ICLASS_EML_MEMSET 0x0398 #define CMD_ICLASS_EML_MEMSET 0x0398
// For measurements of the antenna tuning // For measurements of the antenna tuning
@ -163,20 +163,21 @@ typedef struct{
#define CMD_MIFARE_NESTED 0x0612 #define CMD_MIFARE_NESTED 0x0612
#define CMD_MIFARE_READBL 0x0620 #define CMD_MIFARE_READBL 0x0620
#define CMD_MIFAREU_READBL 0x0720 #define CMD_MIFAREU_READBL 0x0720
#define CMD_MIFARE_READSC 0x0621 #define CMD_MIFARE_READSC 0x0621
#define CMD_MIFAREU_READCARD 0x0721 #define CMD_MIFAREU_READCARD 0x0721
#define CMD_MIFARE_WRITEBL 0x0622 #define CMD_MIFARE_WRITEBL 0x0622
#define CMD_MIFAREU_WRITEBL 0x0722 #define CMD_MIFAREU_WRITEBL 0x0722
#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 #define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
#define CMD_MIFARE_CHKKEYS 0x0623 #define CMD_MIFARE_CHKKEYS 0x0623
#define CMD_MIFARE_SNIFFER 0x0630 #define CMD_MIFARE_SNIFFER 0x0630
//ultralightC //ultralightC
#define CMD_MIFAREUC_AUTH1 0x0724 #define CMD_MIFAREUC_AUTH 0x0724
#define CMD_MIFAREUC_AUTH2 0x0725 //0x0725 and 0x0726 no longer used
#define CMD_MIFAREUC_READCARD 0x0726 #define CMD_MIFAREUC_SETPWD 0x0727
// mifare desfire // mifare desfire
#define CMD_MIFARE_DESFIRE_READBL 0x0728 #define CMD_MIFARE_DESFIRE_READBL 0x0728
@ -199,10 +200,11 @@ typedef struct{
//Iclass reader flags //Iclass reader flags
#define FLAG_ICLASS_READER_ONLY_ONCE 0x01 #define FLAG_ICLASS_READER_ONLY_ONCE 0x01
#define FLAG_ICLASS_READER_CC 0x02 #define FLAG_ICLASS_READER_CC 0x02
#define FLAG_ICLASS_READER_CSN 0x04 #define FLAG_ICLASS_READER_CSN 0x04
#define FLAG_ICLASS_READER_CONF 0x08 #define FLAG_ICLASS_READER_CONF 0x08
#define FLAG_ICLASS_READER_AA 0x10 #define FLAG_ICLASS_READER_AA 0x10
#define FLAG_ICLASS_READER_ONE_TRY 0x20