New version of pcsc-lite: 1.8.11

I just released a new version of pcsc-lite 1.8.11.

No major changes except polkit support (pushed by Red Hat).

Changes:
pcsc-lite-1.8.11: Ludovic Rousseau
14 February 2014

  • Add polkit support. See doc/README.polkit
  • /etc/reader.conf: CHANNELID and DEVICENAME are both optional but not at the same time
  • Some other minor improvements and bug corrections

New version of libccid: 1.4.15

I just released a version 1.4.15 of libccid the free software CCID class smart card reader driver.

Changes:
1.4.15 - 14 February 2014, Ludovic Rousseau

  • Add support of
    • DUALi DRAGON NFC READER
    • Feitian bR301
    • Gemalto CR30 reader in serial communication
    • Gemalto Ezio Shield Pro SC
    • IIT E.Key Almaz-1C
  • PIN_MODIFY_STRUCTURE & PIN_VERIFY_STRUCTURE: Fix calculation of the command length after pcsc-lite 1.8.9 (October 2013) changed the PCSC/reader.h header
  • Add specific PIN min (0) & max (25) sizes for SmartTerminal ST-2xxx
  • Do not get the data rates if bNumDataRatesSupported = 0
  • Support Gemalto features for pinpad readers MinimumPINSize, MaximumPINSize and bEntryValidationCondition are fetched from the reader firmware
  • disable (broken) pinpad for Fujitsu SmartCase KB SCR eSIG
  • examples/scardcontrol.c:
    • Parse codes returned by a pinpad (as SW1/SW2)
      Known codes for now are:
      • 0x9000: Success
      • 0x6400: Timeout
      • 0x6401: Cancelled by user
      • 0x6402: PIN mismatch
      • 0x6403: Too short or too long PIN
    • Retrieve min and max PIN sizes from the driver
    • Retrieve bEntryValidationCondition from the driver
  • be more strict for bInterfaceClass = 255 by also checking extra_length
  • some minor bugs removed

CCID descriptor statistics: dwDataRate

Article from the serie "CCID descriptor statistics"

The dwDataRate field is a number value from the CCID USB descriptor:

Default ICC I/O data rate in bps. This is an integer value

Example: 9600 bps is encoded as the integer value 9600. (00002580h)

dwDataRate # %
10752 bps 99 38.98 %
9600 bps 62 24.41 %
12903 bps 24 9.45 %
10753 bps 19 7.48 %
9946 bps 10 3.94 %
9909 bps 8 3.15 %
12407 bps 5 1.97 %
4032 bps 4 1.57 %
10080 bps 3 1.18 %
106000 bps 3 1.18 %
12902 bps 3 1.18 %
2688 bps 2 0.79 %
5376 bps 2 0.79 %
8065 bps 2 0.79 %
9924 bps 2 0.79 %
10573 bps 1 0.39 %
12672 bps 1 0.39 %
13440 bps 1 0.39 %
20112 bps 1 0.39 %
9677 bps 1 0.39 %
9910 bps 1 0.39 %


The default data rate is the data rate used before a new data rate is selected by the reader and/or the driver.


Most of the values are around 9600 bps which is the historical data rate value.

The 3 readers with dwDataRate = 106000 bauds are contactless readers.

CCID descriptor statistics: bNumDataRatesSupported

Article from the serie "CCID descriptor statistics"

The bNumDataRatesSupported field is a number value from the CCID USB descriptor:

The number of data rates that are supported by the CCID.

If the value is 00h, all data rates between the default data rate dwDataRate and the maximum data rate dwMaxDataRate are supported. Those values comply with § 1.2 and with all clock frequencies supported by the reader. See offset 18 and GET_CLOCK_FREQUENCIES § 5.3.2.

bNumDataRatesSupported # %
0 (will use whatever is returned) 181 71.26 %
53 20 7.87 %
106 15 5.91 %
1 7 2.76 %
0 4 1.57 %
4 4 1.57 %
5 4 1.57 %
11 3 1.18 %
127 3 1.18 %
52 2 0.79 %
7 2 0.79 %
8 2 0.79 %
15 1 0.39 %
19 1 0.39 %
254 1 0.39 %
3 1 0.39 %
40 1 0.39 %
45 1 0.39 %
57 1 0.39 %


