Saturday, November 5, 2011

Extended APDU support reported by PC/SC

This is a proposition I submitted to the PC/SC workgroup for the November 2011 meeting.

I removed the people names from the document and used XXX instead.

Please send/add comments if you have some.

Extended APDU support reported by PC/SC

Extended APDU support reported by PC/SC

Authors: Ludovic ROUSSEAU
XXX, Xiring
Version: 1.0, October 2011

The problem

More and more cards do support extended APDU. Some card commands may be available only using an extended APDU.

It is not possible for a PC/SC application to know if the connected reader (+ driver) does or does not support extended APDU. The only way is to use SCardTransmit() to send an extended APDU and try to analyze the error code. Analysing an error code is difficult since PC/SC does nor define an error to indicate that the reader does not support extended APDU. So an already existing error code will be returned instead.

It is then hard or impossible for an application to report a clear error to a user like: "your reader does not support extended APDU. Please use another reader model." The error returned by PC/SC may be caused by another problem.


At the CCID level it is easy to know if a CCID reader does support extended APDU or not by interpreting the dwFeatures field in the USB CCID descriptor. Readers defined as "Short APDU level exchange with CCID" are not able to manage extended APDU. See for more details and a list of readers in each categories.

The current proposal is to allow a PC/SC application to access this information at the PC/SC level.

Proposed solution using SCardControl()

Provide a new tag for FEATURE_GET_TLV_PROPERTIES to return the maximal size of data the reader (+ driver) can support.

For a reader supporting the full extended APDU size the value would be 0x10000 (64 kB). This size does not include the APDU header.

Tag name and value

Tag value:
4 bytes
as the other multi-bytes values returned by FEATURE_GET_TLV_PROPERTIES
  • 0: short APDU only
  • 0 < X <= 256: invalid values (RFU)
  • 256 < X <= 0x10000: short and extended APDU of up to X bytes of data
  • 0x10000 < X: invalid values (RFU)

Proposed solution using SCardGetAttrib()

As suggested by XXX I also propose to add a new entry in the table 3-1 in PC/SC part 3, chapter 'Enumeration of Device Capabilities'

I think the correct Information class is "Communications" so the tag should be the next free one: 0x0111.

The table should be updated to add a new line containing:
Information Class Data Element Tag Max Length Data Encoding
Communications Max APDU data size 0x0111 4 bytes DWORD

The PC/SC specification does not define the C macro name. But I propose to use:
XXX from YYY commented this idea with, November 11 2010:
I fully agree that we should find this information in part 3.

However, it is not so nice to do this on Windows as the driver would have to intercept the IOCTL_SMARTCARD_GET_ATTRIBUTE request and treat it locally instead of forward it to SMCLIB via SmartcardDeviceControl (see Note that the driver cannot rely on error code returned by SmartcardDeviceControl to process the request as the IRP has already been completed.

That's why I would prefer using a PC/SC V2 feature for that. PC/SC V2 features such as IFD_PIN_PROPERTIES and IFD_DISPLAY_PROPERTIES are also reader capabilities and should be returned via part 3 but PC/SC structures are restricted in Windows to known fields without possibility to extend them easily.

So we have 2 choices:
  • Add this information in part 3 (and be quite inconsistent with IFD_PIN_PROPERTIES and IFD_DISPLAY_PROPERTIES) and do not strictly respect MS rules on PC/SC drivers
  • Add this information to part 10 as a PC/SC V2 feature
What is Microsoft point of view on that?

AFAIK Microsoft never commented on this remark.

This solution would work just fine using pcsc-lite (and without changing pcsc-lite, just the driver).

Since this solution may be difficult to implement on Windows it may not be a so good solution after all and FEATURE_GET_TLV_PROPERTIES should be used instead.

Sample in pseudo code

If an application need to use extended APDU for a card it should first check support of extended APDU and inform the user in case of problem.

if (get dwMaxAPDUDataSize failed)
    /* we don't know if extended APDU is supported */
    Shall we continue or abort? Maybe it is safer to continue (as before).
    if (dwMaxAPDUDataSize == 0)
        error("your reader does not support extended APDU.")

    if (dwMaxAPDUDataSize < needed_size)
        error("your reader supports too short extended APDU.")
        error("We need at least %d bytes", dwMaxAPDUDataSize)
continue execution

Questions & Answers

On/off state

It is not enough to have a on/off bit to indicate extended APDU support. Some reader may not support a full length extended APDU (64kB) but only a limited length (1kB or 4kB). So the feature must report the maximal size.

Short APDU

This proposal does not try to define what a "short APDU" or an "extended APDU" are. Short and extended APDU are already defined in ISO 7813-3 chapter 12.1.3 (page 33) "Decoding conventions for command APDUs" where cases 1, 2S, 2E, 3S, 3E, 4S and 4E are defined.

Test suite

This proposal does not plan to provide (or extend) a test suite for extended APDU.

Adding extended APDU support in the Microsoft test suite is another subject. I don't think Microsoft is interested in improving the test suite.

Case 4 APDU

The PC/SC specification does not specify if a case 4 APDU is supported or not by PC/SC.

Extended APDU are not restricted to case 4 APDU. But also exist for case 2 and 3. It is another matter to define the behavior of PC/SC with a case 4 APDU (4S or 4E).

Driver support of extended APDU

The driver must also support extended APDU.

Of course the reader and the driver (and the PC/SC middleware) must support extended APDU. The driver will report support of extended APDU only if the reader and the driver both do support extended APDU.

CCID does report extended APDU support

Yes, a CCID reader will report support (or not) of extended APDU. But a PC/SC application do not have access to this information. The purpose of this proposal is to allow a PC/SC application to get this information from the PC/SC layer.

Some non-CCID readers may also support extended APDU. The same mechanism can be used for non-CCID readers. The driver just need to implement the support of dwMaxAPDUDataSize in FEATURE_GET_TLV_PROPERTIES.

Switch the reader in TPDU mode

" In case your reader does not support extended APDU your driver can switch into TPDU mode and provide the APDU to the reader in several TPDUs. "

I do not know any documented/official CCID command to switch a reader from APDU to TPDU. Most readers can't be switched from APDU to TPDU. So this is not an option in most of the cases.

If a reader can be switched from APDU to TPDU and then support extended APDU this should be transparent for the application. It is the job of the driver to do whatever is needed and use dwMaxAPDUDataSize in FEATURE_GET_TLV_PROPERTIES to inform the application that extended APDU are available for this reader.

Use block chaining at the CCID level

" If the reader were a CCID-APDU styled reader, it is the task for the CCID driver to limit the buffers to: dwMaxCCIDMessageLength

All these single buffers can be chained in the CCID protocol, by using the chaining byte. "

CCID block chaining is available only for readers in "Short and Extended APDU level" mode. For readers in "Short APDU level" mode the wLevelParameter parameter of PC_to_RDR_XfrBlock in bChainParameter parameter of RDR_to_PC_DataBlock are RFU and must be 0 (according to CCID v1.1 section 6.1.4 PC_to_RDR_XfrBlock page 30 and 6.2.1 RDR_to_PC_DataBlock page 49).

Maybe the Microsoft CCID driver do use wLevelParameter/bChainParameter even for a "Short APDU level" reader. But this is not CCID compliant.

CCID block chaining is not available for "Short APDU level" readers.