Monday, September 25, 2017

ATR statistics: TA3 - Specific to T after T from 0 to 14 in TDi–1

Article from the series "ATR statistics.

TA3 - Specific to T after T from 0 to 14 in TDi–1

The ISO 7816-3 specification is not public. So I can't copy/paste part of the text. I will use Wikipedia instead.

For T = 1: maximum block size the card can receive. Encodes IFSC.
If T = 15: supported supply voltages and low power modes

TA3#%
137966.55 %
0xFE38818.73 %
0xC71095.26 %
0xC3351.69 %
0x80241.16 %
0x20190.92 %
0x43140.68 %
0x3C90.43 %
0x4780.39 %
0x8670.34 %
0xA070.34 %
0x0060.29 %
0x0360.29 %
0x5060.29 %
0x4250.24 %
0xC650.24 %
0x4040.19 %
0x6040.19 %
0x7040.19 %
0x6630.14 %
0x9030.14 %
0xFC30.14 %
0xFF30.14 %
0x4620.10 %
0x7620.10 %
0xF020.10 %
0xFA20.10 %
0xFB20.10 %
0x0710.05 %
0x2610.05 %
0x3A10.05 %
0x3D10.05 %
0x5210.05 %
0x6410.05 %
0x7C10.05 %
0x8310.05 %
0x8710.05 %
0xC210.05 %
0xEF10.05 %



The interpretation of TA3 depends on the protocol in use.

19% of ATRs have TA3 = 0xFE :

IFSC

The IFSC repartition is as follows:
IFSC#%
25436675,78 %
128214,35 %
32193,93 %
6091,86 %
13471,45 %
16071,45 %
8061,24 %
051,04 %
6440,83 %
9640,83 %
11240,83 %
6630,62 %
10230,62 %
14430,62 %
25230,62 %
25530,62 %
7020,41 %
11820,41 %
24020,41 %
25020,41 %
25120,41 %
3810,21 %
5810,21 %
8210,21 %
10010,21 %
12410,21 %
23910,21 %



With a logarithmic scale:


75% of ATRs with a IFSC defined in TA3 (so T=1 cards only) defines IFSC = 254.

Supported supply voltages

It is also possible to get the repartition of the class:
Class#%
A 5V B 3V C 1.8V11449,57 %
A 5V B 3V10646,09 %
B 3V C 1.8V52,17 %
B 3V31,30 %
B 3V C 1.8V D RFU E RFU20,87 %



50% of ATRs defining the class supports the 3 classes: A, B and C for 5 Volts, 3 Volts and 1.8 Volt.

46% of ATRs defining the class supports the classes A and B but not C.

2 cards declare the support of classes D and E that are RFU. They are 3B D9 18 00 C0 09 10 FE 54 59 46 4F 4E 45 00 00 00 and 3B DD 96 00 80 10 FE 80 31 80 63 01 FF C0 73 B3 21 1B 81 05. It may be a bug in the parsing since the class is defined only after T=15 protocol. But in the two examples the latest defined protocol is T=0. The ATRs may not be valid.

ATR statistics: TD2 - Structural, encodes Y3 and T

Article from the series "ATR statistics"

TD2 - Structural, encodes Y3 and T

The ISO 7816-3 specification is not public. So I can't copy/paste part of the text. I will use Wikipedia instead.

Refer to TD1 - Structural, encodes Y2 and T since the definition of TD2 is identical to TD1.

TD2#%
112354.20 %
0x3139318.97 %
0x0125012.07 %
0x1F1788.59 %
0x71502.41 %
0xB1482.32 %
0x91100.48 %
0x2160.29 %
0x3F50.24 %
0xF150.24 %
0x1020.10 %
0x1120.10 %



TD2 (as the other TDi bytes) is structural and indicates:
  • How to interpret the other ATR bytes
  • What communication protocol the card wants to use

For 54% of the ATRs no TD2 is present. So no other TA3, TB3, TC3 or TD3 is present and no new protocol is defined so the protocol defined by TD1 (if any) will be used.

For 19% of the ATRs TD2 = 0x31. The high nibble is 0011b so TA3, TB3 are present and T=1 protocol is defined. One such ATR is 3B 82 81 31 76 43 C0 02 C5.

For 12% of ATRs TD2 = 0x01. The high nibble is 0000b so no other TA3, TB3, TC3 or TD3 is present and T=1 protocol is defined. One such ATR is 3B 84 80 01 00 00 90 00 95.

0.10% of cards have TD2 = 0x10 and so (re)define the use of T=0. In fact what is important here is the high nibble of TD2 0001b that defines that TA3 is present. One such ATR is 3B DD 96 00 80 10 FE 80 31 80 63 01 FF C0 73 B3 21 1B 81 05.

I will not document all the other cases. I let this exercise to the reader.

Thursday, August 17, 2017

macOS Sierra bug: PC/SC transactions can't be nested

