X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/b915fda392487a876ccc7b0c8b79a1b31ca5e398..abcb166ffe26cab359cd80e0109e6131e31bef49:/client/cmdhf14a.c?ds=inline diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 0298f509..1a31c71f 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -27,7 +27,6 @@ static int CmdHelp(const char *Cmd); static void waitCmd(uint8_t iLen); - // structure and database for uid -> tagtype lookups typedef struct { uint8_t uid; @@ -113,20 +112,15 @@ const manufactureName manufactureMapping[] = { // returns description of the best match char* getTagInfo(uint8_t uid) { - int i, best = -1; + int i; int len = sizeof(manufactureMapping) / sizeof(manufactureName); - for ( i = 0; i < len; ++i ) { - if ( uid == manufactureMapping[i].uid) { - if (best == -1) { - best = i; - } - } - } + for ( i = 0; i < len; ++i ) + if ( uid == manufactureMapping[i].uid) + return manufactureMapping[i].desc; - if (best>=0) return manufactureMapping[best].desc; - - return manufactureMapping[i].desc; + //No match, return default + return manufactureMapping[len-1].desc; } int CmdHF14AList(const char *Cmd) @@ -135,11 +129,6 @@ int CmdHF14AList(const char *Cmd) return 0; } -void iso14a_set_timeout(uint32_t timeout) { - UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}}; - SendCommand(&c); -} - int CmdHF14AReader(const char *Cmd) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; @@ -151,7 +140,7 @@ int CmdHF14AReader(const char *Cmd) iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); - 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, 3: proprietary Anticollision if(select_status == 0) { PrintAndLog("iso14443a card select failed"); @@ -163,6 +152,18 @@ int CmdHF14AReader(const char *Cmd) return 0; } + if(select_status == 3) { + PrintAndLog("Card doesn't support standard iso14443-3 anticollision"); + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + // disconnect + c.arg[0] = 0; + c.arg[1] = 0; + c.arg[2] = 0; + SendCommand(&c); + return 0; + } + + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen)); PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]); @@ -174,7 +175,27 @@ int CmdHF14AReader(const char *Cmd) } switch (card.sak) { - case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break; + case 0x00: + // check if the tag answers to GETVERSION (0x60) + c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT; + c.arg[1] = 1; + c.arg[2] = 0; + c.d.asBytes[0] = 0x60; + SendCommand(&c); + WaitForResponse(CMD_ACK,&resp); + + uint8_t version[8] = {0x00}; + memcpy(&version, resp.d.asBytes, resp.arg[0]); + uint8_t isOK = resp.arg[0] & 0xff; + if ( isOK ){ + // size of tag, check version[4] == 0x0b == smaller. + PrintAndLog("TYPE : NXP MIFARE Ultralight EV1 %d bytes", (version[6] == 0xB) ? 48 : 128); + } + else { + PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); + } + + break; case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break; case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1"); break; @@ -352,7 +373,7 @@ int CmdHF14AReader(const char *Cmd) SendCommand(&c); WaitForResponse(CMD_ACK,&resp); uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") ); + PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") ); // disconnect c.cmd = CMD_READER_ISO_14443a; @@ -418,9 +439,9 @@ int CmdHF14ASim(const char *Cmd) PrintAndLog(" syntax: hf 14a sim "); PrintAndLog(" types: 1 = MIFARE Classic"); PrintAndLog(" 2 = MIFARE Ultralight"); - PrintAndLog(" 3 = MIFARE DESFIRE"); + PrintAndLog(" 3 = MIFARE Desfire"); PrintAndLog(" 4 = ISO/IEC 14443-4"); - PrintAndLog(" 5 = MIFARE TNP3XXX"); + PrintAndLog(" 5 = MIFARE Tnp3xxx"); PrintAndLog(""); return 1; } @@ -486,7 +507,8 @@ int CmdHF14ASim(const char *Cmd) int CmdHF14ASnoop(const char *Cmd) { int param = 0; - if (param_getchar(Cmd, 0) == 'h') { + uint8_t ctmp = param_getchar(Cmd, 0) ; + if (ctmp == 'h' || ctmp == 'H') { PrintAndLog("It get data from the field and saves it into command buffer."); PrintAndLog("Buffer accessible from command hf list 14a."); PrintAndLog("Usage: hf 14a snoop [c][r]"); @@ -497,7 +519,7 @@ int CmdHF14ASnoop(const char *Cmd) { } for (int i = 0; i < 2; i++) { - char ctmp = param_getchar(Cmd, i); + ctmp = param_getchar(Cmd, i); if (ctmp == 'c' || ctmp == 'C') param |= 0x01; if (ctmp == 'r' || ctmp == 'R') param |= 0x02; } @@ -507,30 +529,38 @@ int CmdHF14ASnoop(const char *Cmd) { return 0; } + int CmdHF14ACmdRaw(const char *cmd) { UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; - uint8_t reply=1; - uint8_t crc=0; - uint8_t power=0; - uint8_t active=0; - uint8_t active_select=0; + bool reply=1; + bool crc = FALSE; + bool power = FALSE; + bool active = FALSE; + bool active_select = FALSE; uint16_t numbits=0; + bool bTimeout = FALSE; + uint32_t timeout=0; + bool topazmode = FALSE; char buf[5]=""; int i=0; - uint8_t data[100]; - unsigned int datalen=0, temp; + uint8_t data[USB_CMD_DATA_SIZE]; + uint16_t datalen=0; + uint32_t temp; if (strlen(cmd)<2) { - PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] <0A 0B 0C ... hex>"); + PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-a] [-t] [-b] <0A 0B 0C ... hex>"); PrintAndLog(" -r do not read response"); PrintAndLog(" -c calculate and append CRC"); PrintAndLog(" -p leave the signal field ON after receive"); PrintAndLog(" -a active signal field ON without select"); PrintAndLog(" -s active signal field ON with select"); PrintAndLog(" -b number of bits to send. Useful for send partial byte"); + PrintAndLog(" -t timeout in ms"); + PrintAndLog(" -T use Topaz protocol to send command"); return 0; } + // strip while (*cmd==' ' || *cmd=='\t') cmd++; @@ -539,19 +569,19 @@ int CmdHF14ACmdRaw(const char *cmd) { if (cmd[i]=='-') { switch (cmd[i+1]) { case 'r': - reply=0; + reply = FALSE; break; case 'c': - crc=1; + crc = TRUE; break; case 'p': - power=1; + power = TRUE; break; case 'a': - active=1; + active = TRUE; break; case 's': - active_select=1; + active_select = TRUE; break; case 'b': sscanf(cmd+i+2,"%d",&temp); @@ -560,6 +590,17 @@ int CmdHF14ACmdRaw(const char *cmd) { while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } i-=2; break; + case 't': + bTimeout = TRUE; + sscanf(cmd+i+2,"%d",&temp); + timeout = temp; + i+=3; + while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } + i-=2; + break; + case 'T': + topazmode = TRUE; + break; default: PrintAndLog("Invalid option"); return 0; @@ -577,18 +618,27 @@ int CmdHF14ACmdRaw(const char *cmd) { if (strlen(buf)>=2) { sscanf(buf,"%x",&temp); data[datalen]=(uint8_t)(temp & 0xff); - datalen++; *buf=0; + if (++datalen>sizeof(data)){ + if (crc) + PrintAndLog("Buffer is full, we can't add CRC to your data"); + break; + } } continue; } PrintAndLog("Invalid char on input"); return 0; } - if(crc && datalen>0) + + if(crc && datalen>0 && datalen MAX_TIMEOUT) { + timeout = MAX_TIMEOUT; + PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); + } + c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) + } + if(power) c.arg[0] |= ISO14A_NO_DISCONNECT; + if(datalen>0) c.arg[0] |= ISO14A_RAW; - c.arg[1] = datalen; - c.arg[2] = numbits; + if(topazmode) + c.arg[0] |= ISO14A_TOPAZMODE; + + // Max buffer is USB_CMD_DATA_SIZE + c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); memcpy(c.d.asBytes,data,datalen); SendCommand(&c); @@ -619,6 +684,7 @@ int CmdHF14ACmdRaw(const char *cmd) { return 0; } + static void waitCmd(uint8_t iSelect) { uint8_t *recv; @@ -652,7 +718,7 @@ static command_t CommandTable[] = {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"}, {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"}, {"cuids", CmdHF14ACUIDs, 0, " Collect n>0 ISO14443 Type A UIDs in one go"}, - {"sim", CmdHF14ASim, 0, " -- Fake ISO 14443a tag"}, + {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443a tag"}, {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"}, {"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"}, {NULL, NULL, 0, NULL}