Secure CCID (PC/SC) over Bluetooth

The Secure BLE CCID host interface is an extension of the BLE CCID (PC/SC) implementation. It uses the same characteristics, with the same constraints and restrictions, yet, when secure communication is enabled, the CCID over CCID frames are ciphered and authenticated.

Secure communication starts when the host initiate a mutual authentication sequence with the SpringCore device. The secure communication may be enforced in the configuration of the device. In this case, the device does not accept any command before the mutual authentication sequence takes place.

During the mutual authentication sequence, at set of session keys are generated from the nonces exchanged between the host and the device (one key for ciphering the payloads, two keys to compute the CMAC).

After the mutual authentication sequence, all the exchanges over the CCID_PC_To_RDR and CCID_RDR_To_PC characteristics must use secure communication.

The host may initiate a new mutual authentication sequence at any time, if the synchronization has been lost or to prevent using the session keys for a too long period.

Format of the messages with secure communication

CCID_Status

The specification of the CCID Status characteristic is not modified when secure communication is enabled.

CCID_PC_To_RDR

When secure communication is enabled, the payload is padded and ciphered (not the header), and a cryptographic message authentication code (CMAC) is added after the payload.

Format of the message (secure communication)

Bytes Content
0-9 Header
10-N Ciphered Payload = AES128-CBC ( Payload || Padding )
N+1 - N+4 Authentication code = AES128-CMAC ( Header || Ciphered Payload )
Byte Content
0 Command code, see table below
1-4 Length of payload, LSB-first.
The highest-level bit (bit 31) is set to denote that the payload is ciphered and that the length includes the padding and the CMAC.
5 Slot number
6 Sequence number
7-9 Command parameters

CCID_RDR_To_PC

When secure communication is enabled, the payload is padded and ciphered (not the header), and a cryptographic message authentication code (CMAC) is added after the payload.

Format of the message (secure communication)

Bytes Content
0-9 Header
10-N Ciphered Payload = AES128-CBC ( Payload || Padding )
N+1 - N+4 Authentication code = AES128-CMAC ( Header || Ciphered Payload )

Header

Byte Content
0 Response code, see table below
1-4 Length of payload, LSB-first.
The highest-level bit (bit 31) is set to denote that the payload is ciphered and that the length includes the padding and the CMAC.
5 Slot number
6 Sequence number
7 Slot status
8 Slot error
9 RFU

Mutual authentication

The mutual authentication is initiated by the host in a RDR_To_PC_Escape command, the payload of the command being a PROTOCOL : AUTHENTICATE instruction.

Notation

In the following paragraphs,

  • EECB (K, x) is the AES128-ECB Encrypt (one-block encipher) function, using key K over plain block x,
  • E-1ECB (K, y) is the AES128-ECB Decrypt (one-block decipher) function, using key K over ciphered block y,
  • ECBC (K, x, iv) is the AES128-CBC Encrypt (cipher block chaining mode, encipher) function, using key K and initialization vector iv over plain message x,
  • E-1CBC (K, y, iv) is the AES128-CBC Decrypt (cipher block chaining mode, decipher) function, using key K and initialization vector iv over ciphered message y.

Host AUTHENTICATE command