This is the second new PC/SC bug I report for macOS Sierra (first one was "macOS Sierra bug: SCardTransmit() silently truncates the card response").
I imagine this bug is also present in El Capitan and Yosemite but I have not checked.

SCardEndTransaction() ends all the transactions

SCardEndTransaction() does not work as it should, at least it does not work as the pcsc-lite version on GNU/Linux.
If you start a new PC/SC transaction inside a PC/SC transaction you expect the card to be available to another application only after all the transactions have ended.

For example if, in one application, you do:
A. SCardBeginTransaction()
  B. SCardBeginTransaction()
  C. SCardEndTransaction()
D. SCardEndTransaction()
You may expect that the card is available again for another application after the transaction is ended in step D.

What happens on macOS Sierra is that the transaction is ended at step C instead. So all the card APDU exchanges between steps C and D are not protected by the PC/SC transaction and can be mixed with APDU exchanges from any other applications.

It looks like PC/SC on macOS does not include a nested transaction counter. The first call to SCardEndTransaction() will end the transaction.

The sample code above is very simple and may seem stupid. But maybe the steps B and C are executed in another function of your application and then more hidden.

The macOS Sierra behaviour may produce very bad side effects. Imagine you use transactions to restrict access to the card private key after verifying the card PIN code. Then another application could also use the private key (between steps C and D) before the PIN is unverified just before step D.

See also

Apple bug report #33940052 "Smart card PC/SC transactions can't be nested"
Closed by Apple as a duplicate of #33752531.

Sample code


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif

#define pcsc_error(fct) printf(fct ": %s 0x%08lX\n", pcsc_stringify_error(err), (long)err)

int main(void)
{
    LPSTR mszReaders;
    DWORD err, cchReaders = 0;
    SCARDCONTEXT hContext = 0;
    SCARDHANDLE hCard = 0;

    err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    if (err != SCARD_S_SUCCESS) {
        pcsc_error("ScardEstablishedContext");
        return -1;
    }

    err = SCardListReaders(hContext, NULL, NULL, &cchReaders);
    if (err != 0) {
        pcsc_error("ScardListReaders");
        return -1;
    }
    mszReaders = calloc(cchReaders, sizeof(char));
    if (!mszReaders) {
        printf("calloc\n");
        return -1;
    }
    err = SCardListReaders(hContext,NULL, mszReaders, &cchReaders);
    if (err != SCARD_S_SUCCESS) {
        pcsc_error("ScardListReaders");
        return -1;
    }

    printf("Using reader: %s\n", mszReaders);

    DWORD dwActiveProtocol;
    printf("connect\n");
    err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
    if (err != SCARD_S_SUCCESS) {
        pcsc_error("SCardConnect");
        return 0;
    }

    printf("transaction 1\n");
    err = SCardBeginTransaction(hCard);
    if (err != SCARD_S_SUCCESS)
        pcsc_error("SCardBeginTransaction");

    printf("transaction 2\n");
    err = SCardBeginTransaction(hCard);
    if (err != SCARD_S_SUCCESS)
        pcsc_error("SCardBeginTransaction");

    printf("release transaction 2\n");
    err = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
    if (err != SCARD_S_SUCCESS)
        pcsc_error("SCardBeginTransaction");

    printf("Start me again and press enter\n");
    getchar();

    printf("release transaction 1\n");
    err = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
    if (err != SCARD_S_SUCCESS)
        pcsc_error("SCardBeginTransaction");

    err = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
    if (err != SCARD_S_SUCCESS)
        pcsc_error("SCardDisconnect");

    SCardReleaseContext(hContext);

    return 0;
}

Result (on Sierra)

$ CFLAGS="-framework PCSC" make main
cc -framework PCSC    main.c   -o main

First execution:
$ ./main_Mac
Using reader: Gemalto PC Twin Reader
connect
transaction 1
transaction 2
release transaction 2
Start me again and press enter

Second execution in another window:
$ ./main_Mac 
Using reader: Gemalto PC Twin Reader
connect
transaction 1
transaction 2
release transaction 2
Start me again and press enter

Expected result (on Debian)

$ CFLAGS=`pkg-config --cflags libpcsclite` LDFLAGS=`pkg-config --libs libpcsclite` make main
cc -pthread -I/usr/include/PCSC    -lpcsclite    main.c   -o main

First execution:
$ ./main_Linux 
Using reader: Gemalto PC Twin Reader 00 00
connect
transaction 1
transaction 2
release transaction 2
Start me again and press enter

Second execution in another window:
$ ./main_Linux 
Using reader: Gemalto PC Twin Reader 00 00
connect

Here you notice that the second execution is blocked at the "connect" step. Once you press "Enter" for the first execution then the transaction is released and the second execution can continue.

Known workaround

None. Do not use nested PC/SC transactions.

Saturday, June 24, 2017

New PyKCS11 1.4.3 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

