X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/bed3e4c20d2d885dbc560d21c1e954058145ae51..9658b9e137dbeb2f81ec3d72d3045c1ee22650dd:/client/cmdhf14a.c diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index f3189c10..24a66b88 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -11,9 +11,30 @@ #include "cmdhf14a.h" +#include +#include +#include +#include +#include +#include "util.h" +#include "util_posix.h" +#include "iso14443crc.h" +#include "data.h" +#include "proxmark3.h" +#include "ui.h" +#include "cmdparser.h" +#include "common.h" +#include "cmdmain.h" +#include "mifare.h" +#include "cmdhfmfu.h" +#include "mifarehost.h" +#include "emv/apduinfo.h" +#include "emv/emvcore.h" + static int CmdHelp(const char *Cmd); static int waitCmd(uint8_t iLen); + const manufactureName manufactureMapping[] = { // ID, "Vendor Country" { 0x01, "Motorola UK" }, @@ -220,8 +241,10 @@ int CmdHF14AInfo(const char *Cmd) PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]); + bool isMifareClassic = true; switch (card.sak) { case 0x00: + isMifareClassic = false; //***************************************test**************** // disconnect @@ -456,6 +479,19 @@ int CmdHF14AInfo(const char *Cmd) // try to see if card responses to "chinese magic backdoor" commands. mfCIdentify(); + if (isMifareClassic) { + switch(DetectClassicPrng()) { + case 0: + PrintAndLog("Prng detection: HARDEND (hardnested)"); + break; + case 1: + PrintAndLog("Prng detection: WEAK"); + break; + default: + PrintAndLog("Prng detection error."); + } + } + return select_status; } @@ -603,74 +639,73 @@ int CmdHF14ASnoop(const char *Cmd) { return 0; } +void DropField() { + UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; + SendCommand(&c); +} + int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int *dataoutlen) { - uint8_t data[USB_CMD_DATA_SIZE]; - int datalen; - uint8_t cmdc = 0; - uint8_t first, second; + uint16_t cmdc = 0; - if (activateField) - cmdc |= ISO14A_CONNECT; + if (activateField) { + cmdc |= ISO14A_CONNECT | ISO14A_CLEAR_TRACE; + } if (leaveSignalON) cmdc |= ISO14A_NO_DISCONNECT; - // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 - memcpy(data + 1, datain, datainlen); - data[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) - datalen = datainlen + 1; - - ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second); - data[datalen++] = first; - data[datalen++] = second; - // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes // https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size // here length USB_CMD_DATA_SIZE=512 // timeout timeout14a * 1.06 / 100, true, size, &keyBlock[6 * c], e_sector); // timeout is (ms * 106)/10 or us*0.0106 - UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_SET_TIMEOUT | cmdc, (datalen & 0xFFFF), 1000 * 1000 * 1.06 / 100}}; - memcpy(c.d.asBytes, data, datalen); + UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_APDU | ISO14A_SET_TIMEOUT | cmdc, (datainlen & 0xFFFF), 1000 * 1000 * 1.06 / 100}}; + memcpy(c.d.asBytes, datain, datainlen); SendCommand(&c); uint8_t *recv; UsbCommand resp; if (activateField) { - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLog("APDU ERROR: Proxmark connection timeout."); return 1; - if (resp.arg[0] != 1) + } + if (resp.arg[0] != 1) { + PrintAndLog("APDU ERROR: Proxmark error %d.", resp.arg[0]); return 1; + } } if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { recv = resp.d.asBytes; - uint8_t iLen = resp.arg[0]; + int iLen = resp.arg[0]; - *dataoutlen = iLen - 1 - 2; + *dataoutlen = iLen - 2; if (*dataoutlen < 0) *dataoutlen = 0; - memcpy(dataout, recv + 1, *dataoutlen); + memcpy(dataout, recv, *dataoutlen); - if(!iLen) + if(!iLen) { + PrintAndLog("APDU ERROR: No APDU response."); return 1; - - // check apdu length - if (iLen < 5) { - PrintAndLog("APDU ERROR: Small APDU response."); - return 2; } - - // check block - if (data[0] != recv[0]) { - PrintAndLog("APDU ERROR: Block type mismatch: %02x-%02x", data[0], recv[0]); + + // check block TODO + if (iLen == -2) { + PrintAndLog("APDU ERROR: Block type mismatch."); return 2; } // CRC Check - ComputeCrc14443(CRC_14443_A, recv, iLen, &first, &second); - if (first || second) { + if (iLen == -1) { PrintAndLog("APDU ERROR: ISO 14443A CRC error."); return 3; } + + // check apdu length + if (iLen < 4) { + PrintAndLog("APDU ERROR: Small APDU response. Len=%d", iLen); + return 2; + } } else { PrintAndLog("APDU ERROR: Reply timeout."); @@ -738,29 +773,18 @@ int CmdHF14AAPDU(const char *cmd) { cmdp++; } - PrintAndLog("--%s %s %s >>>> %s", activateField ? "sel": "", leaveSignalON ? "keep": "", decodeTLV ? "TLV": "", sprint_hex(data, datalen)); + PrintAndLog(">>>>[%s%s%s] %s", activateField ? "sel ": "", leaveSignalON ? "keep ": "", decodeTLV ? "TLV": "", sprint_hex(data, datalen)); - switch(ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, &datalen)) { - case 0: - break; - case 1: - PrintAndLog("APDU ERROR: Send APDU error."); - return 1; - case 2: - return 2; - case 3: - return 3; - case 4: - return 4; - default: - return 5; - } + int res = ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, &datalen); + + if (res) + return res; PrintAndLog("<<<< %s", sprint_hex(data, datalen)); PrintAndLog("APDU response: %02x %02x - %s", data[datalen - 2], data[datalen - 1], GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1])); - // here TLV decoder... + // TLV decoder if (decodeTLV && datalen > 4) { TLVPrintFromBuffer(data, datalen - 2); } @@ -890,7 +914,7 @@ int CmdHF14ACmdRaw(const char *cmd) { if(active || active_select) { - c.arg[0] |= ISO14A_CONNECT; + c.arg[0] |= ISO14A_CONNECT | ISO14A_CLEAR_TRACE; if(active) c.arg[0] |= ISO14A_NO_SELECT; }