This field is used to retrieve the list of all the data rates supported by the reader. The driver then select the best (fastest) data rate to use with the card according to the card ATR TA1 byte.

The longer the list, the better because it will give more choice for the driver to select the best data rate.

CCID descriptor statistics: bNumClockSupported

Article from the serie "CCID descriptor statistics"

The bNumClockSupported field is a number value from the CCID USB descriptor:

The number of clock frequencies that are supported by the CCID. If the value is 00h, the supported clock frequencies are assumed to be the default clock frequency defined by dwDefaultClock and the maximum clock frequency defined by dwMaximumClock.

The reader must implement the command PC_to_RDR_SetDataRateAndClockFrequency if more than one clock frequency is supported.

bNumClockSupported # %
0 (will use whatever is returned) 190 74.80 %
1 38 14.96 %
4 18 7.09 %
0 4 1.57 %
5 2 0.79 %
2 1 0.39 %
6 1 0.39 %


This field is not use by my CCID driver. The vast majority of readers have the "Automatic ICC clock frequency change according to parameters" bit set in dwFeatures. So the clock selection is made by the reader itself.

PCSC API spy, on Mac OS X

In a previous article "PCSC API spy, third try" I described a way to get a nice log of all the PC/SC calls made by an application. The example was using an application on GNU/Linux. A version for Mac OS X was planned but not yet available at that time.

I now realise I finished the Mac OS X version of pcsc-spy but have not yet blogged about it. It is time to fix this.

Installation

pcsc-spy is part of (the official) pcsc-lite. You can get it from the PCSC lite project web page. The latest version of pcsc-lite as I write this blog entry is 1.8.10.

$ curl -O https://alioth.debian.org/frs/download.php/file/3963/pcsc-lite-1.8.10.tar.bz2
$ tar xjf pcsc-lite-1.8.10.tar.bz2
$ cd pcsc-lite-1.8.10/
$ ./configure
[...]
$ cd src/spy
$ make
$ make framework

Now you can find a PCSC.framework directory that is the equivalent of libpcscspy.so on GNU/Linux.

The installation is not automatic but very easy. You copy the PCSC.framework directory in /tmp

$ cp -a PCSC.framework /tmp

Copy the official PCSC.framework (binary only) in /tmp

$ cp /System/Library/Frameworks/PCSC.framework/PCSC /tmp

Since we use the temporary directory /tmp the log/debug files will be automatically erased on the next system boot. No side effect.

Execution

In a Terminal application window (shell) run the pcsc-spy command:

$ ./pcsc-spy

In another Terminal application windows run the application you want to debug:

$ DYLD_FRAMEWORK_PATH=/tmp pcsctest

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Feitian bR301 00 00
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Feitian bR301 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 12 (0xc)
Current Reader ATR Value         : 3B A7 00 40 18 80 65 A2 08 01 01 52 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.
Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Feitian bR301 00 00
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Feitian bR301 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 12 (0xc)
Current Reader ATR Value         : 3B A7 00 40 18 80 65 A2 08 01 01 52 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.

PC/SC Test Completed Successfully !

In the first Terminal window you will get the colorfull (oh yeah!) log output:
SCardEstablishContext
 i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)
 o hContext: 0x0103253B
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000722]
SCardGetStatusChange
 i hContext: 0x0103253B
 i dwTimeout: 0xFFFFFFFF (4294967295)
 i cReaders: 0
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000044]
SCardListReaders
 i hContext: 0x0103253B
 i mszGroups: (null)
 o pcchReaders: 0x00000015
 o mszReaders: NULL
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000059]
SCardListReaders
 i hContext: 0x0103253B
 i mszGroups: (null)
 o pcchReaders: 0x00000015
 o mszReaders: Feitian bR301 00 00
 o mszReaders: 
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000042]
SCardGetStatusChange
 i hContext: 0x0103253B
 i dwTimeout: 0xFFFFFFFF (4294967295)
 i cReaders: 1
 i szReader: Feitian bR301 00 00
 i  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)
 i  dwEventState: SCARD_STATE_IGNORE, SCARD_STATE_CHANGED, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_EXCLUSIVE, SCARD_STATE_INUSE, SCARD_STATE_EMPTY, SCARD_STATE_MUTE, SCARD_STATE_PRESENT, SCARD_STATE_UNPOWERED, SCARD_STATE_ATRMATCH (0x00007FFF)
 i  Atr length: 0x00000012 (18)
 i  Atr: 00 00 00 00 68 70 E7 0D 01 00 00 00 01 00 00 00 00 00
 o szReader: Feitian bR301 00 00
 o  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)
 o  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)
 o  Atr length: 0x0000000C (12)
 o  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000163]
