Beginning of Ultralight additions.
detection of Ultralight Types added
dump command now auto detects type
can authenticate Ultralight C
ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
break;
#endif
-
+
#ifdef WITH_ISO15693
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
AcquireRawAdcSamplesIso15693();
break;
case CMD_READER_MIFARE:
- ReaderMifare(c->arg[0]);
+ ReaderMifare(c->arg[0]);
break;
case CMD_MIFARE_READBL:
MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFAREU_READBL:
- MifareUReadBlock(c->arg[0],c->d.asBytes);
+ MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
break;
case CMD_MIFAREUC_AUTH1:
MifareUC_Auth1(c->arg[0],c->d.asBytes);
case CMD_MIFAREUC_READCARD:
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
break;
+ case CMD_MIFAREUC_SETPWD:
+ MifareUSetPwd(c->arg[0], c->d.asBytes);
+ break;
case CMD_MIFARE_READSC:
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
break;
case CMD_MIFAREU_WRITEBL_COMPAT:
MifareUWriteBlock(c->arg[0], c->d.asBytes);
- break;
+ break;
case CMD_MIFAREU_WRITEBL:
- MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
- break;
+ MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
+ break;
case CMD_MIFARE_NESTED:
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
void ReaderMifare(bool first_try);
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 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_Auth2(uint32_t arg0, uint8_t *datain);
void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
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 MifareCIdent(); // is "magic chinese" card?
+void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
//desfire
void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);
des_dec(out, out, (uint8_t*)key + 0);
}
+void tdes_2key_enc(void* out, const void* in, size_t length, const void* key){
+
+ if( length % 8 ) return;
+
+ uint8_t* tin = (uint8_t*) in;
+ uint8_t* tout = (uint8_t*) out;
+
+ while( length > 0 )
+ {
+ des_enc(tout, tin, (uint8_t*)key + 0);
+ des_dec(tout, tout, (uint8_t*)key + 8);
+ des_enc(tout, tout, (uint8_t*)key + 0);
+
+ tin += 8;
+ tout += 8;
+ length -= 8;
+ }
+}
+
+void tdes_2key_dec(void* out, const void* in, size_t length, const void* key){
+
+ if( length % 8 ) return;
+
+ uint8_t* tin = (uint8_t*) in;
+ uint8_t* tout = (uint8_t*) out;
+
+ while( length > 0 )
+ {
+ des_dec(tout, tin, (uint8_t*)key + 0);
+ des_enc(tout, tout, (uint8_t*)key + 8);
+ des_dec(tout, tout, (uint8_t*)key + 0);
+
+ tin += 8;
+ tout += 8;
+ length -= 8;
+ }
+}
+
+
/******************************************************************************/
*/
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);
+ void tdes_2key_dec(void* out, const void* in, size_t length, const void* key);
+
#endif /*DES_H_*/
// Copied from des.h in desfire imp.
#include "apps.h"\r
#include "util.h"\r
\r
+#include "des.h"\r
#include "crc.h"\r
\r
+// the block number for the ISO14443-4 PCB\r
+uint8_t pcb_blocknum = 0;\r
+// Deselect card by sending a s-block. the crc is precalced for speed\r
+static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};\r
+\r
+\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Read a MIFARE tag. \r
// read block\r
LEDsoff();\r
}\r
\r
-\r
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){\r
\r
- byte_t isOK = 0;\r
byte_t dataoutbuf[16] = {0x00};\r
uint8_t uid[10] = {0x00};\r
- uint32_t cuid;\r
+ uint32_t cuid = 0x00;\r
\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
\r
clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Can't select card");\r
- //OnError(0);\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+ OnError(0);\r
return;\r
};\r
\r
- if(mifare_ultra_auth1(cuid, dataoutbuf)){\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
- Dbprintf("Authentication part1: Fail.");\r
- //OnError(1);\r
+ if(mifare_ultra_auth1(dataoutbuf)){\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail.");\r
+ OnError(1);\r
return;\r
}\r
\r
- isOK = 1;\r
- if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
- DbpString("AUTH 1 FINISHED");\r
+ if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
\r
- cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);\r
+ cmd_send(CMD_ACK,1,cuid,0,dataoutbuf,11);\r
LEDsoff();\r
}\r
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){\r
\r
- uint32_t cuid = arg0;\r
uint8_t key[16] = {0x00};\r
- byte_t isOK = 0;\r
byte_t dataoutbuf[16] = {0x00};\r
\r
memcpy(key, datain, 16);\r
\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
\r
- if(mifare_ultra_auth2(cuid, key, dataoutbuf)){\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
- Dbprintf("Authentication part2: Fail...");\r
- //OnError(1);\r
+ if(mifare_ultra_auth2(key, dataoutbuf)){\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part2: Fail...");\r
+ OnError(1);\r
return; \r
}\r
\r
- isOK = 1;\r
- if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
- DbpString("AUTH 2 FINISHED");\r
+ if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");\r
\r
- cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);\r
+ cmd_send(CMD_ACK,1,0,0,dataoutbuf,11);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain)\r
+void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
{\r
uint8_t blockNo = arg0;\r
byte_t dataout[16] = {0x00};\r
uint8_t uid[10] = {0x00};\r
- uint32_t cuid;\r
- \r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
- \r
+ uint8_t key[16] = {0x00};\r
+ bool usePwd = (arg1 == 1);\r
+\r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
+\r
clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- \r
- int len = iso14443a_select_card(uid, NULL, &cuid);\r
+\r
+ int len = iso14443a_select_card(uid, NULL, NULL);\r
if(!len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
- //OnError(1);\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);\r
+ OnError(1);\r
return;\r
- };\r
- \r
- len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
- if(len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
- //OnError(2);\r
+ }\r
+\r
+ // authenticate here.\r
+ if ( usePwd ) {\r
+\r
+ memcpy(key, datain, 16);\r
+\r
+ // Dbprintf("KEY: %02x %02x %02x %02x %02x %02x %02x %02x", key[0],key[1],key[2],key[3],key[4],key[5],key[6],key[7] );\r
+ // Dbprintf("KEY: %02x %02x %02x %02x %02x %02x %02x %02x", key[8],key[9],key[10],key[11],key[12],key[13],key[14],key[15] );\r
+\r
+ uint8_t a[8] = {1,1,1,1,1,1,1,1 };\r
+ uint8_t b[8] = {0x00};\r
+ uint8_t enc_b[8] = {0x00};\r
+ uint8_t ab[16] = {0x00};\r
+ uint8_t enc_ab[16] = {0x00};\r
+ uint8_t enc_key[8] = {0x00};\r
+ \r
+ uint16_t len;\r
+ uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
+\r
+ len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
+ if (len != 11) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ OnError(1);\r
+ return;\r
+ }\r
+\r
+ // tag nonce.\r
+ memcpy(enc_b,receivedAnswer+1,8);\r
+\r
+ // decrypt nonce.\r
+ tdes_2key_dec(b, enc_b, 8, key );\r
+\r
+ Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] );\r
+ Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x", b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7] );\r
+ rol(b,8);\r
+ \r
+ memcpy(ab ,a,8);\r
+ memcpy(ab+8,b,8);\r
+\r
+ Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );\r
+ Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );\r
+\r
+ // encrypt\r
+ tdes_2key_enc(enc_ab, ab, 16, key);\r
+\r
+ Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", enc_ab[0],enc_ab[1],enc_ab[2],enc_ab[3],enc_ab[4],enc_ab[5],enc_ab[6],enc_ab[7] );\r
+ Dbprintf("e_enc_ab: %02x %02x %02x %02x %02x %02x %02x %02x", enc_ab[8],enc_ab[9],enc_ab[10],enc_ab[11],enc_ab[12],enc_ab[13],enc_ab[14],enc_ab[15] );\r
+\r
+ len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, enc_ab, receivedAnswer, receivedAnswerPar, NULL);\r
+ if (len != 11) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ OnError(1);\r
+ return;\r
+ }\r
+\r
+ // the tags' encryption of our nonce, A.\r
+ memcpy(enc_key, receivedAnswer+1, 8);\r
+ \r
+ // clear B.\r
+ memset(b, 0x00, 8);\r
+\r
+ // decrypt \r
+ tdes_2key_dec(b, enc_key, 8, key );\r
+ if ( memcmp(a, b, 8) == 0 )\r
+ Dbprintf("Verified key");\r
+ else\r
+ Dbprintf("failed authentication");\r
+ \r
+ Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x", a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7] );\r
+ Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x", b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7] );\r
+ }\r
+\r
+ if( mifare_ultra_readblock(blockNo, dataout) ) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
+ OnError(2);\r
return;\r
- };\r
- \r
- len = mifare_ultra_halt(cuid);\r
- if(len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
- //OnError(3);\r
+ }\r
+\r
+ if( mifare_ultra_halt() ) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+ OnError(3);\r
return;\r
- };\r
- \r
- cmd_send(CMD_ACK,1,0,0,dataout,16);\r
+ }\r
+ \r
+ cmd_send(CMD_ACK,1,0,0,dataout,16);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
-\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Read a MIFARE tag. \r
// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)\r
\r
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
{\r
- // params\r
- uint8_t sectorNo = arg0;\r
+ // params\r
+ uint8_t sectorNo = arg0;\r
int Pages = arg1;\r
- int count_Pages = 0;\r
+ int countpages = 0;\r
byte_t dataout[176] = {0x00};;\r
- uint8_t uid[10] = {0x00};\r
- uint32_t cuid;\r
+ uint32_t cuid = 0x00;\r
\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
-\r
- if (MF_DBGLEVEL >= MF_DBG_ALL) \r
- Dbprintf("Pages %d",Pages);\r
- \r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
- int len = iso14443a_select_card(uid, NULL, &cuid);\r
- \r
+ int len = iso14443a_select_card(NULL, NULL, &cuid);\r
if (!len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Can't select card");\r
- //OnError(1);\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
+ OnError(1);\r
return;\r
}\r
\r
for (int i = 0; i < Pages; i++){\r
\r
- len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);\r
+ len = mifare_ultra_readblock(sectorNo * 4 + i, dataout + 4 * i);\r
\r
if (len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Read block %d error",i);\r
- //OnError(2);\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i);\r
+ OnError(2);\r
return;\r
} else {\r
- count_Pages++;\r
+ countpages++;\r
}\r
}\r
\r
- len = mifare_ultra_halt(cuid);\r
+ len = mifare_ultra_halt();\r
if (len) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Halt error");\r
- //OnError(3);\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+ OnError(3);\r
return;\r
}\r
\r
- if (MF_DBGLEVEL >= MF_DBG_ALL) {\r
- Dbprintf("Pages read %d", count_Pages);\r
- }\r
+ if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Pages read %d", countpages);\r
+\r
+// len = 16*4; //64 bytes\r
\r
- len = 16*4; //64 bytes\r
- \r
// Read a UL-C\r
- if (Pages == 44 && count_Pages > 16) \r
- len = 176;\r
+// if (Pages == 44 && countpages > 16) \r
+// len = 176;\r
+ len = Pages * 4;\r
\r
cmd_send(CMD_ACK, 1, 0, 0, dataout, len); \r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
-\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Write a MIFARE tag. \r
// read block\r
\r
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)\r
{\r
- // params\r
- uint8_t blockNo = arg0;\r
+ uint8_t blockNo = arg0;\r
byte_t blockdata[16] = {0x00};\r
\r
- memcpy(blockdata, datain,16);\r
- \r
- // variables\r
- byte_t isOK = 0;\r
+ memcpy(blockdata, datain, 16);\r
+\r
uint8_t uid[10] = {0x00};\r
- uint32_t cuid;\r
\r
- clear_trace();\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
-\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
- };\r
-\r
- if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
- break;\r
- };\r
-\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
- };\r
- \r
- isOK = 1;\r
- break;\r
- }\r
- \r
- if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
-\r
- cmd_send(CMD_ACK,isOK,0,0,0,0);\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
+ clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+ if(!iso14443a_select_card(uid, NULL, NULL)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ OnError(0);\r
+ return;\r
+ };\r
+\r
+ if(mifare_ultra_writeblock(blockNo, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(0);\r
+ return; };\r
+\r
+ if(mifare_ultra_halt()) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ OnError(0);\r
+ return;\r
+ };\r
+\r
+ if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
+\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
}\r
\r
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)\r
{\r
- // params\r
uint8_t blockNo = arg0;\r
byte_t blockdata[4] = {0x00};\r
\r
memcpy(blockdata, datain,4);\r
\r
- // variables\r
- byte_t isOK = 0;\r
uint8_t uid[10] = {0x00};\r
- uint32_t cuid;\r
+ \r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
+ clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+ if(!iso14443a_select_card(uid, NULL, NULL)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ OnError(0);\r
+ return;\r
+ };\r
\r
+ if(mifare_ultra_special_writeblock(blockNo, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(0);\r
+ return;\r
+ };\r
+\r
+ if(mifare_ultra_halt()) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ OnError(0);\r
+ return;\r
+ };\r
+\r
+ if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
+\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+}\r
+\r
+void MifareUSetPwd(uint8_t arg0, uint8_t *datain){\r
+ \r
+ uint8_t pwd[16] = {0x00};\r
+ byte_t blockdata[4] = {0x00};\r
+ \r
+ memcpy(pwd, datain, 16);\r
+ \r
+ LED_A_ON(); LED_B_OFF(); LED_C_OFF();\r
clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
+ if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ OnError(0);\r
+ return;\r
+ };\r
\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
- };\r
+ blockdata[0] = pwd[7];\r
+ blockdata[1] = pwd[6];\r
+ blockdata[2] = pwd[5];\r
+ blockdata[3] = pwd[4];\r
+ if(mifare_ultra_special_writeblock( 44, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(44);\r
+ return;\r
+ };\r
\r
- if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
- break;\r
- };\r
+ blockdata[0] = pwd[3];\r
+ blockdata[1] = pwd[2];\r
+ blockdata[2] = pwd[1];\r
+ blockdata[3] = pwd[0];\r
+ if(mifare_ultra_special_writeblock( 45, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(45);\r
+ return;\r
+ };\r
\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
- };\r
+ blockdata[0] = pwd[15];\r
+ blockdata[1] = pwd[14];\r
+ blockdata[2] = pwd[13];\r
+ blockdata[3] = pwd[12];\r
+ if(mifare_ultra_special_writeblock( 46, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(46);\r
+ return;\r
+ };\r
\r
- isOK = 1;\r
- break;\r
- }\r
+ blockdata[0] = pwd[11];\r
+ blockdata[1] = pwd[10];\r
+ blockdata[2] = pwd[9];\r
+ blockdata[3] = pwd[8];\r
+ if(mifare_ultra_special_writeblock( 47, blockdata)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ OnError(47);\r
+ return;\r
+ }; \r
\r
- if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
+ if(mifare_ultra_halt()) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ OnError(0);\r
+ return;\r
+ };\r
\r
- cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
+\r
+void OnSuccess(){\r
+ pcb_blocknum = 0;\r
+ ReaderTransmit(deselect_cmd, 3 , NULL);\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+}\r
+\r
+void OnError(uint8_t reason){\r
+ pcb_blocknum = 0;\r
+ ReaderTransmit(deselect_cmd, 3 , NULL);\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ cmd_send(CMD_ACK,0,reason,0,0,0);\r
+ LEDsoff();\r
+}\r
// send commands\r
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)\r
{\r
- return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);
-}
-
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
-{
- uint8_t dcmd[8];
- dcmd[0] = cmd;
- dcmd[1] = data[0];
- dcmd[2] = data[1];
- dcmd[3] = data[2];
- dcmd[4] = data[3];
- dcmd[5] = data[4];
- AppendCrc14443a(dcmd, 6);
- ReaderTransmit(dcmd, sizeof(dcmd), NULL);
- int len = ReaderReceive(answer, answer_parity);
- if(!len) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
- return 2;
+ return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);\r
+}\r
+\r
+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)\r
+{\r
+ uint8_t dcmd[8];\r
+ dcmd[0] = cmd;\r
+ dcmd[1] = data[0];\r
+ dcmd[2] = data[1];\r
+ dcmd[3] = data[2];\r
+ dcmd[4] = data[3];\r
+ dcmd[5] = data[4];\r
+ AppendCrc14443a(dcmd, 6);\r
+ ReaderTransmit(dcmd, sizeof(dcmd), NULL);\r
+ int len = ReaderReceive(answer, answer_parity);\r
+ if(!len) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");\r
+ return 2;\r
}\r
return len;\r
}\r
if(len==1) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed.");\r
return 1;\r
- }
- return len;
-}
-
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
-{
- uint8_t dcmd[4], ecmd[4];
+ }\r
+ return len;\r
+}\r
+\r
+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)\r
+{\r
+ uint8_t dcmd[4], ecmd[4];\r
uint16_t pos, res;\r
uint8_t par[1]; // 1 Byte parity is enough here\r
dcmd[0] = cmd;\r
}\r
\r
memcpy(blockData, receivedAnswer, 16);\r
- return 0;
-}
-
+ return 0;\r
+}\r
+\r
// mifare ultralight commands\r
-int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){\r
+int mifare_ultra_auth1(uint8_t *blockData){\r
\r
uint16_t len;\r
- uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
- uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+ uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
\r
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
- if (len == 1) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ if (len != 11) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
return 1;\r
}\r
- if (len != 11)\r
- return 1;\r
\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",\r
return 0;\r
}\r
\r
-int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){\r
+int mifare_ultra_auth2(uint8_t *key, uint8_t *blockData){\r
\r
uint16_t len;\r
- uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
- uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+ uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
\r
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);\r
- if (len == 1) {\r
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ if (len != 11) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
return 1;\r
}\r
- if (len != 11)\r
- return 1; \r
\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {\r
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",\r
return 0;\r
}\r
\r
-int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
- uint16_t len;
- uint8_t bt[2];
- uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
- uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-
+int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)\r
+{\r
+ uint16_t len;\r
+ uint8_t bt[2];\r
+ uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
\r
- // command MIFARE_CLASSIC_READBLOCK
- len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
- if (len == 1) {
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
- return 1;
- }
- if (len != 18) {
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Error: card timeout. len: %x", len);
- return 2;
- }
-
- memcpy(bt, receivedAnswer + 16, 2);
- AppendCrc14443a(receivedAnswer, 16);
- if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
- if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd CRC response error.");
- return 3;
- }
-
- memcpy(blockData, receivedAnswer, 14);
- return 0;
-}
-
-
-int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
- // variables
+ len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ if (len == 1) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ return 1;\r
+ }\r
+ if (len != 18) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);\r
+ return 2;\r
+ }\r
+ \r
+ memcpy(bt, receivedAnswer + 16, 2);\r
+ AppendCrc14443a(receivedAnswer, 16);\r
+ if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");\r
+ return 3;\r
+ }\r
+ \r
+ memcpy(blockData, receivedAnswer, 14);\r
+ return 0;\r
+}\r
+\r
+\r
+\r
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) \r
+{\r
+ // variables\r
uint16_t len, i; \r
uint32_t pos;\r
uint8_t par[3] = {0}; // enough for 18 Bytes to send\r
return 2;\r
}\r
\r
- return 0;
-}
-
-int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
- uint16_t len;
- uint8_t par[3] = {0}; // enough for 18 parity bits
- uint8_t d_block[18] = {0x00};
- uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
- uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-
- // command MIFARE_CLASSIC_WRITEBLOCK
- len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
-
- if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
+ return 0;\r
+}\r
+\r
+int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) \r
+{\r
+ uint16_t len;\r
+ uint8_t par[3] = {0}; // enough for 18 parity bits\r
+ uint8_t d_block[18] = {0x00};\r
+ uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
+\r
+ // command MIFARE_CLASSIC_WRITEBLOCK\r
+ len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+\r
+ if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
- return 1;
- }
-
- memcpy(d_block, blockData, 16);
- AppendCrc14443a(d_block, 16);
-
- ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
-
- len = ReaderReceive(receivedAnswer, receivedAnswerPar);
-
- if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
+ Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);\r
+ return 1;\r
+ }\r
+\r
+ memcpy(d_block, blockData, 16);\r
+ AppendCrc14443a(d_block, 16);\r
+\r
+ ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);\r
+\r
+ len = ReaderReceive(receivedAnswer, receivedAnswerPar);\r
+\r
+ if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
- return 2;
- }
- return 0;
-}
-
-int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
-{
- uint16_t len;
- uint8_t d_block[8] = {0x00};
+ Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);\r
+ return 2;\r
+ }\r
+ return 0;\r
+}\r
+\r
+int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData)\r
+{\r
+ uint16_t len;\r
+ uint8_t d_block[8] = {0x00};\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-
- // command MIFARE_CLASSIC_WRITEBLOCK
- d_block[0]= blockNo;
- memcpy(d_block+1,blockData,4);
- AppendCrc14443a(d_block, 6);
-
- len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
-
- if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
+\r
+ // command MIFARE_CLASSIC_WRITEBLOCK\r
+ d_block[0]= blockNo;\r
+ memcpy(d_block+1,blockData,4);\r
+ AppendCrc14443a(d_block, 6);\r
+\r
+ len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);\r
+\r
+ if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
- return 1;
- }
-\r return 0;
-}
-
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
-{
+ Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) \r
+{\r
uint16_t len; \r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
return 1;\r
}\r
\r
- return 0;
-}
-
-int mifare_ultra_halt(uint32_t uid)
-{
- uint16_t len;
+ return 0;\r
+}\r
+\r
+int mifare_ultra_halt()\r
+{\r
+ uint16_t len;\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
-
- len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
- if (len != 0) {
+ \r
+ len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
+ if (len != 0) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
- Dbprintf("halt error. response len: %x", len);
- return 1;
- }
- return 0;
-}
-
+ Dbprintf("halt error. response len: %x", len);\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
\r
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),\r
// plus evtl. 8 sectors with 16 blocks each (4k cards)\r
}\r
\r
\r
-// work with emulator memory
-void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
- uint8_t* emCARD = BigBuf_get_EM_addr();
+// work with emulator memory\r
+void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r
+ uint8_t* emCARD = BigBuf_get_EM_addr();\r
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);\r
}\r
\r
return 0;\r
}\r
return 1;\r
-}
+}\r
\r
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();\r
\r
-//functions
-int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
-int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
+//functions\r
+int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);\r
+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);\r
\r
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);\r
-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);\r
+\r
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);\r
-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_ultra_auth1(uint32_t cuid, uint8_t *blockData);\r
-int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);\r
-int mifare_ultra_readblock(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_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
-int mifare_ultra_halt(uint32_t uid);
+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);\r
+int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); \r
+int mifare_ultra_auth1(uint8_t *blockData);\r
+int mifare_ultra_auth2(uint8_t *key, uint8_t *blockData);\r
+int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);\r
+int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData);\r
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); \r
+int mifare_ultra_halt();\r
\r
// desfire\r
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);\r
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing);\r
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);\r
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);\r
-
-// crypto functions
-void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
+\r
+// crypto functions\r
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);\r
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);\r
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);\r
\r
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);\r
uint64_t emlGetKey(int sectorNum, int keyType);\r
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);\r
-int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);
-int emlCheckValBl(int blockNum);
-
-#endif
+int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);\r
+int emlCheckValBl(int blockNum);\r
+\r
+#endif\r
//-----------------------------------------------------------------------------
// High frequency MIFARE ULTRALIGHT (C) commands
//-----------------------------------------------------------------------------
-//#include <openssl/des.h>
#include "loclass/des.h"
#include "cmdhfmfu.h"
#include "cmdhfmf.h"
#include "cmdhf14a.h"
+#include "mifare.h"
+#define MAX_UL_BLOCKS 0x0f
+#define MAX_ULC_BLOCKS 0x2f
+#define MAX_ULEV1a_BLOCKS 0x0b;
+#define MAX_ULEV1b_BLOCKS 0x20;
-#define MAX_ULTRA_BLOCKS 0x0f
-#define MAX_ULTRAC_BLOCKS 0x2f
-//#define MAX_ULTRAC_BLOCKS 0x2c
+uint8_t default_3des_keys[7][16] = {
+ { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
+ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
+ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
+ { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
+ { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones
+ { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF
+ { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
+ };
+
+static int CmdHelp(const char *Cmd);
+// return 1 if tag responded to 0x1A.
+uint8_t requestAuthentication( uint8_t* nonce){
-static int CmdHelp(const char *Cmd);
+ UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC ,2 ,0}};
+ c.d.asBytes[0] = 0x1A;
+ c.d.asBytes[1] = 0x00;
+ SendCommand(&c);
+ UsbCommand resp;
+ WaitForResponse(CMD_ACK, &resp); // skip select answer.
-int CmdHF14AMfUInfo(const char *Cmd){
+ if ( !(resp.arg[0] & 0xff) )
+ return 0;
+
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
+
+ if ( resp.arg[0] & 0xff ) {
+ memcpy(nonce, resp.d.asBytes+1, 8);
+ return 1;
+ }
+ }
+ return 0;
+}
- uint8_t datatemp[7] = {0x00};
+typedef enum TAGTYPE_UL {
+ UNKNOWN = 0x00,
+ UL = 0x01,
+ UL_C = 0x02,
+ UL_EV1_48 = 0x04,
+ UL_EV1_128 = 0x08,
+ UL_MAGIC = 0x11,
+ UL_C_MAGIC = 0x12,
+ MAGIC = 0x10,
+ UL_ERROR = 0xFF,
+} TagTypeUL_t;
+
+uint8_t GetHF14AMfU_Type(uint8_t *data, uint8_t dataSize){
+ TagTypeUL_t tagtype = UNKNOWN;
uint8_t isOK = 0;
- uint8_t *data = NULL;
UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
isOK = resp.arg[0] & 0xff;
- data = resp.d.asBytes;
+ memcpy(data, resp.d.asBytes, dataSize);
if (!isOK) {
PrintAndLog("Error reading from tag");
- return -1;
+ return UL_ERROR;
}
} else {
PrintAndLog("Command execute timed out");
- return -1;
+ return UL_ERROR;
}
- PrintAndLog("");
- PrintAndLog("-- Mifare Ultralight / Ultralight-C Tag Information ---------");
- PrintAndLog("-------------------------------------------------------------");
+ c.cmd = CMD_READER_ISO_14443a;
+ c.arg[0] = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC;
+ c.arg[1] = 1;
+ c.arg[2] = 0;
+ c.d.asBytes[0] = 0x60;
+ SendCommand(&c);
+ WaitForResponse(CMD_ACK, &resp);
+
+ if ( resp.arg[0] ) {
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
+ uint8_t version[8] = {0,0,0,0,0,0,0,0};
+ memcpy(&version, resp.d.asBytes, sizeof(version));
+ uint8_t len = resp.arg[0] & 0xff;
+
+ if ( len == 0x0A && version[6] == 0x0B )
+ tagtype = UL_EV1_48;
+ else if ( len == 0x0A && version[6] != 0x0B )
+ tagtype = UL_EV1_128;
+ else if ( len == 0x01 )
+ tagtype = UL_C;
+ else if ( len == 0x00 )
+ tagtype = UL; //| UL_MAGIC | UL_C_MAGIC
+ }
+ }
+
+ // Magic UL-C, mine have a static nonce response to 0x1A command.
+ uint8_t nonce1[8] = {0,0,0,0,0,0,0,0};
+ uint8_t nonce2[8] = {0,0,0,0,0,0,0,0};
+ uint8_t status = requestAuthentication(nonce1);
+ if ( status ) {
+ requestAuthentication(nonce2);
+ if ( !memcmp(nonce1, nonce2, 8) )
+ tagtype ^= MAGIC;
+ } else {
+ // Magic Ultralight test here - TODO
+ }
+ return tagtype;
+}
+
+int CmdHF14AMfUInfo(const char *Cmd){
+
+ TagTypeUL_t tagtype = UNKNOWN;
+
+ uint8_t datatemp[7] = {0x00};
+ uint8_t data[16] = {0x00};
+
+ tagtype = GetHF14AMfU_Type(data, sizeof(data));
+ if (tagtype == UL_ERROR) return -1;
+
+ PrintAndLog("\n-- Tag Information ---------");
+ PrintAndLog("-------------------------------------------------------------");
+ switch(tagtype){
+ case UNKNOWN : PrintAndLog(" TYPE : Unknown"); return 0;
+ case UL : PrintAndLog(" TYPE : MIFARE Ultralight");break;
+ case UL_C : PrintAndLog(" TYPE : MIFARE Ultralight C");break;
+ case UL_EV1_48 : PrintAndLog(" TYPE : MIFARE Ultralight EV1 48 bytes"); break;
+ case UL_EV1_128 : PrintAndLog(" TYPE : MIFARE Ultralight EV1 128 bytes"); break;
+ case UL_MAGIC : PrintAndLog(" TYPE : MIFARE Ultralight (MAGIC)");break;
+ case UL_C_MAGIC : PrintAndLog(" TYPE : MIFARE Ultralight-C (MAGIC)");break;
+ default : PrintAndLog(" TYPE : Unknown %x",tagtype);break;
+ }
+
// UID
memcpy( datatemp, data, 3);
memcpy( datatemp+3, data+4, 4);
- PrintAndLog("MANUFACTURER : %s", getTagInfo(datatemp[0]));
- PrintAndLog(" UID : %s ", sprint_hex(datatemp, 7));
+ PrintAndLog(" UID : %s ", sprint_hex(datatemp, 7));
+ PrintAndLog(" UID[0] : (Manufacturer Byte) = %02x, Manufacturer: %s", datatemp[0], getTagInfo(datatemp[0]) );
+
// BBC
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
if ( data[3] == crc0 )
- PrintAndLog(" BCC0 : %02x - Ok", data[3]);
+ PrintAndLog(" BCC0 : %02x - Ok", data[3]);
else
- PrintAndLog(" BCC0 : %02x - crc should be %02x", data[3], crc0);
+ PrintAndLog(" BCC0 : %02x - crc should be %02x", data[3], crc0);
int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
if ( data[8] == crc1 )
- PrintAndLog(" BCC1 : %02x - Ok", data[8]);
+ PrintAndLog(" BCC1 : %02x - Ok", data[8]);
else
- PrintAndLog(" BCC1 : %02x - crc should be %02x", data[8], crc1 );
+ PrintAndLog(" BCC1 : %02x - crc should be %02x", data[8], crc1 );
- PrintAndLog(" Internal : %s ", sprint_hex(data + 9, 1));
+ PrintAndLog(" Internal : %s ", sprint_hex(data + 9, 1));
memcpy(datatemp, data+10, 2);
- PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
- PrintAndLog(" OneTimePad : %s ", sprint_hex(data + 3*4, 4));
+ PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
+ PrintAndLog("OneTimePad : %s ", sprint_hex(data + 3*4, 4));
PrintAndLog("");
-
- int len = CmdHF14AMfucAuth("K 0");
-// PrintAndLog("CODE: %d",len);
- PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
+
+ PrintAndLog("--- ");
+ if ((tagtype & UL_C)){
+
+ PrintAndLog("Trying some default 3des keys");
+ uint8_t *key;
+
+ for (uint8_t i = 0; i < 5; ++i ){
+ key = default_3des_keys[i];
+ if (try3DesAuthentication(key)){
+ PrintAndLog("Found default 3des key: %s", sprint_hex(key,16));
+ return 0;
+ }
+ }
+ }
+ else if ((tagtype & (UL_EV1_48 | UL_EV1_128))) {
+ //********** TODO ********************************
+ //PrintAndLog("Trying some known EV1 passwords.");
+ }
return 0;
}
blockNo = param_get8(Cmd, 0);
- if (blockNo > MAX_ULTRA_BLOCKS){
+ if (blockNo > MAX_UL_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
return 1;
}
// Mifare Ultralight Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd){
-
- uint8_t blockNo = -1;
+ UsbCommand resp;
+ uint8_t blockNo = -1;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu rdbl <block number>");
PrintAndLog(" sample: hfu mfu rdbl 0");
return 0;
- }
-
+ }
+
blockNo = param_get8(Cmd, 0);
- if (blockNo > MAX_ULTRA_BLOCKS){
- PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
- return 1;
+ if (blockNo > MAX_UL_BLOCKS){
+ PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight");
+ return 1;
}
-
- PrintAndLog("--block no:0x%02X (%d)", (int)blockNo, blockNo);
+
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
SendCommand(&c);
- UsbCommand resp;
+
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- uint8_t * data = resp.d.asBytes;
-
- PrintAndLog("isOk: %02x", isOK);
-
- if (isOK)
- PrintAndLog("Data: %s", sprint_hex(data, 4));
+ uint8_t isOK = resp.arg[0] & 0xff;
+ if (isOK) {
+ uint8_t *data = resp.d.asBytes;
+ PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
+ }
+ else {
+ PrintAndLog("Failed reading block: (%02x)", isOK);
+ }
} else {
- PrintAndLog("Command execute timeout");
+ PrintAndLog("Command execute time-out");
}
+
return 0;
}
PrintAndLog("Reads all pages from Mifare Ultralight or Ultralight-C tag.");
PrintAndLog("It saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLog("Usage: hf mfu dump <c> <filename w/o .bin>");
- PrintAndLog(" <c> optional cardtype c == Ultralight-C, if not defaults to Ultralight");
+ PrintAndLog(" <c> optional cardtype c == Ultralight-C, Defaults to Ultralight");
PrintAndLog(" sample: hf mfu dump");
PrintAndLog(" : hf mfu dump myfile");
PrintAndLog(" : hf mfu dump c myfile");
// UL or UL-C?
Pages = (cmdp == 'c' || cmdp == 'C') ? 44 : 16;
- PrintAndLog("Dumping Ultralight%s Card Data...", (Pages ==16)?"":"-C");
+ uint8_t data2[16] = {0x00};
+ TagTypeUL_t tagtype = GetHF14AMfU_Type(data2, sizeof(data2));
+ switch(tagtype){
+ case UL_C:
+ Pages = 44;
+ PrintAndLog("Dumping Ultralight_C Card Data...");
+ break;
+ case UL_EV1_48:
+ Pages = 18;
+ PrintAndLog("Dumping Ultralight EV1_48 Card Data...");
+ break;
+ case UL_EV1_128:
+ Pages = 32;
+ PrintAndLog("Dumping Ultralight EV1_128 Card Data...");
+ break;
+ case UL_MAGIC:
+ Pages = 16;
+ PrintAndLog("Dumping Ultralight (Magic) Card Data...");
+ break;
+ case UL_C_MAGIC:
+ Pages = 44;
+ PrintAndLog("Dumping Ultralight_C (Magic) Card Data...");
+ break;
+ case UL:
+ default:
+ Pages = 16;
+ PrintAndLog("Dumping Ultralight Card Data...");
+ break;
+ }
+ //PrintAndLog("Dumping Ultralight%s Card Data...", (Pages ==16)?"":"-C");
UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
SendCommand(&c);
}
data = resp.d.asBytes;
} else {
- PrintAndLog("Command execute timeout");
+ PrintAndLog("Command execute time-out");
return 0;
}
//
int CmdHF14AMfucAuth(const char *Cmd){
- uint8_t default_keys[5][16] = {
- { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
- { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
- { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
- { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
- { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } // all ones
- };
-
- char cmdp = param_getchar(Cmd, 0);
-
uint8_t keyNo = 0;
bool errors = false;
+
+ char cmdp = param_getchar(Cmd, 0);
+
//Change key to user defined one
if (cmdp == 'k' || cmdp == 'K'){
keyNo = param_get8(Cmd, 1);
- if(keyNo >= 4) errors = true;
+ if(keyNo > 6)
+ errors = true;
}
- if (cmdp == 'h' || cmdp == 'H') {
+ if (cmdp == 'h' || cmdp == 'H')
errors = true;
- }
-
+
if (errors) {
PrintAndLog("Usage: hf mfu cauth k <key number>");
PrintAndLog(" 0 (default): 3DES standard key");
- PrintAndLog(" 1 : all zeros key");
+ PrintAndLog(" 1 : all 0x00 key");
PrintAndLog(" 2 : 0x00-0x0F key");
PrintAndLog(" 3 : nfc key");
- PrintAndLog(" 4 : all ones key");
- PrintAndLog(" sample : hf mfu cauth k");
+ PrintAndLog(" 4 : all 0x01 key");
+ PrintAndLog(" 5 : all 0xff key");
+ PrintAndLog(" 6 : 0x00-0xFF key");
+ PrintAndLog("\n sample : hf mfu cauth k");
PrintAndLog(" : hf mfu cauth k 3");
return 0;
}
- uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
- //uint8_t enc_random_a[8] = { 0 };
- uint8_t random_b[8] = { 0 };
- uint8_t enc_random_b[8] = { 0 };
- uint8_t random_a_and_b[16] = { 0 };
- des3_context ctx = { 0 };
- uint8_t *key = default_keys[keyNo];
+ uint8_t *key = default_3des_keys[keyNo];
+ if (try3DesAuthentication(key))
+ PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 8));
+ else
+ PrintAndLog("Authentication failed");
+
+ return 0;
+}
+
+int try3DesAuthentication( uint8_t *key){
+
uint8_t blockNo = 0;
uint32_t cuid = 0;
- //Auth1
+ des3_context ctx = { 0 };
+
+ uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
+ uint8_t random_b[8] = { 0 };
+ uint8_t enc_random_b[8] = { 0 };
+ uint8_t rnd_ab[16] = { 0 };
+ uint8_t iv[8] = { 0 };
+
UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
SendCommand(&c);
UsbCommand resp;
- if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- cuid = resp.arg[1];
- uint8_t * data= resp.d.asBytes;
-
- if (isOK){
- PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
- memcpy(enc_random_b,data+1,8);
- } else {
- PrintAndLog("Auth failed");
- return 2; // auth failed.
- }
- } else {
- PrintAndLog("Command execute timeout");
- return 1;
- }
-
- uint8_t iv[8] = { 0 };
- // Do we need random ? Right now we use all ones, is that random enough ?
-// DES_random_key(&RndA);
-
- PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
- PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
+ if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return -1;
+ if ( !(resp.arg[0] & 0xff) ) return -2;
+
+ cuid = resp.arg[1];
+ memcpy(enc_random_b,resp.d.asBytes+1,8);
des3_set2key_dec(&ctx, key);
-
- des3_crypt_cbc(&ctx // des3_context *ctx
- , DES_DECRYPT // int mode
- , sizeof(random_b) // size_t length
- , iv // unsigned char iv[8]
- , enc_random_b // const unsigned char *input
- , random_b // unsigned char *output
- );
-
- PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc( &ctx, DES_DECRYPT, sizeof(random_b), iv , enc_random_b , random_b);
rol(random_b,8);
- memcpy(random_a_and_b ,random_a,8);
- memcpy(random_a_and_b+8,random_b,8);
-
- PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
+ memcpy(rnd_ab ,random_a,8);
+ memcpy(rnd_ab+8,random_b,8);
des3_set2key_enc(&ctx, key);
-
- des3_crypt_cbc(&ctx // des3_context *ctx
- , DES_ENCRYPT // int mode
- , sizeof(random_a_and_b) // size_t length
- , enc_random_b // unsigned char iv[8]
- , random_a_and_b // const unsigned char *input
- , random_a_and_b // unsigned char *output
- );
-
- PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc(&ctx, DES_ENCRYPT, sizeof(rnd_ab), enc_random_b, rnd_ab, rnd_ab);
//Auth2
- UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
- memcpy(d.d.asBytes,random_a_and_b, 16);
- SendCommand(&d);
+ c.cmd = CMD_MIFAREUC_AUTH2;
+ c.arg[0] = cuid;
+ memcpy(c.d.asBytes, rnd_ab, 16);
+ SendCommand(&c);
- UsbCommand respb;
- if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
- uint8_t isOK = respb.arg[0] & 0xff;
- uint8_t * data2= respb.d.asBytes;
+ if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
+ if ( !(resp.arg[0] & 0xff)) return -2;
+
+ uint8_t enc_resp[8] = { 0 };
+ uint8_t resp_random_a[8] = { 0 };
+ memcpy(enc_resp, resp.d.asBytes+1, 8);
- if (isOK){
- PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
- } else {
- return 2;
- }
-
- } else {
- PrintAndLog("Command execute timeout");
- return 1;
- }
+ des3_set2key_dec(&ctx, key);
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc( &ctx, DES_DECRYPT, 8, enc_random_b, enc_resp, resp_random_a);
+
+ if ( !memcmp(resp_random_a, random_a, 8))
+ return 1;
return 0;
+
+ //PrintAndLog(" RndA :%s", sprint_hex(random_a, 8));
+ //PrintAndLog(" enc(RndB) :%s", sprint_hex(enc_random_b, 8));
+ //PrintAndLog(" RndB :%s", sprint_hex(random_b, 8));
+ //PrintAndLog(" A+B :%s", sprint_hex(random_a_and_b, 16));
+ //PrintAndLog(" enc(A+B) :%s", sprint_hex(random_a_and_b, 16));
+ //PrintAndLog(" enc(RndA') :%s", sprint_hex(data2+1, 8));
}
+
/**
A test function to validate that the polarssl-function works the same
was as the openssl-implementation.
//
int CmdHF14AMfUCRdBl(const char *Cmd)
{
+ UsbCommand resp;
+ bool hasPwd = FALSE;
uint8_t blockNo = -1;
+ unsigned char key[16];
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
- PrintAndLog("Usage: hf mfu crdbl <block number>");
- PrintAndLog(" sample: hf mfu crdbl 0");
+ PrintAndLog("Usage: hf mfu crdbl <block number> <password>");
+ PrintAndLog("");
+ PrintAndLog("sample: hf mfu crdbl 0");
+ PrintAndLog(" hf mfu crdbl 0 112233445566778899AABBCCDDEEFF");
return 0;
}
return 1;
}
- if (blockNo > MAX_ULTRAC_BLOCKS ){
- PrintAndLog("Error: Maximum number of readable blocks is 47 for Ultralight-C Cards!");
+ if (blockNo > MAX_ULC_BLOCKS ){
+ PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C");
return 1;
}
- PrintAndLog("--block no: 0x%02X (%d)", (int)blockNo, blockNo);
+ // key
+ if ( strlen(Cmd) > 3){
+ if (param_gethex(Cmd, 1, key, 32)) {
+ PrintAndLog("Key must include %d HEX symbols", 32);
+ return 1;
+ } else {
+ hasPwd = TRUE;
+ }
+ }
//Read Block
- UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
- SendCommand(&e);
- UsbCommand resp_c;
- if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
- uint8_t isOK = resp_c.arg[0] & 0xff;
- uint8_t *data = resp_c.d.asBytes;
-
- PrintAndLog("isOk: %02x", isOK);
- if (isOK)
- PrintAndLog("Data: %s", sprint_hex(data, 4));
-
+ UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
+ if ( hasPwd ) {
+ c.arg[1] = 1;
+ memcpy(c.d.asBytes,key,16);
+ }
+ SendCommand(&c);
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ if (isOK) {
+ uint8_t *data = resp.d.asBytes;
+ PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
+ }
+ else {
+ PrintAndLog("Failed reading block: (%02x)", isOK);
+ }
} else {
- PrintAndLog("Command execute timeout");
+ PrintAndLog("Command execute time-out");
}
return 0;
}
}
blockNo = param_get8(Cmd, 0);
- if (blockNo > MAX_ULTRAC_BLOCKS ){
+ if (blockNo > MAX_ULC_BLOCKS ){
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!");
return 1;
}
return 0;
}
+//
+// Mifare Ultralight C - Set password
+//
+int CmdHF14AMfucSetPwd(const char *Cmd){
+
+ uint8_t pwd[16] = {0x00};
+
+ char cmdp = param_getchar(Cmd, 0);
+
+ if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
+ PrintAndLog(" [password] - (32 hex symbols)");
+ PrintAndLog("");
+ PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
+ PrintAndLog("");
+ return 0;
+ }
+
+ if (param_gethex(Cmd, 0, pwd, 32)) {
+ PrintAndLog("Password must include 32 HEX symbols");
+ return 1;
+ }
+
+ UsbCommand c = {CMD_MIFAREUC_SETPWD};
+ memcpy( c.d.asBytes, pwd, 16);
+ SendCommand(&c);
+
+ UsbCommand resp;
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+ if ( (resp.arg[0] & 0xff) == 1)
+ PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
+ else{
+ PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
+ return 1;
+ }
+ }
+ else {
+ PrintAndLog("command execution time out");
+ return 1;
+ }
+
+ return 0;
+}
+
+//
+// Mifare Ultraligh - Set UID
+//
+int CmdHF14AMfucSetUid(const char *Cmd){
+
+ UsbCommand c;
+ UsbCommand resp;
+ uint8_t uid[7] = {0x00};
+ char cmdp = param_getchar(Cmd, 0);
+
+ if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: hf mfu setuid <uid (14 hex symbols)>");
+ PrintAndLog(" [uid] - (14 hex symbols)");
+ PrintAndLog("\nThis only works for Magic Ultralight tags.");
+ PrintAndLog("");
+ PrintAndLog("sample: hf mfu setuid 11223344556677");
+ PrintAndLog("");
+ return 0;
+ }
+
+ if (param_gethex(Cmd, 0, uid, 14)) {
+ PrintAndLog("UID must include 14 HEX symbols");
+ return 1;
+ }
+
+ // read block2.
+ c.cmd = CMD_MIFAREU_READBL;
+ c.arg[0] = 2;
+ SendCommand(&c);
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ PrintAndLog("Command execute timeout");
+ return 2;
+ }
+
+ // save old block2.
+ uint8_t oldblock2[4] = {0x00};
+ memcpy(resp.d.asBytes, oldblock2, 4);
+
+ // block 0.
+ c.cmd = CMD_MIFAREU_WRITEBL;
+ c.arg[0] = 0;
+ c.d.asBytes[0] = uid[0];
+ c.d.asBytes[1] = uid[1];
+ c.d.asBytes[2] = uid[2];
+ c.d.asBytes[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
+ SendCommand(&c);
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ PrintAndLog("Command execute timeout");
+ return 3;
+ }
+
+ // block 1.
+ c.arg[0] = 1;
+ c.d.asBytes[0] = uid[3];
+ c.d.asBytes[1] = uid[4];
+ c.d.asBytes[2] = uid[5];
+ c.d.asBytes[3] = uid[6];
+ SendCommand(&c);
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+ PrintAndLog("Command execute timeout");
+ return 4;
+ }
+
+ // block 2.
+ c.arg[0] = 2;
+ c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
+ c.d.asBytes[1] = oldblock2[1];
+ c.d.asBytes[2] = oldblock2[2];
+ c.d.asBytes[3] = oldblock2[3];
+ SendCommand(&c);
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+ PrintAndLog("Command execute timeout");
+ return 5;
+ }
+
+ return 0;
+}
+
+int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
+
+ uint8_t iv[8] = { 0x00 };
+ uint8_t block = 0x07;
+
+ // UL-EV1
+ //04 57 b6 e2 05 3f 80 UID
+ //4a f8 4b 19 PWD
+ uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E };
+ uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
+ uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
+ uint8_t dkeyA[8] = { 0x00 };
+ uint8_t dkeyB[8] = { 0x00 };
+
+ uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
+
+ uint8_t mix[8] = { 0x00 };
+ uint8_t divkey[8] = { 0x00 };
+
+ memcpy(mix, mifarekeyA, 4);
+
+ mix[4] = mifarekeyA[4] ^ uid[0];
+ mix[5] = mifarekeyA[5] ^ uid[1];
+ mix[6] = block ^ uid[2];
+ mix[7] = uid[3];
+
+ des3_context ctx = { 0x00 };
+ des3_set2key_enc(&ctx, masterkey);
+
+ des3_crypt_cbc(&ctx // des3_context
+ , DES_ENCRYPT // int mode
+ , sizeof(mix) // length
+ , iv // iv[8]
+ , mix // input
+ , divkey // output
+ );
+
+ PrintAndLog("3DES version");
+ PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
+ PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
+ PrintAndLog("Sector :\t %0d", block);
+ PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
+ PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
+ PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
+
+ PrintAndLog("\n DES version");
+
+ for (int i=0; i < sizeof(mifarekeyA); ++i){
+ dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
+ dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1);
+ }
+
+ for (int i=0; i < sizeof(mifarekeyB); ++i){
+ dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1);
+ dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
+ }
+
+ uint8_t zeros[8] = {0x00};
+ uint8_t newpwd[8] = {0x00};
+ uint8_t dmkey[24] = {0x00};
+ memcpy(dmkey, dkeyA, 8);
+ memcpy(dmkey+8, dkeyB, 8);
+ memcpy(dmkey+16, dkeyA, 8);
+ memset(iv, 0x00, 8);
+
+ des3_set3key_enc(&ctx, dmkey);
+
+ des3_crypt_cbc(&ctx // des3_context
+ , DES_ENCRYPT // int mode
+ , sizeof(newpwd) // length
+ , iv // iv[8]
+ , zeros // input
+ , newpwd // output
+ );
+
+ PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
+ PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
+ PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
+ PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
+
+ return 0;
+}
+
+// static uint8_t * diversify_key(uint8_t * key){
+
+ // for(int i=0; i<16; i++){
+ // if(i<=6) key[i]^=cuid[i];
+ // if(i>6) key[i]^=cuid[i%7];
+ // }
+ // return key;
+// }
+
+// static void GenerateUIDe( uint8_t *uid, uint8_t len){
+ // for (int i=0; i<len; ++i){
+
+ // }
+ // return;
+// }
+
//------------------------------------
// Menu Stuff
//------------------------------------
{"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
{"info", CmdHF14AMfUInfo, 0,"Taginfo"},
{"dump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight / Ultralight-C tag to binary file"},
- {"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
+ {"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
{"wrbl", CmdHF14AMfUWrBl, 0,"Write block - MIFARE Ultralight"},
- {"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
- {"cwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
- {"cauth", CmdHF14AMfucAuth, 0,"try a Ultralight C Authentication"},
- //{"testdes", CmdTestDES , 1, "Test DES"},
+ {"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
+ {"cwrbl", CmdHF14AMfUCWrBl, 0,"Write block - MIFARE Ultralight C"},
+ {"cauth", CmdHF14AMfucAuth, 0,"Ultralight C Authentication"},
+ {"setpwd", CmdHF14AMfucSetPwd , 1, "Set 3des password [Ultralight-C only]"},
+ {"setuid", CmdHF14AMfucSetUid , 1, "Set UID"},
+ {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
{NULL, NULL, 0, NULL}
};
int CmdHelp(const char *Cmd){
CmdsHelp(CommandTable);
return 0;
-}
\ No newline at end of file
+}
#include "cmdhfmf.h"
#include "cmdhf14a.h"
+#ifndef CMDHFMFU_H__
+#define CMDHFMFU_H__
+
//standard ultralight
int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd);
int CmdHF14AMfUDump(const char *Cmd);
void rol (uint8_t *data, const size_t len);
+uint8_t requestAuthentication( uint8_t *nonce);
+int try3DesAuthentication( uint8_t *key);
int CmdHFMFUltra(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);
+#endif
CMD_MIFARE_SNIFFER = 0x0630,
--//ultralightC
- CMD_MIFAREUC_AUTH1 = 0x0724,
- CMD_MIFAREUC_AUTH2 = 0x0725,
- CMD_MIFAREUC_READCARD = 0x0726,
- CMD_MIFAREUC_SETPWD = 0x0727,
- CMD_MIFAREU_SETUID = 0x0728,
+ CMD_MIFAREUC_AUTH1 = 0x0724,
+ CMD_MIFAREUC_AUTH2 = 0x0725,
+ CMD_MIFAREUC_READCARD = 0x0726,
+ CMD_MIFAREUC_SETPWD = 0x0727,
--// mifare desfire
CMD_MIFARE_DESFIRE_READBL = 0x0728,
local _reverse_lookup,k,v = {}
- for k, v in pairs(_commands) do
- _reverse_lookup[v] = k
- end
- _commands.tostring = function(command)
+for k, v in pairs(_commands) do
+ _reverse_lookup[v] = k
+end
+_commands.tostring = function(command)
if(type(command) == 'number') then
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
end
local data = self.data
local cmd = self.cmd
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
- return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data);
+
+ return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
end
return _commands
#define CMD_SNOOP_ICLASS 0x0392
#define CMD_SIMULATE_TAG_ICLASS 0x0393
#define CMD_READER_ICLASS 0x0394
-#define CMD_READER_ICLASS_REPLAY 0x0395
-#define CMD_ICLASS_ISO14443A_WRITE 0x0397
+#define CMD_READER_ICLASS_REPLAY 0x0395
+#define CMD_ICLASS_ISO14443A_WRITE 0x0397
#define CMD_ICLASS_EML_MEMSET 0x0398
// For measurements of the antenna tuning
#define CMD_MIFARE_NESTED 0x0612
#define CMD_MIFARE_READBL 0x0620
-#define CMD_MIFAREU_READBL 0x0720
+#define CMD_MIFAREU_READBL 0x0720
#define CMD_MIFARE_READSC 0x0621
-#define CMD_MIFAREU_READCARD 0x0721
+#define CMD_MIFAREU_READCARD 0x0721
#define CMD_MIFARE_WRITEBL 0x0622
-#define CMD_MIFAREU_WRITEBL 0x0722
-#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
+#define CMD_MIFAREU_WRITEBL 0x0722
+#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
#define CMD_MIFARE_CHKKEYS 0x0623
#define CMD_MIFARE_SNIFFER 0x0630
//ultralightC
-#define CMD_MIFAREUC_AUTH1 0x0724
-#define CMD_MIFAREUC_AUTH2 0x0725
-#define CMD_MIFAREUC_READCARD 0x0726
+#define CMD_MIFAREUC_AUTH1 0x0724
+#define CMD_MIFAREUC_AUTH2 0x0725
+#define CMD_MIFAREUC_READCARD 0x0726
+#define CMD_MIFAREUC_SETPWD 0x0727
+
// mifare desfire
#define CMD_MIFARE_DESFIRE_READBL 0x0728