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 : snprintf(exp,size,"PWD-AUTH"); 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] < 0x21)
+ if ( cmdsize >=3 && cmd[2] <= 0xE6)
snprintf(exp,size,"READ RANGE (%d-%d)",cmd[1],cmd[2]);
else
snprintf(exp,size,"?");
}
}
-
void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
{
switch(cmd[0]) {
case TOPAZ_READ8 :snprintf(exp, size, "READ8");break;
case TOPAZ_WRITE_E8 :snprintf(exp, size, "WRITE-E8");break;
case TOPAZ_WRITE_NE8 :snprintf(exp, size, "WRITE-NE8");break;
- default: snprintf(exp,size,"?"); break;
+ default :snprintf(exp,size,"?"); break;
}
}
+// iso 7816-3
+void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
+ // S-block
+ if ( (cmd[0] & 0xC0) && (cmdsize == 3) ) {
+ switch ( (cmd[0] & 0x3f) ) {
+ case 0x00 : snprintf(exp, size, "S-block RESYNCH req"); break;
+ case 0x20 : snprintf(exp, size, "S-block RESYNCH resp"); break;
+ case 0x01 : snprintf(exp, size, "S-block IFS req"); break;
+ case 0x21 : snprintf(exp, size, "S-block IFS resp"); break;
+ case 0x02 : snprintf(exp, size, "S-block ABORT req"); break;
+ case 0x22 : snprintf(exp, size, "S-block ABORT resp"); break;
+ case 0x03 : snprintf(exp, size, "S-block WTX reqt"); break;
+ case 0x23 : snprintf(exp, size, "S-block WTX resp"); break;
+ default : snprintf(exp, size, "S-block"); break;
+ }
+ }
+ // R-block (ack)
+ else if ( ((cmd[0] & 0xD0) == 0x80) && ( cmdsize > 2) ) {
+ if ( (cmd[0] & 0x10) == 0 )
+ snprintf(exp, size, "R-block ACK");
+ else
+ snprintf(exp, size, "R-block NACK");
+ }
+ // I-block
+ else {
+
+ int pos = (cmd[0] == 2 || cmd[0] == 3) ? 2 : 3;
+ switch ( cmd[pos] ){
+ case ISO7816_READ_BINARY :snprintf(exp, size, "READ BIN");break;
+ case ISO7816_WRITE_BINARY :snprintf(exp, size, "WRITE BIN");break;
+ case ISO7816_UPDATE_BINARY :snprintf(exp, size, "UPDATE BIN");break;
+ case ISO7816_ERASE_BINARY :snprintf(exp, size, "ERASE BIN");break;
+ case ISO7816_READ_RECORDS :snprintf(exp, size, "READ RECORDS");break;
+ case ISO7816_WRITE_RECORDS :snprintf(exp, size, "WRITE RECORDS");break;
+ case ISO7816_APPEND_RECORD :snprintf(exp, size, "APPEND RECORD");break;
+ case ISO7816_UPDATE_RECORD :snprintf(exp, size, "UPDATE RECORD");break;
+ case ISO7816_GET_DATA :snprintf(exp, size, "GET DATA");break;
+ case ISO7816_PUT_DATA :snprintf(exp, size, "PUT DATA");break;
+ case ISO7816_SELECT_FILE :snprintf(exp, size, "SELECT FILE");break;
+ case ISO7816_VERIFY :snprintf(exp, size, "VERIFY");break;
+ case ISO7816_INTERNAL_AUTHENTICATION :snprintf(exp, size, "INTERNAL AUTH");break;
+ case ISO7816_EXTERNAL_AUTHENTICATION :snprintf(exp, size, "EXTERNAL AUTH");break;
+ case ISO7816_GET_CHALLENGE :snprintf(exp, size, "GET CHALLENGE");break;
+ case ISO7816_MANAGE_CHANNEL :snprintf(exp, size, "MANAGE CHANNEL");break;
+ default :snprintf(exp,size,"?"); break;
+ }
+ }
+}
/**
06 00 = INITIATE
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
{
switch(cmd[0]){
- case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
- case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
- case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
- case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break;
- case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break;
- case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break;
- case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break;
- case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break;
- case ISO14443B_RESET : snprintf(exp,size,"RESET");break;
- case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break;
- case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break;
- default : snprintf(exp,size ,"?");break;
+ case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
+ case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
+ case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
+ case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break;
+ case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break;
+ case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break;
+ case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break;
+ case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break;
+ case ISO14443B_RESET : snprintf(exp,size,"RESET");break;
+ case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break;
+ case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break;
+ case ISO14443B_PING : snprintf(exp,size,"PING");break;
+ case ISO14443B_PONG : snprintf(exp,size,"PONG");break;
+ default : snprintf(exp,size ,"?");break;
}
-
}
/**
if (data_len > 2) {
switch (protocol) {
case ICLASS:
- crcStatus = iclass_CRC_check(isResponse, frame, data_len);
+ crcStatus = iclass_CRC_check(isResponse, frame, data_len);
break;
case ISO_14443B:
case TOPAZ:
- crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
+ crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
break;
case ISO_14443A:
crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
- break;
+ break;
default:
break;
}
//2 Not crc-command
//--- Draw the data column
- //char line[16][110];
char line[16][110];
for (int j = 0; j < data_len && j/16 < 16; j++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
uint8_t parityBits = parityBytes[j>>3];
- if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+ if (protocol != ISO_14443B && isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
+
} else {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
}
}
if (markCRCBytes) {
- if(crcStatus == 0 || crcStatus == 1)
- {//CRC-command
+ //CRC-command
+ if(crcStatus == 0 || crcStatus == 1) {
char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
- (*pos1) = '[';
+ (*pos1) = '[';
char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
sprintf(pos2, "%c", ']');
}
}
- if(data_len == 0)
- {
- if(data_len == 0){
- sprintf(line[0],"<empty trace - possible error>");
- }
+ if(data_len == 0){
+ sprintf(line[0],"<empty trace - possible error>");
}
//--- Draw the CRC column
-
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
EndOfTransmissionTimestamp = timestamp + duration;
case ISO_14443A: annotateIso14443a(explanation,sizeof(explanation),frame,data_len); break;
case ISO_14443B: annotateIso14443b(explanation,sizeof(explanation),frame,data_len); break;
case TOPAZ: annotateTopaz(explanation,sizeof(explanation),frame,data_len); break;
+ case ISO_7816_4: annotateIso7816(explanation,sizeof(explanation),frame,data_len); break;
default: break;
}
}
(j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : "");
} else {
- PrintAndLog(" | | | %-64s| %s| %s",
+ PrintAndLog(" | | |%-64s | %s| %s",
line[j],
- (j == num_lines-1)?crc:" ",
+ (j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : "");
}
}
if (showWaitCycles && !isResponse && next_record_is_response(tracepos, trace)) {
uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
- PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
+ PrintAndLog(" %10d | %10d | %s |fdt (Frame Delay Time): %d",
(EndOfTransmissionTimestamp - first_timestamp),
(next_timestamp - first_timestamp),
" ",
protocol = ISO_14443B;
} else if(strcmp(type,"topaz")== 0) {
protocol = TOPAZ;
+ } else if(strcmp(type,"7816")== 0) {
+ protocol = ISO_7816_4;
} else if(strcmp(type,"raw")== 0) {
protocol = -1;//No crc, no annotations
}else{
PrintAndLog(" 14b - interpret data as iso14443b communications");
PrintAndLog(" iclass - interpret data as iclass communications");
PrintAndLog(" topaz - interpret data as topaz communications");
+ PrintAndLog(" 7816 - interpret data as iso7816-4 communications");
PrintAndLog("");
PrintAndLog("example: hf list 14a f");
PrintAndLog("example: hf list iclass");
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 = HF14BInfo(false);
+ if (ans) {
+ PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n");
+ return ans;
+ }
+ ans = HFiClassReader("", false, false);
+ if (ans) {
+ PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n");
+ return ans;
+ }
+ ans = HF15Reader("", false);
+ if (ans) {
+ PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n");
+ return ans;
+ }
+ PrintAndLog("\nno known/supported 13.56 MHz tags found\n");
+ return 0;
+}
static command_t CommandTable[] =
{
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
- {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
+ {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"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}
};