X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/05ddb52c43f932db852e18fe6836bee71e91f74e..ec0872181b882afe69213c2443f074426ccaa94f:/client/cmdhf.c?ds=sidebyside diff --git a/client/cmdhf.c b/client/cmdhf.c index 0d678ab6..7a2f3252 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -8,11 +8,16 @@ // High frequency commands //----------------------------------------------------------------------------- +#include #include #include #include "proxmark3.h" -#include "graph.h" +#include "util.h" +#include "data.h" #include "ui.h" +#include "iso14443crc.h" +#include "parity.h" +#include "cmdmain.h" #include "cmdparser.h" #include "cmdhf.h" #include "cmdhf14a.h" @@ -25,6 +30,7 @@ #include "cmdhfmfu.h" #include "cmdhftopaz.h" #include "protocols.h" +#include "emv/cmdemv.h" static int CmdHelp(const char *Cmd); @@ -72,11 +78,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_RESTORE: snprintf(exp,size,"RESTORE(%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_MAGICWUPC1: snprintf(exp,size,"MAGIC WUPC1"); break; case MIFARE_MAGICWUPC2: snprintf(exp,size,"MAGIC WUPC2"); 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; } return; @@ -145,7 +197,6 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) { - switch(cmd[0]) { case TOPAZ_REQA :snprintf(exp, size, "REQA");break; case TOPAZ_WUPA :snprintf(exp, size, "WUPA");break; @@ -154,6 +205,10 @@ void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) case TOPAZ_READ :snprintf(exp, size, "READ");break; case TOPAZ_WRITE_E :snprintf(exp, size, "WRITE-E");break; case TOPAZ_WRITE_NE :snprintf(exp, size, "WRITE-NE");break; + case TOPAZ_RSEG :snprintf(exp, size, "RSEG");break; + 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; } } @@ -319,7 +374,7 @@ bool next_record_is_response(uint16_t tracepos, uint8_t *trace) bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len) { -#define MAX_TOPAZ_READER_CMD_LEN 9 +#define MAX_TOPAZ_READER_CMD_LEN 16 uint32_t last_timestamp = timestamp + *duration; @@ -428,15 +483,9 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui for (int j = 0; j < data_len && j/16 < 16; j++) { - int oddparity = 0x01; - int k; - - for (k=0 ; k<8 ; k++) { - oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); - } uint8_t parityBits = parityBytes[j>>3]; - if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) { - snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x!", frame[j]); + if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((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]); } @@ -479,7 +528,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui int num_lines = MIN((data_len - 1)/16 + 1, 16); for (int j = 0; j < num_lines ; j++) { if (j == 0) { - PrintAndLog(" %9d | %9d | %s |%-64s | %s| %s", + PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s", (timestamp - first_timestamp), (EndOfTransmissionTimestamp - first_timestamp), (isResponse ? "Tag" : "Rdr"), @@ -487,7 +536,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui (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) ? explanation : ""); @@ -498,7 +547,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui 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), " ", @@ -514,7 +563,7 @@ int CmdHFList(const char *Cmd) bool showWaitCycles = false; bool markCRCBytes = false; char type[40] = {0}; - int tlen = param_getstr(Cmd,0,type); + int tlen = param_getstr(Cmd,0,type, sizeof(type)); char param1 = param_getchar(Cmd, 1); char param2 = param_getchar(Cmd, 2); bool errors = false; @@ -600,8 +649,8 @@ int CmdHFList(const char *Cmd) PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); PrintAndLog("iClass - Timings are not as accurate"); PrintAndLog(""); - PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |"); - PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|"); + PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |"); + PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|"); while(tracepos < traceLen) { @@ -612,6 +661,41 @@ int CmdHFList(const char *Cmd) return 0; } +int CmdHFSearch(const char *Cmd){ + int ans = 0; + PrintAndLog(""); + ans = CmdHF14AInfo("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 is longest test currently (and rarest chip type) ... put last + ans = HF14BInfo(false); + if (ans) { + PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n"); + return ans; + } + PrintAndLog("\nno known/supported 13.56 MHz tags found\n"); + return 0; +} + +int CmdHFSnoop(const char *Cmd) +{ + char * pEnd; + UsbCommand c = {CMD_HF_SNIFFER, {strtol(Cmd, &pEnd,0),strtol(pEnd, &pEnd,0),0}}; + SendCommand(&c); + return 0; +} static command_t CommandTable[] = { @@ -620,6 +704,7 @@ static command_t CommandTable[] = {"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"}, {"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"}, {"epa", CmdHFEPA, 1, "{ German Identification Card... }"}, + {"emv", CmdHFEMV, 1, "{ EMV cards... }"}, {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, @@ -627,6 +712,8 @@ static command_t CommandTable[] = {"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"}, + {"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"}, + {"snoop", CmdHFSnoop, 0, " Generic HF Snoop"}, {NULL, NULL, 0, NULL} };