SCardConnect
 i hContext: 0x0103253B
 i szReader Feitian bR301 00 00
 i dwShareMode: SCARD_SHARE_SHARED (0x00000002)
 i dwPreferredProtocols: 0x00000003 (T=0, T=1)
 i phCard 0x00007FFF (32767)
 i pdwActiveProtocol 0x00000000 (0)
 o phCard 0x0001616A (90474)
 o dwActiveProtocol: T=0 (0x00000001)
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000411198]
SCardStatus
 i hCard: 0x0001616A
 i pcchReaderLen 0x00000034 (52)
 i pcbAtrLen 0x00000021 (33)
 o cchReaderLen 0x00000014 (20)
 o mszReaderName Feitian bR301 00 00
 o dwState 0x00000034 (52)
 o dwProtocol 0x00000001 (1)
 o bAtrLen 0x0000000C (12)
 o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000473]
SCardDisconnect
 i hCard: 0x0001616A
 i dwDisposition: SCARD_UNPOWER_CARD (0x00000002)
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000594971]
SCardReleaseContext
 i hContext: 0x0103253B
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000209]
SCardEstablishContext
 i dwScope: SCARD_SCOPE_SYSTEM (0x00000002)
 o hContext: 0x01035D3C
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000541]
SCardGetStatusChange
 i hContext: 0x01035D3C
 i dwTimeout: 0xFFFFFFFF (4294967295)
 i cReaders: 0
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000033]
SCardListReaders
 i hContext: 0x01035D3C
 i mszGroups: (null)
 o pcchReaders: 0x00000015
 o mszReaders: NULL
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000034]
SCardListReaders
 i hContext: 0x01035D3C
 i mszGroups: (null)
 o pcchReaders: 0x00000015
 o mszReaders: Feitian bR301 00 00
 o mszReaders: 
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000039]
SCardGetStatusChange
 i hContext: 0x01035D3C
 i dwTimeout: 0xFFFFFFFF (4294967295)
 i cReaders: 1
 i szReader: Feitian bR301 00 00
 i  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)
 i  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)
 i  Atr length: 0x0000000C (12)
 i  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52
 o szReader: Feitian bR301 00 00
 o  dwCurrentState: SCARD_STATE_EMPTY (0x00000010)
 o  dwEventState: SCARD_STATE_CHANGED, SCARD_STATE_PRESENT (0x00000022)
 o  Atr length: 0x0000000C (12)
 o  Atr: 3B A7 00 40 18 80 65 A2 08 01 01 52
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000129]
SCardConnect
 i hContext: 0x01035D3C
 i szReader Feitian bR301 00 00
 i dwShareMode: SCARD_SHARE_SHARED (0x00000002)
 i dwPreferredProtocols: 0x00000003 (T=0, T=1)
 i phCard 0x0001616A (90474)
 i pdwActiveProtocol 0x00000001 (1)
 o phCard 0x00011242 (70210)
 o dwActiveProtocol: T=0 (0x00000001)
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000411238]
SCardStatus
 i hCard: 0x00011242
 i pcchReaderLen 0x00000034 (52)
 i pcbAtrLen 0x00000021 (33)
 o cchReaderLen 0x00000014 (20)
 o mszReaderName Feitian bR301 00 00
 o dwState 0x00000034 (52)
 o dwProtocol 0x00000001 (1)
 o bAtrLen 0x0000000C (12)
 o bAtr 3B A7 00 40 18 80 65 A2 08 01 01 52
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000465]
SCardDisconnect
 i hCard: 0x00011242
 i dwDisposition: SCARD_UNPOWER_CARD (0x00000002)
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000594863]
SCardReleaseContext
 i hContext: 0x01035D3C
 => Command successful. (SCARD_S_SUCCESS [0x00000000])  [0.000000369]

