Secure Communication

The Direct Protocol supports Secure Communication.

Secure Communication is activated by the PROTOCOL : AUTHENTICATE sequence.

Principles

Mutual authentication

The mutual authentication sequence

  1. Allows the device to trust the host, and opens the access to functions that requires evelated priviledges such as writing a new configuration,

  2. Allows the host to trust the device,

  3. Initiate a secure communication channel, with 2 session keys KENC and KMAC generated from the nonces.

Following the mutual authentication sequence on a communication channel, all exchanges on this channel must use secure messaging.

Secure messaging

Secure messaging involves two concepts:

  1. The content of the messages is ciphered (using KENC), to protect potentially-sensitive data against eavesdropping,

  2. The message are authenticated by a CMAC (using KMAC and a rolling init vector), to protect the channel against replay attacks, injection attacks, and even against the consequences of a lost message.

In the case of SpringCore Direct, there are 3 endpoints to consider:

  • The Command endpoint (Bulk_Out USB endpoint, Direct_Command BLE characteristics) in the host to device direction,
  • The Response endpoint (Bulk_In USB endpoint, Direct_Response BLE characteristics) in the device to host direction,
  • The Events endpoint (Interrupt_In USB endpoint, Direct_Events BLE characteristics) in the device to host direction.

Every endpoint must have its own rolling init vector, that evolves independently of the init vectors of the other channels.

Secure messaging over CCID channel

Refer to the CCID (PC/SC) over BLE implementation paragraph for details regarding the secure messaging for CCID over BLE.

Note 1: secure messaging is not available for CCID over USB (but mutual authentication is).

Note 2: in the case of CCID over BLE, the CCID_Status endpoint does not provide secure messaging (CCID_PC_To_RDR and and CCID_RDR_To_PC endpoints do).

Cookbook

Both the host and the device shall maintain three init vectors:

  • IVCOMMAND for the Command endpoint,
  • IVRESPONSE for the Response endpoint,
  • IVEVENTS for the Events endpoint.

After the authentication sequence, the three init vectors are initialized to IV0 (see PROTOCOL : AUTHENTICATE for the definition of IV0).

Command endpoint

Sender rules (host)

  1. Create a valid SpringCore Direct Command message as usual, but set bit 5 (Secure) of PCB to 1 in the Header,

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

    where

    • Header || Payload || 8000..00 is the plain message followed by 80 and padded with 00's to reach a multiple of 16 bytes,
    • IVCOMMAND,N is the current init vector for sending on the Command endpoint. Keep the complete CMAC as IVCOMMAND,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; adjust the LEN field in the header accordingly,

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

  5. Increase the LEN field in the Header by 8 bytes,

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

Receiver rules (device)

  1. Recognize a secure message from the bit 5 set in PCB,

  2. Decrease the value of LEN by 8,

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

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

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

    where

    • Header || PayloadPLAIN || 8000..00 is the plain message padded to reach a multiple of 16 bytes,
    • IVCOMMAND,N is the current init vector for receiving on the Command endpoint. Keep the complete CMAC as IVCOMMAND,N+1 for the next reception.
  6. Verify that the 8 first bytes of the computed CMAC match with the ones received.

Response endpoint

Sender rules (device)

  1. Create a valid SpringCore Direct Response message as usual, but set bit 5 (Secure) of PCB to 1 in the Header,

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

    where

    • Header || Payload || 8000..00 is the plain message followed by 80 and padded with 00's to reach a multiple of 16 bytes,
    • IVRESPONSE,N is the current init vector for sending on the Command endpoint. Keep the complete CMAC as IVRESPONSE,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; adjust the LEN field in the header accordingly,

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

  5. Increase the LEN field in the Header by 8 bytes,

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

Receiver rules (host)

  1. Recognize a secure message from the bit 5 set in PCB,

  2. Decrease the value of LEN by 8,

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

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

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

    where

    • Header || PayloadPLAIN || 8000..00 is the plain message padded to reach a multiple of 16 bytes,
    • IVRESPONSE,N is the current init vector for receiving on the Command endpoint. Keep the complete CMAC as IVRESPONSE,N+1 for the next reception.
  6. Verify that the 8 first bytes of the computed CMAC match with the ones received.

Events endpoint

Sender rules (device)

  1. Create a valid SpringCore Direct Events message as usual, but set bit 5 (Secure) of PCB to 1 in the Header,

  2. Compute CMAC = ECBC ( KMAC , Header || Payload || Message || 8000..00 , IVEVENTS,N )

    where

    • Header || Payload || 8000..00 is the plain message followed by 80 and padded with 00's to reach a multiple of 16 bytes,
    • IVEVENTS,N is the current init vector for sending on the Command endpoint. Keep the complete CMAC as IVEVENTS,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; adjust the LEN field in the header accordingly,

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

  5. Increase the LEN field in the Header by 8 bytes,

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

Receiver rules (host)

  1. Recognize a secure message from the bit 5 set in PCB,

  2. Decrease the value of LEN by 8,

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

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

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

    where

    • Header || PayloadPLAIN || 8000..00 is the plain message padded to reach a multiple of 16 bytes,
    • IVEVENTS,N is the current init vector for receiving on the Command endpoint. Keep the complete CMAC as IVEVENTS,N+1 for the next reception.
  6. Verify that the 8 first bytes of the computed CMAC match with the ones received.