diff --git a/README.md b/README.md
index d0dfa27..3967fdc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# SmartDeviceLink Protocol
-**Current Version: 5.4.0**
+**Current Version: 5.4.1**
## 1. Overview
The SmartDeviceLink protocol specification describes the method for establishing communication between an application and head unit and registering the application for continued communication with the head unit. The protocol is used as the base formation of packets sent from one module to another.
@@ -123,7 +123,7 @@ All transported data is formed with a header followed by an optional payload. Th
E |
1 bit |
- Encryption Flag 0x0 This packet is not encrypted 0x1 This packet is encrypted Note: Only available in Protocol Version 2 and higher |
+ Encryption Flag 0x0 This packet is not encrypted 0x1 This packet is encrypted Note: Only available in Protocol Version 2 and higher. Must be always set to zero for a First Frame |
Frame Type |
@@ -191,9 +191,9 @@ All transported data is formed with a header followed by an optional payload. Th
Frame Type = 0x00 (Control Frame)
0x0 - 0xFFFFFFFF reserved.
Frame Type = 0x02 (First Frame)
- 0x08 The data size for a first frame is always 8 bytes. In the payload, the first four bytes denote the Total Size of the data contained in all consecutive frames, and the second four bytes denote the number of consecutive frames following this one
+ 0x08 The data size for a first frame is always 8 bytes. In the payload, the first four bytes denote the Total Size of the data contained in all consecutive frames. This is always the size of whole non-encrypted payload (even if consecutive frames are encrypted). The second four bytes denote the number of consecutive frames following this one
Frame Type = 0x01 or 0x03 (Single or Consecutive Frame)
- The total bytes in this frame's payload
+ The total bytes in this frame's payload. If frame is encrypted this is the size of encrypted payload, otherwise size of non-encrypted payload.
@@ -665,7 +665,7 @@ Payload includes a constructed BSON object that has a single parameter of `proto
Payload |
- [protocolVersion: x.x.x] | [protocolVersion: x.x.x]
@@ -886,6 +886,10 @@ If a session has already been started, or can't be started, a `StartServiceNAK`
+##### 4.2.5 Start Service
+
+The RPC service always needs to be started as unencrypted first, then it can be moved to an encrypted state by sending another `StartService` request containing an encryption flag set to `1` at a later point. Services of another type can be started as encrypted initially, i.e. it is not necessary to start them as unencrypted and then move to encrypted state using second `StartService` request (however such sequence of actions is also valid). See "7. Secured Communication" section for more details.
+
### 4.3 Registration
>Required: All Protocol Versions
@@ -1182,7 +1186,294 @@ Messages sent have a priority based on their Service Type. Lower values for serv
### 5.1 Control Service
>Required: All Protocol Versions
-The control service is the lowest level service available. While Control Frame packets are used frequently, the control service itself is rarely used.
+The control service is the lowest level service available. While Control Frame packets are used frequently, the control service itself is rarely used.
+
+#### 5.1.1 Security Query
+
+When establishing a secure connection, the TLS Payload is sent in a control service message with a binary query header. The size of this header is 12 bytes, similar to the RPC Payload Binary Header.
+
+##### 5.1.1.1 Payload
+
+The security query is able to contain JSON data as well as binary data. During the handshake the TLS handshake data is sent as binary data. See "Send Handshake Data" section for details.
+
+In case of an error, a notification is sent with an error code and error message as JSON data. See "Send Internal Error" section for details.
+
+
+ Binary Query Header |
+ JSON Data |
+ Binary Data |
+
+
+##### 5.1.1.2 Binary Header
+
+
+
+ Byte 1 |
+ Byte 2 |
+ Byte 3 |
+ Byte 4 |
+
+
+ Query Type |
+ Query ID |
+
+
+ Sequential Number |
+
+
+ JSON Size |
+
+
+
+###### 5.1.1.2.1 Binary Header Fields
+
+
+
+ Field |
+ Size |
+ Description |
+
+
+ Query Type |
+ 8 bit |
+
+ 0x00 Request
+ 0x01 - 0x0F Reserved
+ 0x10 Response
+ 0x11 - 0x1F Reserved
+ 0x20 Notification
+ 0x21 - 0xFE Reserved
+ 0xFF Invalid Query Type
+ |
+
+
+ Query ID |
+ 24 bit |
+
+ 0x000001 Send Handshake Data
+ 0x000002 Send Internal Error
+ 0x000003 - 0xFFFFFE Reserved
+ 0xFFFFFF Invalid Query ID
+ |
+
+
+ Sequential Number |
+ 32 bit |
+
+ Message ID can be set by the mobile libraries to track security messages.
+ The system uses the same Message ID when replying to the query allowing the mobile libraries to correlate messages.
+ |
+
+
+ JSON Size |
+ 32 bit |
+
+ The size of the JSON data following the binary query header.
+ Any additional data following the JSON data in the payload is binary data.
+ |
+
+
+
+##### 5.1.1.3 Send Handshake Data
+
+When performing the TLS handshake, the server sends a "Send Handshake Data" request containing its handshake data to the client, and the client sends a response with its own handshake data accordingly.
+
+###### 5.1.1.3.1 Request Payload
+
+**Note:** Prior to SDL Core version 8.0.0, Core sent the "Notification" type (`0x20`) in this message instead of "Request" (`0x00`). Client libraries should account for this when communicating with older versions of SDL Core.
+
+
+
+ Binary Query Header |
+
+
+ Query Type |
+ TLS Message Type |
+ Sequential Number |
+ JSON Size |
+
+
+ Request |
+ Send Handshake Data |
+ Any number to be used to correlate query messages |
+ Zero |
+
+
+ 0x00 |
+ 0x000001 |
+ 0xNNNNNNNN |
+ 0x00000000 |
+
+
+ Binary Data: SSL Handshake Request
+ |
+
+
+###### 5.1.1.3.2 Response Payload
+
+
+ Binary Query Header |
+
+
+ Query Type |
+ TLS Message Type |
+ Sequential Number |
+ JSON Size |
+
+
+ Response |
+ Send Handshake Data |
+ Any number to be used to correlate query messages |
+ Zero |
+
+
+ 0x10 |
+ 0x000001 |
+ 0xNNNNNNNN |
+ 0x00000000 |
+
+
+ Binary Data: SSL Handshake Response
+ |
+
+
+#### 5.1.1.4 Send Internal Error
+
+If an error occurs during the TLS handshake, a notification is sent with both JSON data and binary data describing the error. The JSON data contains the error code and an error text. The binary data is one single byte and only contains the error code.
+
+The error code in JSON data and the binary data are the same value from the same code list.
+
+##### 5.1.1.4.1 Payload
+
+The following query header is used by the system and the application to send error messages.
+
+
+
+ Binary Query Header |
+
+
+ Query Type |
+ TLS Message Type |
+ Sequential Number |
+ JSON Size |
+
+
+ Notification |
+ Send Internal Error |
+ Unused |
+ Size of the JSON data |
+
+
+ 0x20 |
+ 0x000002 |
+ 0xNNNNNNNN |
+ 0xNNNNNNNN |
+
+
+ JSON Data |
+
+
+ Binary Data: Single Byte Error Code |
+
+
+
+##### 5.1.1.4.2 JSON structure
+
+
+
+ Key |
+ Description |
+
+
+ id |
+ A decimal value representing an Error code. |
+
+
+ text |
+ A string describing the error. |
+
+
+
+##### 5.1.1.4.3 Error codes
+
+
+
+ Error code |
+ Byte |
+ Value |
+ Description |
+
+
+ ERROR_SUCCESS |
+ 0x00 | 0 |
+ Internal Security Manager value |
+
+
+ ERROR_INVALID_QUERY_SIZE |
+ 0x01 | 1 |
+ Wrong size of query data |
+
+
+ ERROR_INVALID_QUERY_ID |
+ 0x02 | 2 |
+ Unknown Query ID |
+
+
+ ERROR_NOT_SUPPORTED |
+ 0x03 | 3 |
+ SDL does not support encryption |
+
+
+ ERROR_SERVICE_ALREADY_PROTECTED |
+ 0x04 | 4 |
+ Received request to protect a service that was protected before |
+
+
+ ERROR_SERVICE_NOT_PROTECTED |
+ 0x05 | 5 |
+ Received handshake or encrypted data for not protected service |
+
+
+ ERROR_DECRYPTION_FAILED |
+ 0x06 | 6 |
+ Decryption failed |
+
+
+ ERROR_ENCRYPTION_FAILED |
+ 0x07 | 7 |
+ Encryption failed |
+
+
+ ERROR_SSL_INVALID_DATA |
+ 0x08 | 8 |
+ SSL invalid data |
+
+
+ ERROR_HANDSHAKE_FAILED |
+ 0x09 | 9 |
+ In case of all other handshake errors |
+
+
+ INVALID_CERT |
+ 0x0A | 10 |
+ Handshake failed because certificate is invalid |
+
+
+ EXPIRED_CERT |
+ 0x0B | 11 |
+ Handshake failed because certificate is expired |
+
+
+ ERROR_INTERNAL |
+ 0xFF | 255 |
+ Internal error |
+
+
+ ERROR_UNKNOWN_INTERNAL_ERROR |
+ 0xFE | 254 |
+ Error value for testing |
+
+
### 5.2 RPC Service
>Required: All Protocol Versions
@@ -1303,3 +1594,169 @@ To close out a communication session with the head unit, an application sends an
### 6.2 Closing Specific Services
If the application doesn't want to completely stop its session, but only wishes to close a specific session it can do so using an `EndService` packet that's service type matches the service that the application is trying to close. The `EndService` packet should include the hash ID in its payload that was contained in the `StartServiceACK` for that specific service.
+
+## 7. Secured Communication
+
+It is possible to establish a secured and encrypted communication with the system by setting the frame header encryption flag to `1` when starting a new service or by sending another `StartService` with the encryption flag set to `1` when the service is already established (this the required flow for the RPC service). If the authentication is successful, the system will reply with a `StartService ACK` frame with the encryption flag also set to `1` indicating that encrypted data is now accepted. If the authentication fails for some reason, the system will reset the TLS connection and return a `StartService NAK` frame.
+
+Below are possible combinations of the service encryption status and RPCs protection flag value.
+
+
+
+ Service Encryption Status |
+ RPC Type |
+ Requires Protection |
+ Expected SDL Behavior |
+
+
+ Encryption is not established |
+ Request |
+ yes |
+ SDL Core rejects the request with result code `ENCRYPTION_NEEDED` (please see policy updates for which RPCs need protection). |
+
+
+ no |
+ SDL Core continues processing the RPC request. |
+
+
+ Notification |
+ yes |
+ SDL Core does not send the notification. |
+
+
+ no |
+ SDL Core sends the notification unencrypted. |
+
+
+
+ Encryption is established |
+ Request |
+ yes |
+
+ If unencrypted, SDL Core rejects the request with an unencrypted response and result code `ENCRYPTION_NEEDED`.
+ If encrypted, SDL Core continues processing the request and sends an encrypted response.
+ |
+
+
+ no |
+
+ If unencrypted, SDL Core continues processing the request and sends an unencrypted response.
+ If encrypted, SDL Core continues processing the request and sends an encrypted response.
+ |
+
+
+ Notification |
+ yes |
+ SDL Core sends the notification encrypted. |
+
+
+ no |
+ SDL Core sends the notification unencrypted. |
+
+
+
+
+### 7.1 Authentication
+
+The authentication is done using TLS handshake. The TLS handshake process is defined by TLS and is not part of the SDL protocol.
+
+The below diagram shows the sequence of how the TLS handshake exchanges certificates to compute the master secret.
+
+![TLS Handshake activity diagram](https://user-images.githubusercontent.com/5848997/122258220-cb8b7100-ce9e-11eb-9b2a-a6194b0d1b68.png)
+
+Please see [SDL Overview Guides](https://smartdevicelink.com/en/guides/pull_request/sdl-overview-guides/security/protected-services/) for more details.
+
+The system can be configured to support one encryption method. The following methods are supported:
+
+- TLSv1
+- TLSv1.1
+- TLSv1.2
+- DTLSv1
+- SSLv3 (not supported on most newer systems)
+
+The system has to initiate with the corresponding client method. For instance, if the system is configured to use `DTLSv1`, it has to use the method `DTLSv1_client`. The application role has to be server and must use `DTLSv1_server`.
+
+The system also supports configurable [SSL Security level](https://www.openssl.org/docs/man1.1.0/man3/SSL_CTX_get_security_level.html) introduced in OpenSSL 1.1.0. This parameter can be changed by `SecurityLevel` parameter in the Core configuration file. By default, system uses security level 1 for TLS handshakes. At this time setting the security level higher than 1 for general internet use is likely to cause considerable interoperability issues and is not recommended. This is because the SHA1 algorithm is very widely used in certificates and will be rejected at levels higher than 1 because it only offers 80 bits of security.
+
+### 7.2 Handshake Frames
+
+The system will initiate a TLS handshake to authenticate the application where the system's role will be the client while the application's role will be the server. The system will do this only once if the application was not authenticated before in the current transport connection. The TLS handshake data is always sent in single frames. The service type for TLS handshake is the control service.
+
+#### 7.2.1 SDL Protocol Frame Header
+
+The following SDL frame header is used for every frame related to TLS handshake.
+
+
+
+ SDL Protocol Frame Header |
+
+
+ Version |
+ E |
+ Frame Type |
+ Service Type |
+ Frame Info |
+ Session ID |
+ Data Size |
+ Message ID |
+
+
+ Max major version supported by module and application |
+ no |
+ Single Frame |
+ Control Service |
+ Single Frame Info |
+ Assigned Session ID |
+
+ Query Binary Header +
+ JSON Data size +
+ Binary Handshake Data size
+ |
+ Enumerated number |
+
+
+ 0xN |
+ 0b0 |
+ 0b001 |
+ 0x00 |
+ 0x00 |
+ 0xNN |
+ 0xC + 0xNNNNNNNN + 0xNNNNNNNN |
+ 0xNNNNNNNN |
+
+
+
+#### 7.2.2 Security Query Binary Header
+
+The following query header is used by the system and the application to send TLS handshake data.
+
+
+
+ Binary Query Header |
+
+
+ Query Type |
+ TLS Message Type |
+ Sequential Number |
+ JSON Size |
+
+
+ Request |
+ Send Handshake Data |
+ Any number to be used to correlate query messages |
+ Zero |
+
+
+ 0x00 |
+ 0x000001 |
+ 0xNNNNNNNN |
+ 0x00000000 |
+
+
+ Binary TLS Handshake Data |
+
+
+
+### 7.3 Error handling
+
+In case of an error, the system and the application should reset the active SSL connection of the current transport connection. This impacts already established secured service sessions as all of them will be closed. The application will need to restart all services which require protection.