Host Protocols Direct Protocol Secure Communication
April 13, 2023 at 2:39 AMSecure Communication
The Direct Protocol supports Secure Communication.
Secure Communication is activated by the PROTOCOL : AUTHENTICATE sequence.
Principles
Mutual authentication
The mutual authentication sequence
-
Allows the device to trust the host, and opens the access to functions that requires evelated priviledges such as writing a new configuration,
-
Allows the host to trust the device,
-
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:
-
The content of the messages is ciphered (using KENC), to protect potentially-sensitive data against eavesdropping,
-
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 (BulkOut USB endpoint, Direct_Command BLE characteristics) in the host to device direction,
- The Response endpoint (BulkIn USB endpoint, Direct_Response BLE characteristics) in the device to host direction,
- The Events endpoint (InterruptIn 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)
-
Create a valid SpringCore Direct Command message as usual, but set bit 5 (Secure) of PCB to
1
in the Header, -
Compute CMAC = ECBC ( KMAC , Header || Payload ||
8000..00
, IVCOMMAND,N )where
- Header || Payload ||
8000..00
is the plain message followed by80
and padded with00
’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.
- Header || Payload ||
-
Add
80
at the end of the Payload and add as many00
’s as needed to reach a multiple of 16 bytes; adjust the LEN field in the header accordingly, -
Cipher the Payload (not the Header!): PayloadCIPHER = ECBC ( KENC , PayloadPLAIN || Padding , IVCOMMAND,N ),
-
Increase the LEN field in the Header by 8 bytes,
-
Transmit the 8 first bytes of the CMAC at the end of the message.
Receiver rules (device)
-
Recognize a secure message from the bit 5 set in PCB,
-
Decrease the value of LEN by 8,
-
Decipher the Payload: PayloadPLAIN || Padding = E-1CBC ( KENC , PayloadCIPHER , IVCOMMAND,N )
-
Verify that the Padding is OK, decrease the value of LEN to drop the Padding bytes,
-
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.
- Header || PayloadPLAIN ||
-
Verify that the 8 first bytes of the computed CMAC match with the ones received.
Response endpoint
Sender rules (device)
-
Create a valid SpringCore Direct Response message as usual, but set bit 5 (Secure) of PCB to
1
in the Header, -
Compute CMAC = ECBC ( KMAC , Header || Payload ||
8000..00
, IVRESPONSE,N )where
- Header || Payload ||
8000..00
is the plain message followed by80
and padded with00
’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.
- Header || Payload ||
-
Add
80
at the end of the Payload and add as many00
’s as needed to reach a multiple of 16 bytes; adjust the LEN field in the header accordingly, -
Cipher the Payload (not the Header!): PayloadCIPHER = ECBC ( KENC , PayloadPLAIN || Padding , IVRESPONSE,N ),
-
Increase the LEN field in the Header by 8 bytes,
-
Transmit the 8 first bytes of the CMAC at the end of the message.
Receiver rules (host)
-
Recognize a secure message from the bit 5 set in PCB,
-
Decrease the value of LEN by 8,
-
Decipher the Payload: PayloadPLAIN || Padding = E-1CBC ( KENC , PayloadCIPHER , IVRESPONSE,N )
-
Verify that the Padding is OK, decrease the value of LEN to drop the Padding bytes,
-
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.
- Header || PayloadPLAIN ||
-
Verify that the 8 first bytes of the computed CMAC match with the ones received.
Events endpoint
Sender rules (device)
-
Create a valid SpringCore Direct Events message as usual, but set bit 5 (Secure) of PCB to
1
in the Header, -
Compute CMAC = ECBC ( KMAC , Header || Payload || Message ||
8000..00
, IVEVENTS,N )where
- Header || Payload ||
8000..00
is the plain message followed by80
and padded with00
’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.
- Header || Payload ||
-
Add
80
at the end of the Payload and add as many00
’s as needed to reach a multiple of 16 bytes; adjust the LEN field in the header accordingly, -
Cipher the Payload (not the Header!): PayloadCIPHER = ECBC ( KENC , PayloadPLAIN || Padding , IVEVENTS,N ),
-
Increase the LEN field in the Header by 8 bytes,
-
Transmit the 8 first bytes of the CMAC at the end of the message.
Receiver rules (host)
-
Recognize a secure message from the bit 5 set in PCB,
-
Decrease the value of LEN by 8,
-
Decipher the Payload: PayloadPLAIN || Padding = E-1CBC ( KENC , PayloadCIPHER , IVEVENTS,N )
-
Verify that the Padding is OK, decrease the value of LEN to drop the Padding bytes,
-
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.
- Header || PayloadPLAIN ||
-
Verify that the 8 first bytes of the computed CMAC match with the ones received.