Results sorted by total execution time
total time: 4.221649 sec
1.189834 sec (  2 calls) 28.18% SCardDisconnect
0.822436 sec (  2 calls) 19.48% SCardConnect
0.001263 sec (  2 calls)  0.03% SCardEstablishContext
0.000938 sec (  2 calls)  0.02% SCardStatus
0.000578 sec (  2 calls)  0.01% SCardReleaseContext
0.000369 sec (  4 calls)  0.01% SCardGetStatusChange
0.000174 sec (  4 calls)  0.00% SCardListReaders

Analysis

  • PC/SC commands are in blue
  • Input arguments are in green
  • Output arguments are in mangenta
  • Errors are in bold red
  • The last part of the log contains some statistics about: functions called and times consumed by each of them

Raw log file

If you want to store a log file for a later analysis or if you want to send me a log trace it is better to store the log in raw format. You can do that (as on GNU/Linux) by doing:

$ mkfifo ~/pcsc-spy
$ cat ~/pcsc-spy > logfile
and run your PC/SC application.

The API trace is stored in the file logfile. It is displayed using:

$ pcsc-spy.py logfile

Documentation

The documentation is included with the pcsc-lite source code and is also available online at pcsc-spy.1 manpage.

Conclusion

It is easy to generate a nice PC/SC log on Mac OS X.

New version of pcsc-tools: 1.4.22

I just released a new version of pcsc-tools. 2 new features in this version:

  1. automatic fetch of a new version of the ATR file if it was not upgraded in the last 10 hours.
  2. propose to use http://smartcard-atr.appspot.com/ to submit a new ATR
It should be easier to use with less manual work for you (to resynch the ATR list) and also less work for me (to update the ATR list) since the information should be complete and in the expected format.

Changes:
1.4.22 - 17 January 2014, Ludovic ROUSSEAU

CCID descriptor statistics: bcdDevice

Article from the serie "CCID descriptor statistics"

The bcdDevice field is a number value from the USB descriptor: Device release number in binary-coded decimal

bcdDevice # %
1.00 (firmware release?) 84 33.07 %
1.01 (firmware release?) 11 4.33 %
1.02 (firmware release?) 11 4.33 %
0.00 (firmware release?) 9 3.54 %
2.03 (firmware release?) 9 3.54 %
1.47 (firmware release?) 7 2.76 %
1.10 (firmware release?) 6 2.36 %
2.00 (firmware release?) 6 2.36 %
0.30 (firmware release?) 5 1.97 %
5.23 (firmware release?) 5 1.97 %
0.01 (firmware release?) 4 1.57 %
0.10 (firmware release?) 3 1.18 %
1.12 (firmware release?) 3 1.18 %
1.20 (firmware release?) 3 1.18 %
2.04 (firmware release?) 3 1.18 %
50.00 (firmware release?) 3 1.18 %
0.08 (firmware release?) 2 0.79 %
0.50 (firmware release?) 2 0.79 %
1.08 (firmware release?) 2 0.79 %
1.11 (firmware release?) 2 0.79 %
1.19 (firmware release?) 2 0.79 %
1.71 (firmware release?) 2 0.79 %
1.72 (firmware release?) 2 0.79 %
12.01 (firmware release?) 2 0.79 %
2.10 (firmware release?) 2 0.79 %
20.01 (firmware release?) 2 0.79 %
3.00 (firmware release?) 2 0.79 %
5.00 (firmware release?) 2 0.79 %
5.10 (firmware release?) 2 0.79 %
5.25 (firmware release?) 2 0.79 %
6.00 (firmware release?) 2 0.79 %
61.23 (firmware release?) 2 0.79 %
F0.F0 (firmware release?) 2 0.79 %
0.02 (firmware release?) 1 0.39 %
0.03 (firmware release?) 1 0.39 %
0.05 (firmware release?) 1 0.39 %
0.06 (firmware release?) 1 0.39 %
0.13 (firmware release?) 1 0.39 %
0.38 (firmware release?) 1 0.39 %
0.40 (firmware release?) 1 0.39 %
0.96 (firmware release?) 1 0.39 %
0.99 (firmware release?) 1 0.39 %
1.03 (firmware release?) 1 0.39 %
1.04 (firmware release?) 1 0.39 %
1.06 (firmware release?) 1 0.39 %
1.16 (firmware release?) 1 0.39 %
1.17 (firmware release?) 1 0.39 %
1.21 (firmware release?) 1 0.39 %
1.24 (firmware release?) 1 0.39 %
1.50 (firmware release?) 1 0.39 %
1.57 (firmware release?) 1 0.39 %
1.60 (firmware release?) 1 0.39 %
10.00 (firmware release?) 1 0.39 %
11.63 (firmware release?) 1 0.39 %
2.01 (firmware release?) 1 0.39 %
2.02 (firmware release?) 1 0.39 %
2.05 (firmware release?) 1 0.39 %
2.06 (firmware release?) 1 0.39 %
2.07 (firmware release?) 1 0.39 %
2.11 (firmware release?) 1 0.39 %
2.13 (firmware release?) 1 0.39 %
2.21 (firmware release?) 1 0.39 %
2.71 (firmware release?) 1 0.39 %
3.01 (firmware release?) 1 0.39 %
3.02 (firmware release?) 1 0.39 %
3.10 (firmware release?) 1 0.39 %
5.02 (firmware release?) 1 0.39 %
5.08 (firmware release?) 1 0.39 %
5.18 (firmware release?) 1 0.39 %
5.21 (firmware release?) 1 0.39 %
5.22 (firmware release?) 1 0.39 %
5.30 (firmware release?) 1 0.39 %
5.34 (firmware release?) 1 0.39 %
52.57 (firmware release?) 1 0.39 %
6.07 (firmware release?) 1 0.39 %
6.27 (firmware release?) 1 0.39 %
6.32 (firmware release?) 1 0.39 %
61.10 (firmware release?) 1 0.39 %
7.27 (firmware release?) 1 0.39 %
7.36 (firmware release?) 1 0.39 %
9.14 (firmware release?) 1 0.39 %