Changes:
1.4.3 - June 2017, Ludovic Rousseau
  • Add support of CKM_RSA_PKCS_PSS mechanism
  • fix CKM_AES_CBC issue with Python 3
  • add Unitary Tests (make tests)
  • add tox support (automate and standardize testing in Python)
  • add coverage support (measuring code coverage of Python programs)
  • add Travis-CI configuration (automatic build and tests)
  • some minor improvements

Source code available on:

Results available on:

Saturday, June 17, 2017

New version of pcsc-lite: 1.8.22

I just released a new version of pcsc-lite 1.8.22.
pcsc-lite is a Free Software implementation of the PC/SC (or WinSCard) API for Unix systems.

Changes:
1.8.22: Ludovic Rousseau
17 June 2017
  • SCardCancel() was broken in 1.8.21. The call was blocking.
  • Enable use of info level logging for pcscd using -i/--info

Tuesday, May 30, 2017

pcsc_scan on Windows

Since version 1.5.0 of pcsc-tools (see "New version of pcsc-tools: 1.5.0, 1.5.1, 1.5.2") it is possible to build and run pcsc_scan on Windows.

MSYS2

From the project webpage:

MSYS2 is a software distro and building platform for Windows


At its core is an independent rewrite of MSYS, based on modern Cygwin (POSIX compatibility layer) and MinGW-w64 with the aim of better interoperability with native Windows software. It provides a bash shell, Autotools, revision control systems and the like for building native Windows applications using MinGW-w64 toolchains.

It features a package management system to provide easy installation of packages, Pacman. It brings many powerful features such as dependency resolution and simple complete system upgrades, as well as straight-forward package building.

Using MSYS2 it is easy to build/port a Unix program on Windows.

Build

To build the program use the classic sequence:
  1. ./configure
  2. make

$ ./configure
configure: loading site script /etc/config.site
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yes
checking build system type... x86_64-pc-msys
checking host system type... x86_64-pc-msys
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.exe
checking for suffix of executables... .exe
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
configure: WARNING: libpcsclite not found by pkg-config
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking winscard.h usability... yes
checking winscard.h presence... yes
checking for winscard.h... yes
checking for SCardEstablishContext... yes
checking for ANSI C header files... (cached) yes
checking for unistd.h... (cached) yes
checking time.h usability... yes
checking time.h presence... yes
checking for time.h... yes
checking for string.h... (cached) yes
checking stdio.h usability... yes
checking stdio.h presence... yes
checking for stdio.h... yes
checking for stdlib.h... (cached) yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking whether sys/types.h defines makedev... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands

Windows does not use pcsc-lite but its own natice WinSCard implementation. So it is not surprising that libpcsclite is not found by the configure script. What is important is that the header file winscard.h is found and that the function SCardEstablishContext() can be used.

$ make
make  all-am
make[1] : on entre dans le rĂ©pertoire « /home/Ludovic/pcsc-tools »
  CC       pcsc_scan-pcsc_scan.o
  CCLD     pcsc_scan.exe
make[1] : on quitte le rĂ©pertoire « /home/Ludovic/pcsc-tools »

Run

$ ./pcsc_scan.exe
PC/SC device scanner
V 1.5.2 (c) 2001-2017, Ludovic Rousseau 
Using reader plug'n play mechanism
Scanning present readers...
0: Broadcom Corp Contacted SmartCard 0
1: Broadcom Corp Contactless SmartCard 0
 
Tue May 30 18:04:07 2017
 Reader 0: Broadcom Corp Contacted SmartCard 0
  Card state: Card removed, 
 Reader 1: Broadcom Corp Contactless SmartCard 0
  Card state: Card removed, 
 Reader 2: \\?PnP?\Notification
  Card state: 

Limitations

The program has some limitations:
  • the special reader name \\?PnP?\Notification, used for reader hotplug events, has its name listed.
    This is not the case on GNU/Linux or macOS.
  • the program does not exit when the key sequence Ctrl-C is used. On Unix the Control-C sequence is used to send a SIGINT signal to the process. On Windows I do not know an equivalent.
    To quit pcsc_scan you have to terminate the process using the task manager. Not really a good User eXperience.

Conclusion

I do not plan to put a lot of effort into the Windows version of pcsc_scan. It was just an experiment.

If you want a change you can submit a Pull Request at the pcsc-tools github project.

Sunday, May 28, 2017

New version of pcsc-tools: 1.5.0, 1.5.1, 1.5.2

I just released a new version of pcsc-tools, a suite of tools for PC/SC.

The main changes are for the pcsc_scan command.

Changes:
1.5.2 - 28 May 2017, Ludovic ROUSSEAU
  • include gscriptor.desktop and test.script in the archive

1.5.1 - 28 May 2017, Ludovic ROUSSEAU
  • rename the archive pcsc-tools

1.5.0 - 28 May 2017, Ludovic ROUSSEAU
  • 221 new ATRs
  • pcsc_scan:
    • add APDU stress mode (-s) (send "Select MF" APDU in a loop)
    • display an animation while waiting for a card or reader event
  • use autoconf/automake