X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/5de71ee6bf8abce63566637c4d50f0cd2e0335e9..ad5bc8cc8c0a6573d6b2c7bc58bf94f7ab66ad4c:/client/cmdhf14b.c diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 5666e605..471ac0f3 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -8,50 +8,61 @@ // High frequency ISO14443B commands //----------------------------------------------------------------------------- -#include -#include -#include -#include #include "cmdhf14b.h" #define TIMEOUT 2000 static int CmdHelp(const char *Cmd); int usage_hf_14b_info(void){ - PrintAndLog("Usage: hf 14b info [-h] [-s]"); - PrintAndLog(" -h this help"); - PrintAndLog(" -s silently"); + PrintAndLog("Usage: hf 14b info [h] [s]"); + PrintAndLog("Options:"); + PrintAndLog(" h this help"); + PrintAndLog(" s silently"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b info"); return 0; } int usage_hf_14b_reader(void){ - PrintAndLog("Usage: hf 14b reader [-h] [-s]"); - PrintAndLog(" -h this help"); - PrintAndLog(" -s silently"); + PrintAndLog("Usage: hf 14b reader [h] [s]"); + PrintAndLog("Options:"); + PrintAndLog(" h this help"); + PrintAndLog(" s silently"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b reader"); return 0; } int usage_hf_14b_raw(void){ PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>"); + PrintAndLog("Options:"); PrintAndLog(" -h this help"); PrintAndLog(" -r do not read response"); PrintAndLog(" -c calculate and append CRC"); PrintAndLog(" -p leave the field on after receive"); PrintAndLog(" -s active signal field ON with select"); PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b raw -s -c -p 0200a40400"); return 0; } int usage_hf_14b_snoop(void){ PrintAndLog("It get data from the field and saves it into command buffer."); PrintAndLog("Buffer accessible from command 'hf list 14b'"); - PrintAndLog("Usage: hf 14b snoop [-h]"); - PrintAndLog(" -h this help"); - PrintAndLog("sample: hf 14b snoop"); + PrintAndLog("Usage: hf 14b snoop [h]"); + PrintAndLog("Options:"); + PrintAndLog(" h this help"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b snoop"); return 0; } int usage_hf_14b_sim(void){ - PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID"); - PrintAndLog("Usage: hf 14b sim [-h]"); - PrintAndLog(" -h this help"); - PrintAndLog("sample: hf 14b sim"); + PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID / PUPI"); + PrintAndLog("Usage: hf 14b sim [h] u "); + PrintAndLog("Options:"); + PrintAndLog(" h this help"); + PrintAndLog(" u 4byte UID/PUPI"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b sim"); + PrintAndLog(" hf 14b sim u 11223344"); return 0; } int usage_hf_14b_read_srx(void){ @@ -59,29 +70,37 @@ int usage_hf_14b_read_srx(void){ PrintAndLog("Options:"); PrintAndLog(" h this help"); PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512"); - PrintAndLog("sample: hf 14b read 1"); - PrintAndLog(" : hf 14b read 2"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b read 1"); + PrintAndLog(" hf 14b read 2"); return 0; } int usage_hf_14b_write_srx(void){ - PrintAndLog("Usage: hf 14b write <1|2> "); + PrintAndLog("Usage: hf 14b [h] write <1|2> "); PrintAndLog("Options:"); PrintAndLog(" h this help"); PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512"); PrintAndLog(" BLOCK number depends on tag, special block == FF"); PrintAndLog(" hex bytes of data to be written"); - PrintAndLog("sample : hf 14b write 1 7F 11223344"); - PrintAndLog(" : hf 14b write 1 FF 11223344"); - PrintAndLog(" : hf 14b write 2 15 11223344"); - PrintAndLog(" : hf 14b write 2 FF 11223344"); + PrintAndLog("sample:"); + PrintAndLog(" hf 14b write 1 7F 11223344"); + PrintAndLog(" hf 14b write 1 FF 11223344"); + PrintAndLog(" hf 14b write 2 15 11223344"); + PrintAndLog(" hf 14b write 2 FF 11223344"); return 0; } -static int rawClose(){ +static void switch_on_field_14b(void) { + UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT, 0, 0}}; + clearCommandBuffer(); + SendCommand(&c); +} + +static int switch_off_field_14b(void) { UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}}; clearCommandBuffer(); SendCommand(&c); - return 1; + return 0; } int CmdHF14BList(const char *Cmd) { @@ -90,10 +109,15 @@ int CmdHF14BList(const char *Cmd) { } int CmdHF14BSim(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); + char cmdp = param_getchar(Cmd, 0); if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim(); - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {0, 0, 0}}; + uint32_t pupi = 0; + if (cmdp == 'u' || cmdp == 'U') { + pupi = param_get32ex(Cmd, 1, 0, 16); + } + + UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {pupi, 0, 0}}; clearCommandBuffer(); SendCommand(&c); return 0; @@ -111,18 +135,15 @@ int CmdHF14BSnoop(const char *Cmd) { } int CmdHF14BCmdRaw (const char *Cmd) { - bool reply = TRUE; - bool power = FALSE; - bool select = FALSE; - char buf[5]=""; - + bool reply = TRUE, power = FALSE, select = FALSE; + char buf[5] = ""; int i = 0; uint8_t data[USB_CMD_DATA_SIZE] = {0x00}; uint16_t datalen = 0; - uint32_t flags = 0; + uint32_t flags = ISO14B_CONNECT; uint32_t temp = 0; - if (strlen(Cmd)<3) return usage_hf_14b_raw(); + if ( strlen(Cmd) < 3 ) return usage_hf_14b_raw(); // strip while (*Cmd==' ' || *Cmd=='\t') ++Cmd; @@ -131,8 +152,8 @@ int CmdHF14BCmdRaw (const char *Cmd) { if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; } if (Cmd[i]=='-') { switch (Cmd[i+1]) { - case 'H': case 'h': + case 'H': return usage_hf_14b_raw(); case 'r': case 'R': @@ -148,7 +169,6 @@ int CmdHF14BCmdRaw (const char *Cmd) { break; case 's': case 'S': - flags |= ISO14B_CONNECT; select = TRUE; if (Cmd[i+2]=='s' || Cmd[i+2]=='S') { flags |= ISO14B_SELECT_SR; @@ -182,10 +202,10 @@ int CmdHF14BCmdRaw (const char *Cmd) { return 0; } - if(!power) + if (!power) flags |= ISO14B_DISCONNECT; - if(datalen>0) + if (datalen>0) flags |= ISO14B_RAW; // Max buffer is USB_CMD_DATA_SIZE @@ -200,49 +220,63 @@ int CmdHF14BCmdRaw (const char *Cmd) { bool success = TRUE; // get back iso14b_card_select_t, don't print it. - if(select) + if (select) success = waitCmd(FALSE); // get back response from the raw bytes you sent. - if(success && datalen>0) waitCmd(TRUE); + if (success && datalen>0) waitCmd(TRUE); return 1; } // print full atqb info +// bytes +// 0,1,2,3 = application data +// 4 = bit rate capacity +// 5 = max frame size / -4 info +// 6 = FWI / Coding options static void print_atqb_resp(uint8_t *data, uint8_t cid){ - //PrintAndLog (" UID: %s", sprint_hex(data+1,4)); - PrintAndLog (" App Data: %s", sprint_hex(data,4)); - PrintAndLog (" Protocol: %s", sprint_hex(data+4,3)); + //PrintAndLog(" UID: %s", sprint_hex(data+1,4)); + PrintAndLog(" App Data: %s", sprint_hex(data,4)); + PrintAndLog(" Protocol: %s", sprint_hex(data+4,3)); uint8_t BitRate = data[4]; - if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD"); - if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported"); - if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported"); - if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported"); - if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported"); - if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported"); - if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported"); - if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required"); - - uint16_t maxFrame = data[5]>>4; + if (!BitRate) PrintAndLog(" Bit Rate: 106 kbit/s only PICC <-> PCD"); + if (BitRate & 0x10) PrintAndLog(" Bit Rate: 212 kbit/s PICC -> PCD supported"); + if (BitRate & 0x20) PrintAndLog(" Bit Rate: 424 kbit/s PICC -> PCD supported"); + if (BitRate & 0x40) PrintAndLog(" Bit Rate: 847 kbit/s PICC -> PCD supported"); + if (BitRate & 0x01) PrintAndLog(" Bit Rate: 212 kbit/s PICC <- PCD supported"); + if (BitRate & 0x02) PrintAndLog(" Bit Rate: 424 kbit/s PICC <- PCD supported"); + if (BitRate & 0x04) PrintAndLog(" Bit Rate: 847 kbit/s PICC <- PCD supported"); + if (BitRate & 0x80) PrintAndLog(" Same bit rate <-> required"); + + uint16_t maxFrame = data[5] >> 4; if (maxFrame < 5) maxFrame = 8 * maxFrame + 16; else if (maxFrame == 5) maxFrame = 64; else if (maxFrame == 6) maxFrame = 96; else if (maxFrame == 7) maxFrame = 128; else if (maxFrame == 8) maxFrame = 256; else maxFrame = 257; - - PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : ""); + + PrintAndLog("Max Frame Size: %u%s bytes", maxFrame, (maxFrame == 257) ? "+ RFU" : ""); uint8_t protocolT = data[5] & 0xF; - PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " ); - PrintAndLog ("Frame Wait Int: %u", data[6]>>4); - PrintAndLog (" App Data Code: Application is %s",(data[6]&4) ? "Standard" : "Proprietary"); - PrintAndLog (" Frame Options: NAD is %ssupported",(data[6]&2) ? "" : "not "); - PrintAndLog (" Frame Options: CID is %ssupported",(data[6]&1) ? "" : "not "); - PrintAndLog ("Tag :"); - PrintAndLog (" Max Buf Length: %u (MBLI) %s",cid>>4, (cid & 0xF0) ? "" : "not supported"); - PrintAndLog (" Cid : %u", cid & 0x0f); + PrintAndLog(" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " ); + + uint8_t fwt = data[6]>>4; + if ( fwt < 16 ){ + uint32_t etus = (32 << fwt); + uint32_t fwt_time = (302 << fwt); + PrintAndLog("Frame Wait Integer: %u - %u ETUs | %u us", fwt, etus, fwt_time); + } else { + PrintAndLog("Frame Wait Integer: %u - RFU", fwt); + } + + PrintAndLog(" App Data Code: Application is %s",(data[6]&4) ? "Standard" : "Proprietary"); + PrintAndLog(" Frame Options: NAD is %ssupported",(data[6]&2) ? "" : "not "); + PrintAndLog(" Frame Options: CID is %ssupported",(data[6]&1) ? "" : "not "); + PrintAndLog("Tag :"); + PrintAndLog(" Max Buf Length: %u (MBLI) %s", cid>>4, (cid & 0xF0) ? "" : "chained frames not supported"); + PrintAndLog(" CDI : %u", cid & 0x0f); return; } @@ -361,10 +395,7 @@ bool HF14B_ST_Info(bool verbose){ memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t)); uint64_t status = resp.arg[0]; - if ( status > 0 ) { - rawClose(); - return FALSE; - } + if ( status > 0 ) return switch_off_field_14b(); //add locking bit information here. uint8_t data[16] = {0x00}; // uint8_t datalen = 2; @@ -387,7 +418,7 @@ bool HF14B_ST_Info(bool verbose){ // if (datalen != resplen || !crc) return rawClose(); //print_ST_Lock_info(data[5]>>2); - rawClose(); + switch_off_field_14b(); return TRUE; } @@ -420,17 +451,17 @@ bool HF14B_ST_Reader(bool verbose){ bool isSuccess = FALSE; + switch_on_field_14b(); + // SRx get and print general info about SRx chip from UID - UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}}; + UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_SELECT_SR, 0, 0}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { if (verbose) PrintAndLog("timeout while waiting for reply."); return FALSE; } - iso14b_card_select_t card; memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t)); @@ -456,7 +487,7 @@ bool HF14B_ST_Reader(bool verbose){ break; } - rawClose(); + switch_off_field_14b(); return isSuccess; } @@ -499,7 +530,7 @@ bool HF14B_Std_Reader(bool verbose){ break; } - rawClose(); + switch_off_field_14b(); return isSuccess; } @@ -666,7 +697,7 @@ int CmdHF14BWriteSri(const char *Cmd){ ); } - sprintf(str, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]); + sprintf(str, "-ss -c %02x %02x %02x %02x %02x %02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]); CmdHF14BCmdRaw(str); return 0; } @@ -771,41 +802,6 @@ int srix4kValid(const char *Cmd){ return 0; } -int CmdteaSelfTest(const char *Cmd){ - - uint8_t v[8], v_le[8]; - memset(v, 0x00, sizeof(v)); - memset(v_le, 0x00, sizeof(v_le)); - uint8_t* v_ptr = v_le; - - uint8_t cmdlen = strlen(Cmd); - cmdlen = ( sizeof(v)<<2 < cmdlen ) ? sizeof(v)<<2 : cmdlen; - - if ( param_gethex(Cmd, 0, v, cmdlen) > 0 ){ - PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen); - return 1; - } - - SwapEndian64ex(v , 8, 4, v_ptr); - - // ENCRYPTION KEY: - uint8_t key[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB }; - uint8_t keyle[16]; - uint8_t* key_ptr = keyle; - SwapEndian64ex(key , sizeof(key), 4, key_ptr); - - PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr, 8)); - - tea_decrypt(v_ptr, key_ptr); - PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr, 8)); - - tea_encrypt(v_ptr, key_ptr); - tea_encrypt(v_ptr, key_ptr); - PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr, 8)); - - return 0; -} - bool waitCmd(bool verbose) { bool crc = FALSE; @@ -817,24 +813,28 @@ bool waitCmd(bool verbose) { if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) { - status = (resp.arg[0] & 0xFFFF); + status = (resp.arg[0] & 0xFF); if ( status > 0 ) return FALSE; - + len = (resp.arg[1] & 0xFFFF); + memcpy(data, resp.d.asBytes, len); if (verbose) { - - ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2); - crc = ( data[len-2] == b1 && data[len-1] == b2); - - PrintAndLog("[LEN %u] %s[%02X %02X] %s", - len, - sprint_hex(data, len-2), - data[len-2], - data[len-1], - (crc) ? "OK" : "FAIL" - ); + if ( len >= 3 ) { + ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2); + crc = ( data[len-2] == b1 && data[len-1] == b2); + + PrintAndLog("[LEN %u] %s[%02X %02X] %s", + len, + sprint_hex(data, len-2), + data[len-2], + data[len-1], + (crc) ? "OK" : "FAIL" + ); + } else { + PrintAndLog("[LEN %u] %s", len, sprint_hex(data, len) ); + } } return TRUE; } else { @@ -854,7 +854,6 @@ static command_t CommandTable[] = { {"sriread", CmdHF14BReadSri, 0, "Read contents of a SRI512 | SRIX4K tag"}, {"sriwrite", CmdHF14BWriteSri, 0, "Write data to a SRI512 | SRIX4K tag"}, //{"valid", srix4kValid, 1, "srix4k checksum test"}, - //{"valid", CmdteaSelfTest, 1, "tea test"}, {NULL, NULL, 0, NULL} };