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/cmdsmartcard.c b/client/cmdsmartcard.c index 54876b4e..3da2490d 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -200,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]); @@ -219,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) { @@ -236,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; @@ -266,26 +282,28 @@ 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); + PrintAndLogEx(INFO, "atrlen = %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"); @@ -295,26 +313,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); - uint8_t isok = resp.arg[0] & 0xFF; - if (!isok) { + 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; + } +} + +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)); } @@ -797,23 +827,11 @@ 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) { - 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)); + if (!smart_getATR(&card)) { + if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); + return 1; + } // print header PrintAndLogEx(INFO, "--- Smartcard Information ---------"); @@ -871,22 +889,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) { - 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)); + if (!smart_getATR(&card)) { + if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); + return 1; + } PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); return 0; diff --git a/client/pcsc.c b/client/pcsc.c index e7bdb186..576dc81c 100644 --- a/client/pcsc.c +++ b/client/pcsc.c @@ -15,6 +15,7 @@ #include #include #include "util.h" +#include "cmdhw.h" #ifdef __APPLE__ #include @@ -25,7 +26,9 @@ #include "ui.h" -static SCARDCONTEXT hContext; +static SCARDCONTEXT SC_Context; +static SCARDHANDLE SC_Card; +static DWORD SC_Protocol; static char* AlternativeSmartcardReader = NULL; @@ -37,20 +40,20 @@ char *getAlternativeSmartcardReader(void) bool pcscCheckForCardReaders(void) { - int res = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + LONG res = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &SC_Context); if (res != SCARD_S_SUCCESS) { return false; } DWORD pcchReaders; - res = SCardListReaders(hContext, NULL, NULL, &pcchReaders); + res = SCardListReaders(SC_Context, NULL, NULL, &pcchReaders); if (res != SCARD_S_SUCCESS) { - SCardReleaseContext(hContext); + SCardReleaseContext(SC_Context); return false; } if (res == SCARD_E_NO_READERS_AVAILABLE || res == SCARD_E_NO_SERVICE) { - SCardReleaseContext(hContext); + SCardReleaseContext(SC_Context); return false; } @@ -61,7 +64,7 @@ bool pcscCheckForCardReaders(void) static char *pickReader(LPTSTR readerlist) { PrintAndLogEx(NORMAL, "Please select one of these:"); - PrintAndLogEx(NORMAL, " [0] PM3 RDV40 Smartcard Slot"); + PrintAndLogEx(NORMAL, " [0] PM3 RDV40 Smartcard Slot %s", PM3hasSmartcardSlot() ? "(default)" : "(default, not available)"); int num = 1; for (LPTSTR p = readerlist; *p != '\0'; ) { @@ -108,13 +111,13 @@ char *matchString(LPTSTR readerlist, const char *readername) bool pcscSelectAlternativeCardReader(const char *readername) { DWORD readerlist_len; - int res = SCardListReaders(hContext, NULL, NULL, &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(hContext, NULL, readerlist, &readerlist_len); + res = SCardListReaders(SC_Context, NULL, readerlist, &readerlist_len); if (res != SCARD_S_SUCCESS) { free(readerlist); return false; @@ -139,14 +142,42 @@ bool pcscSelectAlternativeCardReader(const char *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; +} + /* int main(void) { LONG rv; - SCARDCONTEXT hContext; + SCARDCONTEXT SC_Context; LPTSTR mszReaders; - SCARDHANDLE hCard; + SCARDHANDLE SC_Card; DWORD dwReaders, dwActiveProtocol, dwRecvLength; SCARD_IO_REQUEST pioSendPci; @@ -157,25 +188,25 @@ int main(void) unsigned int i; - rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); - CHECK("SCardEstablishContext", rv) + rv = SCardEstablisSC_Context(SCARD_SCOPE_SYSTEM, NULL, NULL, &SC_Context); + CHECK("SCardEstablisSC_Context", rv) #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; - rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders); + rv = SCardListReaders(SC_Context, NULL, (LPTSTR)&mszReaders, &dwReaders); CHECK("SCardListReaders", rv) #else CHECK("SCardListReaders", rv) mszReaders = calloc(dwReaders, sizeof(char)); - rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); + rv = SCardListReaders(SC_Context, NULL, mszReaders, &dwReaders); CHECK("SCardListReaders", rv) #endif printf("reader name: %s\n", mszReaders); - rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, - SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); + rv = SCardConnect(SC_Context, mszReaders, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &SC_Card, &dwActiveProtocol); CHECK("SCardConnect", rv) switch(dwActiveProtocol) @@ -189,7 +220,7 @@ int main(void) break; } dwRecvLength = sizeof(pbRecvBuffer); - rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof(cmd1), + rv = SCardTransmit(SC_Card, &pioSendPci, cmd1, sizeof(cmd1), NULL, pbRecvBuffer, &dwRecvLength); CHECK("SCardTransmit", rv) @@ -199,7 +230,7 @@ int main(void) printf("\n"); dwRecvLength = sizeof(pbRecvBuffer); - rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof(cmd2), + rv = SCardTransmit(SC_Card, &pioSendPci, cmd2, sizeof(cmd2), NULL, pbRecvBuffer, &dwRecvLength); CHECK("SCardTransmit", rv) @@ -208,18 +239,18 @@ int main(void) printf("%02X ", pbRecvBuffer[i]); printf("\n"); - rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD); + rv = SCardDisconnect(SC_Card, SCARD_LEAVE_CARD); CHECK("SCardDisconnect", rv) #ifdef SCARD_AUTOALLOCATE - rv = SCardFreeMemory(hContext, mszReaders); + rv = SCardFreeMemory(SC_Context, mszReaders); CHECK("SCardFreeMemory", rv) #else free(mszReaders); #endif - rv = SCardReleaseContext(hContext); + rv = SCardReleaseContext(SC_Context); CHECK("SCardReleaseContext", rv) diff --git a/client/pcsc.h b/client/pcsc.h index 37ddc191..00046cf7 100644 --- a/client/pcsc.h +++ b/client/pcsc.h @@ -12,9 +12,11 @@ #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/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 //-----------------------------------------------------------------------------