From: pwpiwi Date: Mon, 28 Jan 2019 20:54:34 +0000 (+0100) Subject: Add support for standard USB Smartcard Readers (#765) X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/a9104f7e31d6c134f9772fef6df2156ed06c9e78 Add support for standard USB Smartcard Readers (#765) * add PCSC interface (pcsc.c and pcsc.h) * new command 'sc select' to choose an USB Smartcard Reader * updated CI/.travis.yml accordingly * remove TCK CRC check in i2c.c It is done in PrintATR() anyway * Fix TCK CRC check in PrintATR() * Add PCSC reader support to 'sc info' --- diff --git a/CI/.travis.yml b/CI/.travis.yml index f5fed7a6..0c02c250 100644 --- a/CI/.travis.yml +++ b/CI/.travis.yml @@ -26,7 +26,7 @@ before_install: echo $REPOSITORY_EP; if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; - sudo apt-get install -y gcc-arm-none-eabi; + sudo apt-get install -y gcc-arm-none-eabi libpcsclite-dev; elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; if [[ "$REPOSITORY_EP" == "" ]]; then diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 1348ef04..cdc784c0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -34,6 +34,7 @@ #include "LCD.h" #endif +static uint32_t hw_capabilities; // Craig Young - 14a stand-alone code #ifdef WITH_ISO14443a @@ -312,8 +313,22 @@ extern struct version_information version_information; extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__; +void set_hw_capabilities(void) +{ + if (I2C_is_available()) { + hw_capabilities |= HAS_SMARTCARD_SLOT; + } + + if (false) { // TODO: implement a test + hw_capabilities |= HAS_EXTRA_FLASH_MEM; + } +} + + void SendVersion(void) { + set_hw_capabilities(); + char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */ char VersionString[USB_CMD_DATA_SIZE] = { '\0' }; @@ -347,7 +362,7 @@ void SendVersion(void) // Send Chip ID and used flash memory uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start; uint32_t compressed_data_section_size = common_area.arg1; - cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); + cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, hw_capabilities, VersionString, strlen(VersionString)); } // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 0560d306..7ef0c9c0 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -656,28 +656,6 @@ static bool GetATR(smart_card_atr_t *card_ptr) { if ( !sc_rx_bytes(card_ptr->atr, &len) ) return false; - uint8_t pos_td = 1; - if ( (card_ptr->atr[1] & 0x10) == 0x10) pos_td++; - if ( (card_ptr->atr[1] & 0x20) == 0x20) pos_td++; - if ( (card_ptr->atr[1] & 0x40) == 0x40) pos_td++; - - // T0 indicate presence T=0 vs T=1. T=1 has checksum TCK - if ( (card_ptr->atr[1] & 0x80) == 0x80) { - - pos_td++; - - // 1 == T1 , presence of checksum TCK - if ( (card_ptr->atr[pos_td] & 0x01) == 0x01) { - uint8_t chksum = 0; - // xor property. will be zero when xored with chksum. - for (uint8_t i = 1; i < len; ++i) - chksum ^= card_ptr->atr[i]; - if ( chksum ) { - if ( MF_DBGLEVEL > 2) DbpString("Wrong ATR checksum"); - } - } - } - card_ptr->atr_len = len; LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); diff --git a/client/Makefile b/client/Makefile index 81b46f23..aafbe375 100644 --- a/client/Makefile +++ b/client/Makefile @@ -35,13 +35,27 @@ APP_CFLAGS = include ../common/Makefile_Enabled_Options.common CFLAGS += $(APP_CFLAGS) ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS))) - SRC_SMARTCARD = cmdsmartcard.c + SRC_SMARTCARD = cmdsmartcard.c pcsc.c else SRC_SMARTCARD = endif -LUAPLATFORM = generic platform = $(shell uname) + +ifneq (,$(findstring MINGW,$(platform))) + PCSC_INCLUDES := + PCSC_LIBS = -lwinscard +else + ifeq ($(platform),Darwin) + PCSC_INCLUDES = + PCSC_LIBS = -framework PCSC + else + PCSC_INCLUDES := $(shell pkg-config --cflags libpcsclite) + PCSC_LIBS := $(shell pkg-config --libs libpcsclite) + endif +endif + +LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) LUAPLATFORM = mingw else @@ -259,7 +273,7 @@ all: lua_build jansson_build mbedtls_build cbor_build $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: proxmark3 flasher fpga_compress -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) +proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) $(PCSC_LIBS) proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua $(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ @@ -328,7 +342,7 @@ $(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%.d %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d - $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< + $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) $(PCSC_INCLUDES) -c -o $@ $< $(POSTCOMPILE) %.o: %.cpp diff --git a/client/cmdhw.c b/client/cmdhw.c index f994e938..b6a0d11f 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -20,7 +20,8 @@ #include "cmdmain.h" #include "cmddata.h" -/* low-level hardware control */ + +static uint32_t hw_capabilities = 0; static int CmdHelp(const char *Cmd); @@ -403,6 +404,10 @@ int CmdTune(const char *Cmd) return CmdTuneSamples(Cmd); } +bool PM3hasSmartcardSlot(void) { + return (hw_capabilities & HAS_SMARTCARD_SLOT); +} + int CmdVersion(const char *Cmd) { @@ -411,10 +416,11 @@ int CmdVersion(const char *Cmd) UsbCommand resp = {0, {0, 0, 0}}; SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { PrintAndLog("Prox/RFID mark3 RFID instrument"); PrintAndLog((char*)resp.d.asBytes); lookupChipID(resp.arg[0], resp.arg[1]); + hw_capabilities = resp.arg[2]; } return 0; } diff --git a/client/cmdhw.h b/client/cmdhw.h index b8e10f74..2db2fecc 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -11,6 +11,8 @@ #ifndef CMDHW_H__ #define CMDHW_H__ +#include + int CmdHW(const char *Cmd); int CmdDetectReader(const char *Cmd); @@ -23,5 +25,6 @@ int CmdSetDivisor(const char *Cmd); int CmdSetMux(const char *Cmd); int CmdTune(const char *Cmd); int CmdVersion(const char *Cmd); +bool PM3hasSmartcardSlot(void); #endif diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index edd51b72..a1793240 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -18,14 +18,18 @@ #include "smartcard.h" #include "comms.h" #include "protocols.h" +#include "cmdhw.h" #include "cmdhflist.h" #include "emv/apduinfo.h" // APDUcode description #include "emv/emvcore.h" // decodeTVL #include "crypto/libpcrypto.h" // sha512hash #include "emv/dump.h" // dump_buffer +#include "pcsc.h" #define SC_UPGRADE_FILES_DIRECTORY "sc_upgrade_firmware/" +static bool UseAlternativeSmartcardReader = false; // default: use PM3 RDV40 Smartcard Slot (if available) + static int CmdHelp(const char *Cmd); static int usage_sm_raw(void) { @@ -44,6 +48,17 @@ static int usage_sm_raw(void) { return 0; } +static int usage_sm_select(void) { + PrintAndLogEx(NORMAL, "Usage: sc select [h|] "); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, " : a card reader's name, wildcards allowed, leave empty to pick from available readers"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " sc select : list available card readers and pick"); + PrintAndLogEx(NORMAL, " sc select Gemalto* : select a connected Gemalto card reader" ); + return 0; +} + static int usage_sm_reader(void) { PrintAndLogEx(NORMAL, "Usage: sc reader [h|s]"); PrintAndLogEx(NORMAL, " h : this help"); @@ -185,6 +200,8 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { uint8_t T0 = atr[1]; uint8_t K = T0 & 0x0F; uint8_t TD1 = 0, T1len = 0, TD1len = 0, TDilen = 0; + bool protocol_T0_present = true; + bool protocol_T15_present = false; if (T0 & 0x10) { PrintAndLog("\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]); @@ -204,6 +221,14 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { if (T0 & 0x80) { TD1 = atr[2 + T1len]; PrintAndLog("\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1, TD1 & 0x0f); + protocol_T0_present = false; + if ((TD1 & 0x0f) == 0) { + protocol_T0_present = true; + } + if ((TD1 & 0x0f) == 15) { + protocol_T15_present = true; + } + T1len++; if (TD1 & 0x10) { @@ -221,6 +246,12 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { if (TD1 & 0x80) { uint8_t TDi = atr[2 + T1len + TD1len]; PrintAndLog("\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi, TDi & 0x0f); + if ((TDi & 0x0f) == 0) { + protocol_T0_present = true; + } + if ((TDi & 0x0f) == 15) { + protocol_T15_present = true; + } TD1len++; bool nextCycle = true; @@ -251,26 +282,27 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { } } - uint8_t vxor = 0; - for (int i = 1; i < atrlen; i++) - vxor ^= atr[i]; + if (!protocol_T0_present || protocol_T15_present) { // there is CRC Check Byte TCK + uint8_t vxor = 0; + for (int i = 1; i < atrlen; i++) + vxor ^= atr[i]; + + if (vxor) + PrintAndLogEx(WARNING, "Check sum error. Must be 0 got 0x%02X", vxor); + else + PrintAndLogEx(INFO, "Check sum OK."); + } - if (vxor) - PrintAndLogEx(WARNING, "Check summ error. Must be 0 got 0x%02X", vxor); - else - PrintAndLogEx(INFO, "Check summ OK."); - if (atr[0] != 0x3b) PrintAndLogEx(WARNING, "Not a direct convention [ 0x%02x ]", atr[0]); - uint8_t calen = 2 + T1len + TD1len + TDilen + K; if (atrlen != calen && atrlen != calen + 1) // may be CRC PrintAndLogEx(ERR, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K); if (K > 0) - PrintAndLogEx(INFO, "\nHistorical bytes | len 0x%02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); + PrintAndLogEx(INFO, "\nHistorical bytes | len %02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]); if (K > 1) { PrintAndLogEx(INFO, "\tHistorical bytes"); @@ -280,26 +312,38 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { return 0; } -static bool smart_select(bool silent) { - UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) { - if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return false; +static bool smart_getATR(smart_card_atr_t *card) +{ + if (UseAlternativeSmartcardReader) { + return pcscGetATR(card); + } else { + UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; + SendCommand(&c); + + UsbCommand resp; + if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) { + return false; + } + + if (resp.arg[0] & 0xff) { + return resp.arg[0] & 0xFF; + } + + memcpy(card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); + + return true; } +} - uint8_t isok = resp.arg[0] & 0xFF; - if (!isok) { +static bool smart_select(bool silent) { + + smart_card_atr_t card; + if (!smart_getATR(&card)) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); return false; } if (!silent) { - smart_card_atr_t card; - memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); - PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); } @@ -379,6 +423,32 @@ static int smart_response(uint8_t *data) { return datalen; } + +int CmdSmartSelect(const char *Cmd) { + + const char *readername; + + if (tolower(param_getchar(Cmd, 0)) == 'h') { + return usage_sm_select(); + } + + if (!PM3hasSmartcardSlot() && !pcscCheckForCardReaders()) { + PrintAndLogEx(WARNING, "No Smartcard Readers available"); + UseAlternativeSmartcardReader = false; + return 1; + } + + int bg, en; + if (param_getptr(Cmd, &bg, &en, 0)) { + UseAlternativeSmartcardReader = pcscSelectAlternativeCardReader(NULL); + } else { + readername = Cmd + bg; + UseAlternativeSmartcardReader = pcscSelectAlternativeCardReader(readername); + } + + return 0; +} + int CmdSmartRaw(const char *Cmd) { int hexlen = 0; @@ -756,24 +826,12 @@ int CmdSmartInfo(const char *Cmd){ //Validations if (errors ) return usage_sm_info(); - UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) { - if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; - } - - uint8_t isok = resp.arg[0] & 0xFF; - if (!isok) { + smart_card_atr_t card; + if (!smart_getATR(&card)) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); return 1; } - smart_card_atr_t card; - memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); - // print header PrintAndLogEx(INFO, "--- Smartcard Information ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); @@ -830,22 +888,11 @@ int CmdSmartReader(const char *Cmd){ //Validations if (errors ) return usage_sm_reader(); - UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) { - if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; - } - - uint8_t isok = resp.arg[0] & 0xFF; - if (!isok) { + smart_card_atr_t card; + if (!smart_getATR(&card)) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); return 1; } - smart_card_atr_t card; - memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t)); PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); return 0; @@ -970,6 +1017,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, + {"select", CmdSmartSelect, 1, "Select the Smartcard Reader to use"}, {"list", CmdSmartList, 0, "List ISO 7816 history"}, {"info", CmdSmartInfo, 0, "Tag information"}, {"reader", CmdSmartReader, 0, "Act like an IS07816 reader"}, diff --git a/client/pcsc.c b/client/pcsc.c new file mode 100644 index 00000000..dd331d0a --- /dev/null +++ b/client/pcsc.c @@ -0,0 +1,177 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 piwi +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// PCSC functions to use alternative Smartcard Readers +//----------------------------------------------------------------------------- + +#include "pcsc.h" + +#include +#include +#include +#include + +#if defined (__APPLE__) +#include +#include +#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag))) +#define SCARD_CLASS_ICC_STATE 9 +#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) +#elif defined (_WIN32) +#include +#else +#include +#include +#endif + +#include "ui.h" +#include "util.h" +#include "cmdhw.h" + +static SCARDCONTEXT SC_Context; +static SCARDHANDLE SC_Card; +static DWORD SC_Protocol; +static char* AlternativeSmartcardReader = NULL; + + +char *getAlternativeSmartcardReader(void) +{ + return AlternativeSmartcardReader; +} + + +bool pcscCheckForCardReaders(void) +{ + LONG res = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &SC_Context); + if (res != SCARD_S_SUCCESS) { + return false; + } + + DWORD pcchReaders; + res = SCardListReaders(SC_Context, NULL, NULL, &pcchReaders); + if (res != SCARD_S_SUCCESS) { + SCardReleaseContext(SC_Context); + return false; + } + + if (res == SCARD_E_NO_READERS_AVAILABLE || res == SCARD_E_NO_SERVICE) { + SCardReleaseContext(SC_Context); + return false; + } + + return true; +} + + +static char *pickReader(LPTSTR readerlist) +{ + PrintAndLogEx(NORMAL, "Please select one of these:"); + PrintAndLogEx(NORMAL, " [0] PM3 RDV40 Smartcard Slot %s", PM3hasSmartcardSlot() ? "(default)" : "(default, not available)"); + + int num = 1; + for (LPTSTR p = readerlist; *p != '\0'; ) { + PrintAndLogEx(NORMAL, " [%1d] %s", num++, p); + while (*p++ != '\0') ; // advance to next entry + } + + num--; + + if (num == 1) { + printf("Your choice (0 or 1)?"); + } else { + printf("Your choice (0...%d)? ", num); + } + int selection = getch() - '0'; + printf("\n"); + + if (selection == 0) { + PrintAndLogEx(INFO, "Selected RDV40 Smartcard Slot"); + return NULL; + } + + if (selection >= 1 && selection <= num) { + LPTSTR p = readerlist; + for (int i = 1; i < selection; i++) { + while (*p++ != '\0') ; // advance to next entry + } + PrintAndLogEx(INFO, "Selected %s", p); + return p; + } + + PrintAndLogEx(INFO, "Invalid selection. Using RDV40 Smartcard Slot"); + return NULL; + +} + + +char *matchString(LPTSTR readerlist, const char *readername) +{ + return pickReader(readerlist); +} + + +bool pcscSelectAlternativeCardReader(const char *readername) +{ + DWORD readerlist_len; + LONG res = SCardListReaders(SC_Context, NULL, NULL, &readerlist_len); + if (res != SCARD_S_SUCCESS) { + return false; + } + + LPTSTR readerlist = calloc(readerlist_len, sizeof(char)); + res = SCardListReaders(SC_Context, NULL, readerlist, &readerlist_len); + if (res != SCARD_S_SUCCESS) { + free(readerlist); + return false; + } + + char *selected_readername = NULL; + if (readername) { + selected_readername = matchString(readerlist, readername); + } else { + selected_readername = pickReader(readerlist); + } + + if (selected_readername == NULL) { + free(readerlist); + return false; + } + + free(AlternativeSmartcardReader); + AlternativeSmartcardReader = malloc((strlen(selected_readername) + 1) * sizeof(char)); + strcpy(AlternativeSmartcardReader, selected_readername); + + return true; +} + + +bool pcscGetATR(smart_card_atr_t *card) +{ + if (!card) { + return false; + } + + card->atr_len = 0; + memset(card->atr, 0, sizeof(card->atr)); + + LONG res = SCardConnect(SC_Context, AlternativeSmartcardReader, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &SC_Card, &SC_Protocol); + if (res != SCARD_S_SUCCESS) { + return false; + } + + DWORD atr_len = sizeof(card->atr); + res = SCardGetAttrib(SC_Card, SCARD_ATTR_ATR_STRING, card->atr, &atr_len); + if (res != SCARD_S_SUCCESS) { + return false; + } + card->atr_len = atr_len; + + // TODO: LogTrace without device + + return true; +} diff --git a/client/pcsc.h b/client/pcsc.h new file mode 100644 index 00000000..3dae06c0 --- /dev/null +++ b/client/pcsc.h @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 piwi +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// PCSC functions to use alternative Smartcard Readers +//----------------------------------------------------------------------------- + +#ifndef PCSC_H__ +#define PCSC_H__ + +#include +#include "smartcard.h" + +char *getAlternativeSmartcardReader(void); +bool pcscCheckForCardReaders(void); +bool pcscSelectAlternativeCardReader(const char *readername); +bool pcscGetATR(smart_card_atr_t *card); + +#endif diff --git a/client/proxmark3.c b/client/proxmark3.c index 6fb066e8..a25ecb41 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -28,6 +28,8 @@ #include "cmdhw.h" #include "whereami.h" #include "comms.h" +#include "pcsc.h" + void #ifdef __has_attribute @@ -48,6 +50,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { SetOffline(true); } + // file with script FILE *script_file = NULL; char script_cmd_buf[256] = {0}; // iceman, needs lua script the same file_path_buffer as the rest diff --git a/client/util.c b/client/util.c index dec7c5a1..f13d730c 100644 --- a/client/util.c +++ b/client/util.c @@ -52,7 +52,22 @@ int ukbhit(void) return ( error == 0 ? cnt : -1 ); } -#else +char getch(void) +{ + char c; + int error; + struct termios Otty, Ntty; + if ( tcgetattr(STDIN_FILENO, &Otty) == -1 ) return -1; + Ntty = Otty; + Ntty.c_lflag &= ~ICANON; /* disable buffered i/o */ + if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &Ntty))) { // set new attributes + c = getchar(); + error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes + } + return ( error == 0 ? c : -1 ); +} + +#else // _WIN32 #include int ukbhit(void) { diff --git a/client/util.h b/client/util.h index e3549c02..29dd7d5c 100644 --- a/client/util.h +++ b/client/util.h @@ -76,6 +76,11 @@ #endif extern int ukbhit(void); +#ifndef _WIN32 +extern char getch(void); +#else +#include +#endif extern void AddLogLine(char *fileName, char *extData, char *c); extern void AddLogHex(char *fileName, char *extData, const uint8_t * data, const size_t len); diff --git a/include/smartcard.h b/include/smartcard.h index 70245a78..82b346f5 100644 --- a/include/smartcard.h +++ b/include/smartcard.h @@ -10,6 +10,8 @@ #ifndef __SMARTCARD_H #define __SMARTCARD_H +#include + //----------------------------------------------------------------------------- // ISO 7618 Smart Card //----------------------------------------------------------------------------- diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 785435f0..4c27ac85 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -33,6 +33,7 @@ typedef struct { uint32_t asDwords[USB_CMD_DATA_SIZE/4]; } d; } PACKED UsbCommand; + // A struct used to send sample-configs over USB typedef struct{ uint8_t decimation; @@ -63,6 +64,9 @@ typedef struct{ #define CMD_STATUS 0x0108 #define CMD_PING 0x0109 +// controlling the ADC input multiplexer +#define CMD_SET_ADC_MUX 0x020F + // RDV40, Smart card operations #define CMD_SMART_RAW 0x0140 #define CMD_SMART_UPGRADE 0x0141 @@ -86,7 +90,6 @@ typedef struct{ #define CMD_HID_SIM_TAG 0x020C #define CMD_SET_LF_DIVISOR 0x020D #define CMD_LF_SIMULATE_BIDIR 0x020E -#define CMD_SET_ADC_MUX 0x020F #define CMD_HID_CLONE_TAG 0x0210 #define CMD_EM410X_WRITE_TAG 0x0211 #define CMD_INDALA_CLONE_TAG 0x0212 @@ -112,12 +115,8 @@ typedef struct{ #define CMD_VIKING_CLONE_TAG 0x0223 #define CMD_T55XX_WAKEUP 0x0224 #define CMD_COTAG 0x0225 -// misc extra #define CMD_PARADOX_CLONE_TAG 0x0226 - -/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ - // For the 13.56 MHz tags #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 #define CMD_READ_SRI512_TAG 0x0303 @@ -136,7 +135,6 @@ typedef struct{ #define CMD_SNOOP_HITAG 0x0370 #define CMD_SIMULATE_HITAG 0x0371 #define CMD_READER_HITAG 0x0372 - #define CMD_SIMULATE_HITAG_S 0x0368 #define CMD_TEST_HITAGS_TRACES 0x0367 #define CMD_READ_HITAG_S 0x0373 @@ -144,7 +142,6 @@ typedef struct{ #define CMD_WR_HITAG_S 0x0375 #define CMD_EMU_HITAG_S 0x0376 - #define CMD_SIMULATE_TAG_ISO_14443B 0x0381 #define CMD_SNOOP_ISO_14443B 0x0382 #define CMD_SNOOP_ISO_14443a 0x0383 @@ -251,6 +248,10 @@ typedef struct{ #define FLAG_TUNE_HF 2 #define FLAG_TUNE_ALL 3 +// Hardware capabilities +#define HAS_EXTRA_FLASH_MEM (1 << 0) +#define HAS_SMARTCARD_SLOT (1 << 1) + // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: /* Whether a bootloader that understands the common_area is present */