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

@ -824,19 +824,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
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);

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

@ -1688,13 +1688,15 @@ void ReaderIClass(uint8_t arg0) {
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;

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,105 +92,88 @@ 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;
byte_t dataoutbuf[16] = {0x00};
uint8_t uid[10] = {0x00};
uint32_t cuid;
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
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)
DbpString("AUTH 1 FINISHED");
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;
}
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); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
}
cmd_send(CMD_ACK,1,0,0,0,0);
} }
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 ) {
uint8_t key[16] = {0x00};
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"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
//OnError(2); 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);
@ -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 ) {
uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key) );
len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i); if ( !mifare_ultra_auth(key) ) {
OnError(1);
return;
}
}
// 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 (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i);
Dbprintf("Read block %d error",i); // if no blocks read - error out
//OnError(2); if (i==0){
OnError(2);
return; return;
} else { } else {
count_Pages++; //stop at last successful read block and return what we got
break;
}
} else {
countblocks++;
} }
} }
len = mifare_ultra_halt(cuid); 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) { if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks);
Dbprintf("Pages read %d", count_Pages);
}
len = 16*4; //64 bytes countblocks *= 4;
cmd_send(CMD_ACK, 1, countblocks, countblocks, 0, 0);
// Read a UL-C
if (Pages == 44 && count_Pages > 16)
len = 176;
cmd_send(CMD_ACK, 1, 0, 0, dataout, len);
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;
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);
LED_A_ON(); if(!iso14443a_select_card(uid, NULL, NULL)) {
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break; OnError(0);
return;
}; };
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) { if(mifare_ultra_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break; OnError(0);
}; return; };
if(mifare_ultra_halt(cuid)) { if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break; OnError(0);
return;
}; };
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); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{ {
// params
uint8_t blockNo = arg0; uint8_t blockNo = arg0;
byte_t blockdata[4] = {0x00}; byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4); memcpy(blockdata, datain,4);
// variables LEDsoff();
byte_t isOK = 0; LED_A_ON();
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(NULL, NULL, NULL)) {
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break; OnError(0);
return;
}; };
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) { if(mifare_ultra_special_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break; OnError(0);
return;
}; };
if(mifare_ultra_halt(cuid)) { if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break; OnError(0);
return;
}; };
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 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;
@ -110,6 +111,27 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
return len; return len;
} }
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[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) 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]; uint8_t dcmd[4], ecmd[4];
@ -288,82 +310,135 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
} }
// 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};
memcpy(key, keybytes, 4);
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);
if (len == 1) { len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL);
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (len != 4) {
Dbprintf("Cmd Error: %02x", receivedAnswer[0]); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);
return 1;
}
if (len != 11)
return 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("Auth1 Resp: %02x%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; return 0;
}
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_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ 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; uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t resp[19] = {0x00};
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t respPar[3] = {0,0,0};
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL); // REQUEST AUTHENTICATION
if (len == 1) { len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, resp, respPar ,NULL);
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (len != 11) {
Dbprintf("Cmd Error: %02x", receivedAnswer[0]); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 1; return 0;
} }
if (len != 11)
return 1; // 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("Auth2 Resp: %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]);
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] );
} }
memcpy(blockData, receivedAnswer, 11);
// 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; 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(uint32_t uid, uint8_t blockNo, uint8_t *blockData) int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
{ {
uint16_t len; uint16_t len;
uint8_t bt[2]; uint8_t bt[2];
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];
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) { if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1; return 1;
} }
if (len != 18) { if (len != 18) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);
Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2; return 2;
} }
memcpy(bt, receivedAnswer + 16, 2); memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16); AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");
Dbprintf("Cmd CRC response error.");
return 3; return 3;
} }
@ -371,7 +446,6 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
return 0; return 0;
} }
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)
{ {
// variables // variables
@ -419,13 +493,13 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
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_MIFARE_FRAME_SIZE]; uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK // command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
@ -451,7 +525,7 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
return 0; return 0;
} }
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)
{ {
uint16_t len; uint16_t len;
uint8_t d_block[8] = {0x00}; uint8_t d_block[8] = {0x00};
@ -489,7 +563,7 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
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];
@ -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) {

View file

@ -57,19 +57,20 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd,
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_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_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);

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[] =
{ {
@ -517,6 +589,7 @@ static command_t CommandTable[] =
{"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;
if (verbose)
PrintAndLog("Readstatus:%02x", readStatus); 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,9 +135,7 @@ 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_READCARD = 0x0726,
CMD_MIFAREUC_SETPWD = 0x0727, CMD_MIFAREUC_SETPWD = 0x0727,
CMD_MIFAREU_SETUID = 0x0728, CMD_MIFAREU_SETUID = 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,
} }

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
@ -86,6 +86,21 @@ local Utils =
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,
@ -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
if not reverse then
return t 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:
@ -230,7 +231,7 @@ static int l_iso15693_crc(lua_State *L)
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;
@ -245,20 +246,12 @@ static int l_aes(lua_State *L)
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);
@ -267,6 +260,34 @@ static int l_aes(lua_State *L)
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
} }
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));
return 1;// return 1 to signal one return value
}
static int l_crc16(lua_State *L) static int l_crc16(lua_State *L)
{ {
@ -278,6 +299,28 @@ static int l_crc16(lua_State *L)
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;
}
/** /**
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
* able to do "require('foobar')" if foobar.lua is within lualibs folder. * able to do "require('foobar')" if foobar.lua is within lualibs folder.
@ -298,6 +341,7 @@ int setLuaPath( lua_State* L, const char* path )
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
free(buf);
return 0; // all done! return 0; // all done!
} }
@ -315,8 +359,10 @@ int set_pm3_libraries(lua_State *L)
{"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},
{"crc64", l_crc64},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -80,7 +80,7 @@ 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

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
]] ]]
@ -98,10 +100,11 @@ 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
@ -140,7 +143,8 @@ local function main(args)
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..'00000000000000000000'..subtype local b1 = toytype..string.rep('00',10)..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

@ -217,6 +217,7 @@ local function main(args)
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'
@ -426,6 +428,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)
print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16))) print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16)))
@ -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,10 +123,22 @@ 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
0E xx = SELECT ID (xx = Chip-ID) 0E xx = SELECT ID (xx = Chip-ID)

View file

@ -174,9 +174,10 @@ typedef struct{
#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
@ -203,6 +204,7 @@ typedef struct{
#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