Show / Hide Table of Contents

APDUs

An Application Protocol Data Unit (APDU) is simply a byte array that contains information following the ISO 7816 standard. There are two kinds of APDU:

  • Command
  • Response

The application running on the host machine (in PIV, that is "Off-Card") sends a Command APDU, and the YubiKey returns a response APDU.

Here is an example of a command APDU, and its and response.

command APDU:   00 87 03 9B 04 7C 02 80 00
response APDU:  7C 0A 80 08 3D 12 D6 71 F7 32 75 0D 90 00

Command APDU

There are up to seven elements in a command APDU. All command APDUs must have the first four, but it is legal to have the first four, five, six, or seven elements.

Table 1.1: Possible command APDU elements

Class Instruction Param 1 Param 2 Length of Data Data Max Length of Response Data
CLA INS P1 P2 Lc Data Le
CLA INS P1 P2 Lc Data (absent)
CLA INS P1 P2 Lc (absent) (absent)
CLA INS P1 P2 (absent) (absent) (absent)

For example, with the command APDU 00 87 03 9B 04 7C 02 80 00, these are the elements.

Table 1.2: Example command APDU elements

CLA INS P1 P2 Lc Data Le
00 87 03 9B 04 7C 02 80 00 (absent)

When building command APDUs in the SDK, the Le value will always be absent. The Le value is the maximum number of bytes in the data response. However, we will not specify that. Rather, we will let the YubiKey return as many bytes as it will, and check the length in each command class.

For example, when getting the version, we expect the return data to contain three bytes. We could set Le to 3. If so, then the class that actually sends the APDU (a Connection class) could check the length of the return data for an appropriate length. It could throw an exception or return an error.

However, we will instead make that check in the class that processes the specific command. In that way, if there is an error, the exception or error return can be generated by the class that knows what the command really is and create a more specific error message.

Response APDU

A response APDU consists of up to three elements.

Table 2.1: Possible response APDU elements

Data Status Word 1 Status Word 2
Return Data SW1 SW2
(absent) SW1 SW2

The last two bytes make up the status word, which is the error or success code. A response might contain data and the status word, or just the status word.

For example, with the response APDU 7C 0A 80 08 3D 12 D6 71 F7 32 75 0D 90 00, these are the elements.

Table 2.2: Example response APDU elements

Data SW1 SW2
7C 0A 80 08 3D 12 D6 71 F7 32 75 0D 90 00

Note that if there is an error, the response APDU will be two bytes only: SW1 and SW2. For example, the two-byte response of 6A 81 means "Card is blocked or command not supported".

Table 2.3: Response APDU indicating error

Data SW1 SW2
(absent) 6A 81

It is also possible to have a successful response APDU of only two bytes (no data). For example, suppose a command APDU requests the YubiKey set the number of PIN retries to five (instead of the default three). If the YubiKey successfully sets the retry count, there is no data to be returned, simply the status word, 90 00, indicating success.

Table 2.4: Response APDU indicating success with no data

Data SW1 SW2
(absent) 90 00

Chaining

There is a limit to the length of an APDU. For a command APDU, the limit is 260, and for a response APDU it is 258. If the amount of data to send would cause the APDU to exceed the limit, then it must be sent in more the one call.

Command APDU chaining

For a command APDU, chaining generally means setting the CLA to 10 | CLA (OR 0x10 with the CLA) for the APDUs which do not contain all the data. That is, use the normal CLA value, but just set the 0x10 bit. This indicates that there will be one or more command APDUs following, each with more data. Each of the following command APDUs will be the same as the first, just with more data. Then, for the last APDU (it holds the last of the data), set the CLA to be the regular value (no 0x10 bit).

For example, suppose you were sending the PIV command "Sign" for a 2048-bit RSA key. Here's what the command APDU would be.

CLA INS P1 P2 Lc Data Le
00 87 07 9c data len 7c L1 82 L2 81 L3 <encoded data to sign> absent

The Data is made up of these elements.

7C L1 82 L2 81 L3 Encoded Data
tag (auth template) length (DER) tag (response) length (DER) tag (challenge) length (DER) PKCS 1 v1.5 or PSS

The actual data we will send will be the following.

7C L1 82 L2 81 L3 Encoded Data
decimal 262 00 (this is not a response) decimal 256 PKCS 1 v1.5
7c 82 01 06 82 00 81 82 01 00 00 01 FF FF ... FF 00 <DigestInfo>
1 byte 3 1 1 1 3 256

There will be 268 bytes of data to send. The APDU's field Lc is one byte only, so the maximum value it can represent is 255. So break the data into two commands.

First command APDU

CLA INS P1 P2 Lc Data Le
10 87 07 9c d6 7c 82 01 06 82 00 81 82 01 00 00 01 ff ff ... ff absent
0x10 set, more data in following APDU Lc is 214, number of bytes in APDU's data 214 bytes

Second command APDU

CLA INS P1 P2 Lc Data Le
00 87 07 9c 34 ff ff ff 00 30 2f ... 1F absent
0x10 NOT set, last of the data in this APDU Lc is 52, number of bytes in APDU's data 52 bytes, the rest of the data

For both calls, the CLA, INS, P1, and P2 values are the same (except for the 0x10 bit in the CLA of the first call). The data is simply broken up.

Notice that the data in the first APDU contains some TLV constructions. But those tags are not in the second APDU's data. The second APDU simply continues with the data.

Response APDU chaining

If the YubiKey needs to return more than 256 bytes of data, it will need to break it up into multiple response APDUs.

The response APDU will contain up to 256 bytes of data, followed by SW1 and SW2. If SW1 is 61, then SW2 contains the number of bytes that still need to be returned.

The application running on the host (off-card) will receive the data, and when getting to the status word, will see that there are more bytes waiting to be transferred. At that point, the application needs to send a new command APDU: GET RESPONSE (00 c0 00 00).

For example, suppose the application wanted a copy of the attestation certificate. The process would look something like this.

command APDU:  00 cb 3f ff 05 5c 03 5f ff 01
response APDU: 53 82 02 f5 ... 61 ff
command APDU:  00 c0 00 00
response APDU: a9 e9 c1 5b ... 61 f9
command APDU:  00 c0 00 00
response APDU: 28 42 e5 8d ... 90 00

The first command APDU is GET DATA and the data it is requesting is the attestation cert. The first response APDU starts sending the cert. SW1 is 61, meaning there's more data, and SW2 is ff meaning there is at least 255 bytes of data still to transfer.

So the application sends the GET RESPONSE APDU. The YubiKey returns more data (simply picking up where it left off), and SW1 of 61 (more data still) and SW2 of f9 (only 249 bytes left).

The application sends GET RESPONSE again. This time the response is 249 bytes of data and SW1, SW2 of 90 00, meaning success, so there's no more data.

  • Improve this Doc
In this article
Back to top Generated by DocFX