This field is the firmware release number. So it can be realy anything. The most common value is 1.00. But you can also find strange values as F0.F0 are also possible.

CCID descriptor statistics: bcdCCID

Article from the serie "CCID descriptor statistics"

The bcdCCID field is a number value from the CCID USB descriptor:

Integrated Circuit(s) Cards Interface Devices (CCID) Specification Release Number in Binary-Coded decimal (i.e., 2.10 is 0210h).

bcdCCID # %
1.10 123 48.43 %
1.00 121 47.64 %
1.01 5 1.97 %
10.01 3 1.18 %
2.00 2 0.79 %


The only valid realeases of the CCID specifications are 1.0 and 1.1. ICCD has only one released version: 1.00. So the other values are bogus.

Devices with bcdCCID = 1.01 are:
  • Broadcom Corp 5880
  • Broadcom Corp 5880
  • Cherry GmbH SmartBoard XX1X
  • Cherry GmbH SmartTerminal ST-1275
  • Cherry GmbH SmartTerminal XX1X
  • Dell Dell Smart Card Reader Keyboard
  • Gemalto IDBridge CT30
  • Gemalto IDBridge K30
Theses readers are bogus. 1.1 shall be coded as 1.10 (or 0x0110) as indicated in the specification.

Devices with bcdCCID = 10.01 are:
  • Avtor SC Reader 371
  • Avtor SecureToken
  • COVADIS Auriga
These readers are bogus. The 2 bytes of bcdCCID are reversed and are 0x1001 instead of 0x0110.

Devices with bcdCCID = 2.00 are:
  • OCS ID-One Cosmo Card USB Smart Chip Device
  • Philips Semiconductors JCOP41V221
These readers are declaring to comply to a CCID specification that is not yet released. Maybe they come from the future?

CCID descriptor statistics: bVoltageSupport

Article from the serie "CCID descriptor statistics"

The bVoltageSupport field is a number value from the CCID USB descriptor:

This value indicates what voltages the CCID can supply to its slots.
It is a bitwise OR operation performed on the following values:
  • 01h 5.0V
  • 02h 3.0V
  • 04h 1.8V
Other bits are RFU.

bVoltageSupport # %
0x07 110 43.31 %
0x01 87 34.25 %
0x03 37 14.57 %
0x02 19 7.48 %
0x00 1 0.39 %


The devices with bVoltageSupport = 0x00 is bogus. Even if the reader has the "Automatic ICC voltage selection" feature it should indicate the supported voltages.

Not all the possible combination are used. Readers are in one of the following categories (sorted by number of readers):
  • 0x07: 1.8V, 3V and 5V
  • 0x01: 5V only
  • 0x03: 3V and 5V
  • 0x02: 3V only
  • 0x00: bogus