user jwesthues, at host cq.cx
May 2007, Cambridge MA
-
void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
void IClass_iso14443A_GetPublic(uint8_t arg0);
-
+
// hitag2.h
void SnoopHitag(uint32_t type);
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
// different initial value (CRC_ICLASS)
#include "../common/iso14443crc.h"
#include "../common/iso15693tools.h"
+#include "iso15693tools.h"
static int timeout = 4096;
{
WDT_HIT();
- // Send act_all
- ReaderTransmitIClass(act_all, 1);
- // Card present?
- if(ReaderReceiveIClass(resp)) {
+ // Send act_all
+ ReaderTransmitIClass(act_all, 1);
+ // Card present?
+ if(ReaderReceiveIClass(resp)) {
- ReaderTransmitIClass(identify, 1);
+ ReaderTransmitIClass(identify, 1);
- if(ReaderReceiveIClass(resp) == 10) {
+ if(ReaderReceiveIClass(resp) == 10) {
//Copy the Anti-collision CSN to our select-packet
- memcpy(&select[1],resp,8);
+ memcpy(&select[1],resp,8);
//Dbprintf("Anti-collision CSN: %02x %02x %02x %02x %02x %02x %02x %02x",resp[0], resp[1], resp[2],
// resp[3], resp[4], resp[5],
// resp[6], resp[7]);
//Select the card
- ReaderTransmitIClass(select, sizeof(select));
+ ReaderTransmitIClass(select, sizeof(select));
- if(ReaderReceiveIClass(resp) == 10) {
+ if(ReaderReceiveIClass(resp) == 10) {
//Save CSN in response data
memcpy(card_data,resp,8);
datasize += 8;
break;
}
}
- LED_A_OFF();
+ LED_A_OFF();
}
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
- uint16_t crc = 0;
+ uint16_t crc = 0;
uint8_t cardsize=0;
bool read_success=false;
uint8_t mem=0;
memcpy(write+10,mac,4);
while(!send_success){
ReaderTransmitIClass(write, sizeof(write));
- if(ReaderReceiveIClass(resp) == 10) {
+ if(ReaderReceiveIClass(resp) == 10) {
write_success=true;
}
}//
return true;
}
+// ARG0 flag enums
+enum {
+ NONE = 0x00,
+ INIT = 0x01,
+ DISCONNECT = 0x02,
+ FOO = 0x04,
+ BAR = 0x08,
+} CmdOptions ;
+
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
/* ARG0 contains flags.
0x01 = init card.
- 0x02 =
+ 0x02 = No Disconnect
0x03
*/
uint8_t flags = arg0;
memset(resp,0,sizeof(resp));
if (MF_DBGLEVEL >= 4) {
- Dbprintf(" flags: %02X", flags);
- Dbprintf(" len : %02X", datalen);
- print_result("to send: ", datain, datalen);
+ Dbprintf(" flags : %02X", flags);
+ Dbprintf(" len : %02X", datalen);
+ print_result(" RX : ", datain, datalen);
}
- if ( flags & 0x01 ){
+ if ( flags & INIT ){
if ( !InitDesfireCard() )
return;
}
int len = DesfireAPDU(datain, datalen, resp);
+ print_result(" <--: ", resp, len);
if ( !len ) {
if (MF_DBGLEVEL >= 4) {
print_result("ERR <--: ", resp, len);
OnError();
return;
}
- cmd_send(CMD_ACK,1,len,0,resp,len);
-
- OnSuccess();
+ // reset the pcb_blocknum,
+ pcb_blocknum = 0;
+
+ if ( flags & DISCONNECT )
+ OnSuccess();
+
+ cmd_send(CMD_ACK,1,len,0,resp,len);
}
void MifareDesfireGetInformation(){
}
void OnSuccess(){
- // transmit a DESELECT COMMAND for Desfire.
- ReaderTransmit(deselect_cmd, 3 , NULL);
- // reset the pcb_blocknum,
pcb_blocknum = 0;
+ ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void OnError(){
- cmd_send(CMD_ACK,0,0,0,0,0);
- ReaderTransmit(deselect_cmd, 3 , NULL);
- // reset the pcb_blocknum,
pcb_blocknum = 0;
+ ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ cmd_send(CMD_ACK,0,0,0,0,0);
LEDsoff();
}
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
MOC = $(QTDIR)/bin/moc
LUAPLATFORM = mingw
+else ifeq ($(platform),Darwin)
+CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
+QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
+MOC = $(shell pkg-config --variable=moc_location QtCore)
+LUAPLATFORM = macosx
else
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
cmdhfdes.c \
cmdhw.c \
cmdlf.c \
- cmdlfhid.c \
cmdlfio.c \
+ cmdlfhid.c \
cmdlfem4x.c \
cmdlfhitag.c \
cmdlfti.c \
first_timestamp = timestamp;
}
- // Break and stick with current result if buffer was not completely full
+ // Break and stick with current result idf buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
char line[1000] = "";
PrintAndLog("Usage: hf iclass replay <MAC>");
PrintAndLog(" sample: hf iclass replay 00112233");
return 0;
- }
+ }
if (param_gethex(Cmd, 0, MAC, 8)) {
PrintAndLog("MAC must include 8 HEX symbols");
return 0;
}
- if (param_gethex(Cmd, 0, KEY, 16)) {
+ if (param_gethex(Cmd, 0, KEY, 16))
+ {
PrintAndLog("KEY must include 16 HEX symbols");
return 1;
}
-
+
if (param_getchar(Cmd, 1) == 'e')
{
PrintAndLog("Elite switch on");
if (blockNo>32)
{
PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
- return 1;
+ return 1;
}
if (param_gethex(Cmd, 2, bldata, 8))
{
{"list", CmdHFiClassList, 0, "List iClass history"},
{"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
{"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
- {"reader", CmdHFiClassReader, 0, "Read an iClass tag"},
+ {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
+ {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
+ {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
+ {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
{"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
{"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
{"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
PrintAndLog("-------------------------------------------------------------");
- UsbCommand c1 = {CMD_MIFARE_DESFIRE, { 0x01, 0x01 }};
+ UsbCommand c1 = {CMD_MIFARE_DESFIRE, { 0x03, 0x01 }};
c1.d.asBytes[0] = GET_KEY_SETTINGS;
SendCommand(&c1);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
PrintAndLog(" Master Key settings");
if ( resp.d.asBytes[3] & (1 << 3 ) )
- PrintAndLog(" 0x08 Configuration changeable;");
+ PrintAndLog(" 0x08 Configuration changeable");
else
- PrintAndLog(" 0x08 Configuration NOT changeable;");
+ PrintAndLog(" 0x08 Configuration NOT changeable");
if ( resp.d.asBytes[3] & (1 << 2 ) )
- PrintAndLog(" 0x04 PICC Master Key not required for create / delete;");
+ PrintAndLog(" 0x04 PICC Master Key not required for create / delete");
else
- PrintAndLog(" 0x04 PICC Master Key required for create / delete;");
+ PrintAndLog(" 0x04 PICC Master Key required for create / delete");
if ( resp.d.asBytes[3] & (1 << 1 ) )
- PrintAndLog(" 0x02 Free directory list access without PICC Master Key;");
+ PrintAndLog(" 0x02 Free directory list access without PICC Master Key");
else
- PrintAndLog(" 0x02 Directory list access with PICC Master Key;");
+ PrintAndLog(" 0x02 Directory list access with PICC Master Key");
if ( resp.d.asBytes[3] & (1 << 0 ) )
- PrintAndLog(" 0x01 Allow changing the Master Key;");
+ PrintAndLog(" 0x01 Allow changing the Master Key");
else
- PrintAndLog(" 0x01 Master Key is not changeable anymore;");
+ PrintAndLog(" 0x01 Master Key is not changeable anymore");
// init len
- UsbCommand c2 = {CMD_MIFARE_DESFIRE, { 0x01, 0x02 }};
+ UsbCommand c2 = {CMD_MIFARE_DESFIRE, { 0x03, 0x02 }};
c2.d.asBytes[0] = GET_KEY_VERSION;
c2.d.asBytes[1] = 0x00;
SendCommand(&c2);
}
PrintAndLog("");
- PrintAndLog(" Max number of keys : %d", resp.d.asBytes[2]);
+ PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
PrintAndLog("-------------------------------------------------------------");
- UsbCommand c3 = {CMD_MIFARE_DESFIRE, { 0x01, 0x01 }};
+ UsbCommand c3 = {CMD_MIFARE_DESFIRE, { 0x03, 0x01 }};
c3.d.asBytes[0] = GET_FREE_MEMORY;
SendCommand(&c3);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
PrintAndLog("-------------------------------------------------------------");
/*
- Card Master key (CMK) 0x00 on AID = 00 00 00 (card level) 0x1
- Application Master Key (AMK) 0x00 on AID != 00 00 00
- Application keys (APK) = 0x01-0x0D
- Application free = 0x0E
- Application never = 0x0F
+ Card Master key (CMK) 0x00 AID = 00 00 00 (card level)
+ Application Master Key (AMK) 0x00 AID != 00 00 00
+ Application keys (APK) 0x01-0x0D
+ Application free 0x0E
+ Application never 0x0F
ACCESS RIGHTS:
keys 0,1,2,3 C
int CmdHF14ADesEnumApplications(const char *Cmd){
- UsbCommand c = {CMD_MIFARE_DESFIRE, { 0x01, 0x01 }};
- c.d.asBytes[0] = GET_APPLICATION_IDS;
+ uint32_t options = 0x00;
+
+ options |= INIT;
+ options |= DISCONNECT;
+
+ UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
+ c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
SendCommand(&c);
UsbCommand resp;
PrintAndLog("---Desfire Enum Applications --------------------------------");
PrintAndLog("-------------------------------------------------------------");
- //UsbCommand respFiles;
+ UsbCommand respAid;
+ UsbCommand respFiles;
uint8_t num = 0;
int max = resp.arg[1] -3 -2;
for(int i=3; i<=max; i+=3){
- PrintAndLog(" Aid %d : %s ",num ,sprint_hex(resp.d.asBytes+i,3));
+ PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
num++;
- // UsbCommand cFiles = {CMD_MIFARE_DESFIRE, { 0x01, 0x04 }};
- // cFiles.d.asBytes[0] = GET_FILE_IDS;
- // cFiles.d.asBytes[1] = resp.d.asBytes+i;
- // cFiles.d.asBytes[2] = resp.d.asBytes+i+1;
- // cFiles.d.asBytes[3] = resp.d.asBytes+i+2;
- // SendCommand(&cFiles);
+ options = INIT;
+
+ UsbCommand cAid = {CMD_MIFARE_DESFIRE, { options, 0x04 }};
+ cAid.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
+ cAid.d.asBytes[1] = resp.d.asBytes[i];
+ cAid.d.asBytes[2] = resp.d.asBytes[i+1];
+ cAid.d.asBytes[3] = resp.d.asBytes[i+2];
+ SendCommand(&cAid);
+
+ if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
+ PrintAndLog(" Timed-out");
+ continue;
+ }
+ uint8_t isOK = respAid.arg[0] & 0xff;
+ if ( !isOK ){
+ PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
+ continue;
+ }
+
+ options = DISCONNECT;
+ UsbCommand cFiles = {CMD_MIFARE_DESFIRE, { options, 0x01 }};
+ cFiles.d.asBytes[0] = GET_FILE_IDS; // 0x6f
+ SendCommand(&cFiles);
+
+ if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
+ PrintAndLog(" Timed-out");
+ continue;
+ } else {
- // if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
- // PrintAndLog(" No files found");
- // break;
- // }
+ uint8_t isOK = respFiles.arg[0] & 0xff;
+ if ( !isOK ){
+ PrintAndLog(" No files found");
+ continue;
+ }
+
+ int respfileLen = resp.arg[1]-3-2;
+ for (int j=0; j< respfileLen; ++j){
+ PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
+ }
+ }
}
PrintAndLog("-------------------------------------------------------------");
char * GetVendorStr( uint8_t id);
char * GetProtocolStr(uint8_t id);
+// Command options for Desfire behavior.
+enum {
+ NONE = 0x00,
+ INIT = 0x01,
+ DISCONNECT = 0x02,
+ FOO = 0x04,
+ BAR = 0x08,
+} CmdOptions ;
#define CREATE_APPLICATION 0xca
/**
* @brief
- *Definition 11. Let the function hash0 : F 82 × F 82 × (F 62 ) 8 ? (F 82 ) 8 be defined as
+ *Definition 11. Let the function hash0 : F 82 × F 82 × (F 62 ) 8 → (F 82 ) 8 be defined as
* hash0(x, y, z [0] . . . z [7] ) = k [0] . . . k [7] where
* z'[i] = (z[i] mod (63-i)) + i i = 0...3
* z'[i+4] = (z[i+4] mod (64-i)) + i i = 0...3
- * ? = check(z');
+ * ẑ = check(z');
* @param c
* @param k this is where the diversified key is put (should be 8 bytes)
* @return