Bytes Value Explanations
0 6B PC_To_RDR_Escape
1-4 04000000 Plain communication, length of payload = 4 bytes
5 00 Slot number (don't care)
6 xx Current sequence number
7-9 000000 RFU
10 00 Class = PROTOCOL
11 0A Instruction = AUTHENTICATE
12 01 Authentication method = AES
13 00
01
User access (KAUTH = HostCommUserKey)
Admin access (KAUTH = HostCommAdminKey)

Device response - Authentication Step 1

The device

  1. Generates a 16-byte nonce RndB,
  2. Sends E ( K, RndB ) where KAUTH is the authentication key selected by the host, as it is known by the device (HostCommUserKey or HostCommAdminKey).
Bytes Value Explanations
0 83 RDR_To_PC_Escape
1-4 11000000 Plain communication, length of payload = 17 bytes
5 00 Slot number (same as host's)
6 xx Sequence number (same as host's)
7-9 000000 RFU
10 FF Status = FOLLOWING (see PROTOCOL : Status)
11-26 EECB ( KAUTH , RndB ) First device cryptogram

Host command - Authentication Step 2

The host

  1. Generates a 16-byte nonce RndA,
  2. Retrieves RndB by deciphering the response,
  3. Computes RndB' = RndB << 8 (rotate one byte to the left, with carry),
  4. Sends EECB ( KAUTH , RndA ) || EECB ( KAUTH , RndB' ) where KAUTH is the authentication key as it is known by the host.
Bytes Value Explanations
0 6B PC_To_RDR_Escape
1-4 22000000 Plain communication, length of payload = 34 bytes
5 00 Slot number (don't care)
6 xx Current sequence number (+1 since last exchange)
7-9 000000 RFU
10 00 Class = PROTOCOL
11 FF Instruction = FOLLOWING
12-43 EECB ( KAUTH , RndA ) || EECB ( KAUTH , RndB' ) Host cryptogram

The device deciphers the host cryptogram. If the decrypted RndB' matches with RndB, the device knows that it can trust the host.

Device response - Authentication Step 3

The device

  1. Retrieves RndA from the command,

  2. Computes RndA' = RndA << 8 (rotate one byte to the left, with carry),

  3. Sends EECB ( KAUTH , RndA' ).

Bytes Value Explanations
0 83 RDR_To_PC_Escape
1-4 17000000 Plain communication, length of payload = 17 bytes
5 00 Slot number (same as host's)
6 xx Sequence number (same as host's)
7-9 000000 RFU
10 00 Status = SUCCESS (see PROTOCOL : Status)
11-26 EECB ( KAUTH , RndA' ) Second device cryptogram

The host deciphers the device cryptogram. If the decrypted RndA' matches with RndA, the host knows that it can trust the device.

From now on, secure communication shall be used.

Session keys and first init vector

Both the host and the device generate the same session keys as follow:

  1. Assemble SV1 = RndA[0..3] || RndB[0..3] || RndA[8..11] || RndB[8..11]
  2. Assemble SV2 = RndA[4..7] || RndB[4..7] || RndA[12..15] || RndB[12..15]
  3. Compute the session encryption key KENC = EECB ( KAUTH , SV1 ),
  4. Compute the session authentication key KMAC = EECB ( KAUTH , SV2 ).
  5. Assemble SVMAC = RndA XOR RndB
  6. Compute the first initialization vector IV0 = EECB ( KMAC , SVMAC )

Ciphering and CMACing

Ciphering and CMACing is implemented only over the CCID_PC_TO_RDR and CCID_RDR_TO_PC characteristics. CCID_STATUS uses plain communication only.

Init vectors

The subsequent exchanges will use CBC (cipher block chaining). Both peers have to maintain two init vectors for the CBCs:

  • The IVSEND is used to cipher and MAC the outgoing messages,
  • The IVRECV is used to cipher and MAC the ingoing messages.

Both evolve independently, message after message.

For the first message, they are inited to the same value: IV0.

Frames without a payload

Only a 8-B CMAC is added after the 10-B CCID header.

Sender rules:

  1. Create the 10-B message, containing only the CCID header, with Length equal to 00000000,

  2. Compute CMAC = ECBC ( KMAC , Header || 8000..00 , IVSEND,N )

    where

    • Header || 8000..00 is the Header followed by 80 and padded with 00's to reach 16 bytes,
    • IVSEND,N is the current init vector for sending. Keep the complete CMAC as IVSEND,N+1 for the next transmission.
  3. Adjust the Length field in the Header to 08000080 (8-B of CMAC "in the payload", highest-level bit set to denote secure communication, transmitted LSB-first),

  4. Transmit the 8 first bytes of the CMAC at the end of the message.

Receiver rules:

  1. Recognize a secure, CMAC only message from its Length field equal to 08000080,

  2. Adjust the Length field to 00000000,

  3. Compute CMAC = ECBC ( KMAC , Header || 8000..00 , IVRECV )

    where

    • Header || 8000..00 is the Header followed by 80 and padded with 00's to reach 16 bytes,
    • IVRECV,N is the current init vector for receiving. Keep the complete CMAC as IVRECV,N+1 for the next reception.
  4. Verify that the 8 first bytes of the computed CMAC match with the ones received.

Frames with a payload

The CMAC is computed over the plain message, then the payload is padded and ciphered, and the 8-B CMAC is appended at the end of the message.

Sender rules:

  1. Create the message with a 10-B Header and PayloadPLAIN. The value of field Lengh is between 1 (0100000) and 64kB (000010000),

  2. Compute CMAC = ECBC ( KMAC , Header || PayloadPLAIN || 8000..00 , IVSEND,N )

    where

    • Header || PayloadPLAIN || 8000..00 is the message padded to reach a multiple of 16 bytes (if the original message length is already 16 bytes, 16 padding bytes are added),
    • IVSEND,N is the current init vector for sending. Keep the complete CMAC as IVSEND,N+1 for the next transmission.
  3. Add 80 at the end of the Payload and add as many 00's as needed to reach a multiple of 16 bytes; store the new length of the Payload in the Length field in the header,

  4. Cipher the Payload (not the Header!): PayloadCIPHER = ECBC ( KENC , PayloadPLAIN || Padding , IVSEND,N )

    (note that IVSEND,N is used, not IVSEND,N+1 that is the current CMAC but the next IV)

  5. Increase the Length field in the Header by 8 bytes (8-B of CMAC are to be added "in the payload"), and set the highest-level bit to denote secure communication,

  6. Transmit the 8 first bytes of the CMAC at the end of the message.

Receiver rules:

  1. Recognize a secure message from the highest-level bit set in Length,

  2. Reset the highest-level bit of Length and decrease the value of Length by 8,

  3. Decipher the Payload: PayloadPLAIN || Padding = E-1CBC ( KENC , PayloadCIPHER , IVRECV,N )

  4. Verify that the Padding is OK, decrease the value of Length to drop the Padding bytes,

  5. Compute CMAC = ECBC ( KMAC , Header || PayloadPLAIN || 8000..00 , IVRECV,N )

    where

    • Header || PayloadPLAIN || 8000..00 is the message padded to reach a multiple of 16 bytes (if the original message length is already 16 bytes, 16 padding bytes are added),
    • IVRECV,N is the current init vector for receiving. Keep the complete CMAC as IVRECV,N+1 for the next reception.
  6. Verify that the 8 first bytes of the computed CMAC match with the ones received.

Exception handling

If an error occurs during the mutual authentication process (typically because the host does not know the right KAUTH...), the ERR_AUTHENTICATION status is returned (see PROTOCOL : Status) but the BLE communication channel is kept open.

After the mutual authentication has been successfully performed, if the device

  • Receives a plain message instead of a secure message,
  • Receives a message with a wrong CMAC,
  • Receives a message which deciphers to a wrong Padding,

it does send the ERR_AUTHENTICATION error, and then closes the BLE link (disconnect).

The host has to connect again and start a new mutual authentication.