Data Transmission & Persistence¶
Message Format¶
All data is transmitted using Messages. Data may also be persisted or interchanged using messages, although a more compact form of the message might be used for long-term storage; for example, a persisted message might be compressed or re-encoded in a system-dependent binary format.
A message has 3 or 4 elements:
-
A length
-
A numeric type, see section §
-
Protocol version: the version of this protocol, expressed as a single integer being the major version * 100 + the minor version. For example, version 3.25 is represented as: 325.
-
When present, a body. The body is a JavaScript* Object Notation (JSON) object, transmitted using the encoding of section §: JSON* Distinguished Encoding. The format of the body is determined by the message type.
The other message elements are transmitted differently, depending on the protocol in use:
-
When Secure Device Onboard protocols are transmitted using a reliable stream protocol when Secure Device Onboard objects are persisted offline or using TCP, TLS, Bluetooth® technology, or the message is formatted as a specially-encoded JSON* sequence, containing all the message elements within it.
-
When Secure Device Onboard protocols are transmitted using RESTful protocols, length, numeric type, and protocol version are encoded into the REST headers. The body is transmitted as a REST payload. See section §: Transmission of Messages over a RESTful Protocol.
Transmission of Messages over a Stream Protocol and Persisted Messages¶
In some cases, messages are transmitted over a stream or datagram protocol. This is a protocol that reliably transmits a stream of data with no external or out-of-band information. In this case, all message data must be encapsulated in a single JSON* encoding.
Persisted Messages also use this encapsulation, please see section §: Persistence of Messages* for more information.
In the stream encapsulation of Secure Device Onboard, messages contain their own header, which is formed by encapsulating the message in a JSON* array with 3 or 4 elements:
[length, messageType, protocolVersion]
or
[length, messageType, protocolVersion, body]
Where:
-
Length appears in hex with exactly 6 hex digits, this is an exception to the normal encoding rules. The length includes all the characters in the message, including the length field itself. For example: ["000d",15,4] shows a message with 13 characters (including square brackets, with no body), and has a length of 0xd = 13. Note that the stream reader can determine the length of the message by reading the first 8 bytes, verifying that:
-
bytes 0-1 are open-square bracket and double-quote ([")
-
bytes 2-5 are hexadecimal values in the set: [0-9a-fA-F]
-
bytes 6-7 are double-quote and comma (,)
-
Then the message length in bytes is the hexadecimal number formed by bytes 2-5. The rest of the message can be read as the next message-length-8 bytes (the first 8 bytes have already been read, above).
-
Type: appears as a UInt8.
-
ProtocolVersion: appears as a UInt16.
-
Body: when present, the body is a JSON* object (including the brace brackets). The format and presence of the body is determined by the messagetype field.
When a stream protocol is used as the transport for the JSON* messages, the protocol proceeds as follows:
-
The Device always calls out as the stream client.
-
The Rendezvous Server always acts as the stream server.
-
The Owner Client acts as stream client for Transfer Ownership Protocol 0
TO0—interacting with the Rendezvous Server) and as stream server for Transfer Ownership Protocol 2 (TO2—interacting with the device). -
Server port assignment is currently defined as: TO0: 8040; TO1: 8041; TO2: 8042
-
Note that this does NOT affect port assignment when using RESTful protocols.
-
Messages are sent in the stream verbatim, without a separate messaging layer. Note that the message format is specifically designed with a fixed length field at the start (["000d",…) to allow the reader to read the length prefix of the message as a exactly 8 bytes and use this value to read the rest of the message exactly (length – 8 bytes).
-
The stream is kept open until the last message has been transmitted, then dropped using the normal stream close (For example, TCP FIN).
Maintenance of Stream Connection¶
When the client uses a stream connection, the entire connection proceeds across a single stream connection. In the case of a TCP stream, the client and server must configure their TCP implementation to send “keep-alives” frequently enough to keep the connection alive for the entire protocol transaction, including all stateful routers and firewalls that might be in the connection path. This is particularly an issue if either the client or the server takes a long delay to send some messages.
Transmission of Messages over a RESTful Protocol¶
When a REST protocol is used as transport for JSON* messages, the protocol proceeds as follows:
-
The REST client always uses an HTTP POST. The content type is application/json.
-
The REST server listens on a standard port1 for the transport protocol.
(HTTP: TCP/80, TLS: TCP/443) -
A Device which supports both TLS- and TCP-based REST will choose TLS for port 443 and TCP for all other ports.
-
If the port is not specified in RendezvousInfo, then for each IP address, TLS is tried first on port 443, then TCP is tried on port 80
-
It is possible for an Secure Device Onboard Device to support only TCP; an Secure Device Onboard Owner must support both TLS and TCP to support all possible Secure Device Onboard Devices. However it is recommended that Secure Device Onboard Devices support TLS where feasible.
-
Each REST transaction corresponds to a pair of JSON* messages.
-
The first message body is delivered in the POST body.
-
The second message is delivered as the entire POST response.
-
The length of the message is derived from the Content-Length field.
-
The URL for the message is of the form:
-
/mp/protocolversion/msg/msgnum
Where “/mp/” is verbatim; protocolversion is the protocol version number, expressed as a 3 digit decimal number; “/msg/” is verbatim, and msgnum is the message type (For example, from the table in section §). -
On first message, the REST server allocates a token, which must be maintained by the REST client for the duration of the connection.
-
The token is transmitted in the REST “Authorization” header.
-
The form of the token is implementation-specific. The simplest token is just a random number chosen to be unique from other tokens. A JSON* Web Token (JWT) might also be used.
-
The purpose of the token is to link REST calls to their protocol context within the JSON* message stream defined by the Secure Device Onboard Protocols. For example, a Java* implementation of Secure Device Onboard protocols might use a Java* object to store connection state. A new REST call can find this stored state by looking it up using the token as a key.
The Secure Device Onboard implementation has some latitude in both the form of the authorization token and how this token gets allocated for Secure Device Onboard protocols. In the typical (recommended) case, there is no initial authorization:
-
The initial REST request from the Device has an empty Authorization header or no such header. Secure Device Onboard protocols perform their own authorization within the message layer.
-
The Rendezvous Server detects such a header as a request for a new connection, and allocates a new token and associates it with the protocol context.
-
The Device saves the token and uses it on subsequent requests within the protocol, but not across protocols. An example is when TO1 uses one token, and TO2 uses a different token.
-
The Rendezvous Server uses the token to look up the protocol context so that each subsequent message is processed correctly.
If the Rendezvous Server wishes to obtain a token using specific REST credentials, these must be programmed into the device, then transmitted with or before the first Secure Device Onboard REST request. How this might be done is outside the scope of this document.
Maintenance of REST Connections¶
When transmitting messages across REST transactions, the client and server must take into account the possibility that the underlying network connection may time out between REST transactions. This is a problem if the time between a REST message and its response (that is, a POST and the POST response) is long or if the time between messages is long.
In general, each Secure Device Onboard protocol may send RESTful transactions across a single TCP stream (or SSL stream for HTTPS). We require that the TCP server side (the Owner or the Rendezvous Service) either respond to messages within one or two seconds, or generate TCP keep-alives sufficient to keep the connection open.
In the case of the TO1 and TO2 Protocols, the client is the Device, which might be running on a limited processor. In this case, some of cryptographic operations may take long enough for the underlying TCP connection to timeout between messages. The client must be robust in its ability to restore TCP / TLS connections for each RESTful transaction.
It is legal for the client to open a new TCP connection for each RESTful transaction, although it is recommended that the connection be used for multiple transactions where possible.
Persistence of Messages¶
A message may be persisted by storing it in a permanent medium. If necessary, multiple messages may be persisted in the same medium, one after the other. Since a message is a JSON* statement, it is legal JSON* to store messages in a JSON* object or JSON* sequence.
As the name “message” suggests, most messages are intended for ephemeral transmission only. Messages intended for persistence are defined to help in building tools for the following situations:
-
Defining, storing, and extending the Ownership Voucher.
-
Defining, signing, and storing the Ownership and Manufacturing Credentials.
-
Storing and exchange of public keys during extension of the Ownership Voucher.
Encrypted Message Body¶
Transfer Ownership 2 Protocol (TO2) includes a key exchange (for more information, see section §), which generates a session encryption key (SEK) and a session verification key (SVK). Subsequent message bodies in this protocol are protected by HMAC[SVK] and subsequently encrypted using the session key (Cipher[SEK]). An encrypted message has the following format:
-
A message header, as per section §.
-
A message body:
Code Sample |
---|
|
For example:
{"ct":[[16, “MTIzNDU2Nzg5MGFiY2RlZg==”],6,"QTA1Njc4"],"hmac":[32,"bbddee …44-b64-chars… 45="]}
The HMAC in tag “hmac” should be type HMAC-SHA256 (Secure Device Onboard 1.0 and Secure Device Onboard 1.1 protocol spec) or HMAC-SHA384 (future crypto). The HMAC algorithm must be the same as specified in the Cipher Suite field of the TO2.HelloDevice message (TO2.HelloDevice.cs). The HMAC uses SVK (from the key exchange) as the key. The HMAC covers:
-
the encrypted message body, which is JSON* ASCII data excluding the “ct” tag but includes the enclosing brackets of the “ct” field
-
The “ct” tag contains a base64 representation an encryption of the entire JSON* message being transmitted. The encryption is one of the ciphers described in the table below.
Cipher Suite Name (see TO2.HelloDevice) Secure Device Onboard 1.0/1.1 | Initialization Vector (IVData.iv in "ct" message header) | Meaning |
---|---|---|
AES128/CTR/HMAC-SHA256 (Secure Device Onboard 1.0 and Secure Device Onboard 1.1) | The IV for AES CTR Mode is 16 bytes long in big-endian byte order, where: - The first 12 bytes of IV (nonce) are randomly generated at the beginning of a session, independently by both sides. - The last 4 bytes of IV (counter) is initialized to 0 at the beginning of the session. - The IV value must be maintained with the current session key. “Maintain” means that the IV will be changed by the underlying encryption mechanism and must be copied back to the current session state for future encryption. - For decryption, the IV will come in the header of the received message. The random data source must be a cryptographically strong pseudo random number generator (CSPRNG) or a true random number generator (TNRG). | This is the preferred cipher suite for Secure Device Onboard for 128-bit keys. Other suites are provided for situations where Device implementations cannot use this suite. AES in Counter Mode [6] with 128 bit key using the SEK from key exchange (see section §). |
AES128/CBC/HMAC-SHA256 (Secure Device Onboard 1.0 and Secure Device Onboard 1.1) | IV is 16 bytes containing random data, to use as initialization vector for CBC mode. The random data must be freshly generated for every encrypted message. The random data source must be a cryptographically strong pseudo random number generator (CSPRNG) or a true random number generator (TNRG). | AES in Cipher Block Chaining (CBC) Mode [3] with PKCS7 [17] padding. The key is the SEK from key exchange (see section §). Implementation notes: - Implementation may not return an error that indicates a padding failure. - The implementation must only return the decryption error after the "expected" processing time for this message. It is recognized that the first item is hard to achieve in general, but Secure Device Onboard risk is low in this area, because any decryption error will cause the connection to be torn down. |
AES256/CTR/HMAC-SHA384 | The IV for AES CTR Mode is 16 bytes long in big-endian byte order, where: - The first 12 bytes of IV (nonce) are randomly generated at the beginning of a session, independently by both sides. - The last 4 bytes of IV (counter) is initialized to 0 at the beginning of the session. - The IV value must be maintained with the current session key. “Maintain” means that the IV will be changed by the underlying encryption mechanism and must be copied back to the current session state for future encryption. - For decryption, the IV will come in the header of the received message. The random data source must be a cryptographically strong pseudo random number generator (CSPRNG) or a true random number generator (TNRG). | This is the preferred cipher suite for Secure Device Onboard for 256-bit keys. Other suites are provided for situations where Device implementations cannot use this suite. AES in Counter Mode [6] with 256 bit key using the SEK from key exchange (see section §). |
AES256/CBC/HMAC-SHA384 (Future crypto) | IV is 16 bytes containing random data, to use as initialization vector for CBC mode. The random data must be freshly generated for every encrypted message. The random data source must be cryptographically strong pseudo random number generator (CSPRNG) or a true random number generator (TNRG) | AES-256 in Cipher Block Chaining (CBC) Mode [15] with PKCS7[16] padding. The key is the SEK from key exchange (see section §). Implementation notes: - Implementation may not return an error that indicates a padding failure. - The implementation must only return the decryption error after the "expected" processing time for this message. It is recognized that the item is hard to achieve in general, but Secure Device Onboard risk is low in this area, because any decryption error causes the connection to be torn down. |
Message Types¶
This section defines all persisted and transmitted message types. Each message is described in greater detail in a later section, but the table here can provide an overview of the flow of each protocol.
JSON* object tag names are kept small to help constrained implementations. Within the limits of their brevity, they are chosen for mnemonic value. For example, the error message “ec” standard for “error code.”
Some values appear in successive versions within the protocol. For example, a nonce is often used to verify the “freshness” of a signature (that is, that the signature was performed on demand). Similarly, device GUIDs change, and several different public keys are used. When this happens, the convention is that the object tag is a letter describing the object, and a numeral describing the version. The versions are numbered from 1, based on the Device Initialize Protocol (DI). Persisted types typically use no numeral.
The following table describes all the messages in the protocol with their message types and names. The message contents are indicated in column 3, but the reader is referenced to the detailed section for each message to get a full description. For example, message comments have been removed.
The REST column of the table indicates the URL to use for this message type, when the transport is a RESTful protocol (HTTP, HTTPS, and others).
Note
Messages are not allowed to include whitespace and comments.
Error Message¶
The “catch-all” error message is sent whenever processing cannot continue. This includes protocol errors and any trust or security violations, including:
-
Failure to verify a signature (section §)
-
Revoked EPID Group or signature (SIGRL) (section §)
-
Rejection of Application ID or EPID Group Attributes (section §)
-
Failure to verify the Ownership Voucher against the Device HMAC (section §)
-
Failure to verify the internal consistency of the Ownership Voucher, or failure to verify any of the signatures in the Ownership Voucher against the Device Credentials and the Owner key challenge (section §)
-
Failure to verify the challenge for the Owner key (sections § & §) or the TO0D signature (section §)
-
Failure to verify a HMAC or to decrypt a message (section §)
-
Failure to interpret the ServiceInfo, or failures internal to the ServiceInfo modules (section §)
-
Failure to verify any nonce with the previously transmitted value (section § for example)
-
Any resource or communications failure that makes successful onboarding fail
The Secure Device Onboard protocol is always terminated after an error message, and all Secure Device Onboard error conditions send an error message. However, security errors might not indicate the exact cause of the problem, if this would cause a security issue.
The contents of the error message are intended to help diagnose the error. The “ec” tag is an error code, please see following section, Error Code Values, for detailed information. The “emsg” tag gives the message ID of the previous message, making it easier to put the error into context. The “em” tag gives a string suitable for logging about the error.
The string in the “em” tag must not include security details that are inappropriate for logging, such as a specific security condition, or any key or password information.
Type\# | Message Type Name | Message Contents | From | To | REST Transmission |
---|---|---|---|---|---|
255 | Error |
|
Any | Any | HTTP response with message type 255 when transmitted as HTTP response |
- POST /mp/VVV/msg/255, when transmitted as HTTP request
If the problem is found in a HTTP request, the ERROR message is sent as HTTP response. The body of the response is a Secure Device Onboard/JSON* message with message type 255, and the “emsg” tag indicates the message type of the HTTP request message. The flow is as follows:
-
HTTP request: POST /mp/VVV/msg/X, msg type = X
-
HTTP response: msg type = ERROR(255), emsg = X
-
Secure Device Onboard terminates in error on both sides
If the problem is found in a HTTP response, the ERROR message is sent as a new HTTP request, POST /mp/VVV/msg/255, and the “emsg” tag indicates the message type of the previous HTTP response message. The authentication token from the previous HTTP request appears in the HTTP request containing the ERROR message. Since the ERROR message terminates the Secure Device Onboard protocol, the HTTP response to an ERROR message is an HTTP empty message (zero length). The flow is as follows:
-
HTTP request: POST /mp/VVV/msg/Y, msg type = Y (for any message type Y)
-
HTTP response: msg type = X
-
HTTP request, POST /mp/VVV/msg/255: msg type = 255, emsg = X
-
HTTP response: <zero length>
-
Secure Device Onboard terminates in error on both sides
ERROR messages are never retransmitted, and an ERROR message must never generate an ERROR message in response.
Error Code Values¶
Error Code (EC) | Internal Name | Generated by Message | Description |
---|---|---|---|
001 | INVALID_JWT_TOKEN | DI.SetHMAC TO0.OwnerSign TO1.ProveToSDO TO2.HelloDevice TO2.GetOPNextEntry TO2.ProveDevice TO2.NextDeviceServiceInfo TO2.Done | JWT token is missing or authorization header value does not start with 'Bearer'. Each token has its own validity period, server rejects expired tokens. Server failed to parse JWT token or JWT signature did not verify correctly. The JWT token refers to the token mentioned in section § (which is not required by protocol to be a JWT token). The error message applies to non-JWT tokens, as well. |
002 | INVALID_OWNERSHIP_PROXY | TO0.OwnerSign | Ownership Voucher is invalid: One of Ownership Voucher verification checks has failed. Precise information is not returned to the client but saved only in service logs. |
003 | INVALID_OWNER_SIGN_BODY | TO0.OwnerSign | Verification of signature of owner message failed. TO0.OwnerSign message is signed by the final owner (using key signed by the last Ownership Voucher entry). This error is returned in case that signature is invalid. |
004 | INVALID_IP_ADDRESS | TO0.OwnerSign | IP address is invalid. Bytes that are provided in the request do not represent a valid IPv4/IPv6 address. |
005 | INVALID_GUID | TO0.OwnerSign | GUID is invalid. Bytes that are provided in the request do not represent a proper GUID. |
006 | RESOURCE_NOT_FOUND | TO1.HelloSDO TO2.HelloDevice | The owner connection info for GUID is not found. TO0 Protocol wasn't properly executed for the specified GUID or information that was stored in database has expired and/or has been removed. |
100 | MESSAGE_BODY_ERROR | DI.AppStart DI.SetHMAC TO0.Hello TO0.OwnerSign TO1.HelloSDO TO1.ProveToSDO TO2.HelloDevice TO2.GetOPNextEntry TO2.ProveDevice TO2.NextDeviceServiceInfo TO2.GetNextOwnerServiceInfo TO2.Done | Message Body is structurally unsound: JSON* parse error, or valid JSON*, but is not mapping to the expected Secure Device Onboard type (see section §) |
101 | INVALID_MESSAGE_ERROR | TO0.OwnerSign TO1.HelloSDO TO1.ProveToSDO TO2.HelloDevice TO2.GetOPNextEntry TO2.ProveDevice TO2.NextDeviceServiceInfo TO2.GetNextOwnerServiceInfo | Message structurally sound, but failed validation tests. The nonce didn’t match, signature didn’t verify, hash, or mac didn’t verify, index out of bounds, and others... |
500 | INTERNAL_SERVER_ERROR | DI.AppStart DI.SetHMAC TO0.Hello TO0.OwnerSign TO1.HelloSDO TO1.ProveToSDO TO2.HelloDevice TO2.GetOPNextEntry TO2.ProveDevice TO2.NextDeviceServiceInfo TO2.GetNextOwnerServiceInfo TO2.Done | Something went wrong which couldn’t be classified otherwise. (This was chosen to match the HTTP 500 error code.) |
Persisted Messages¶
Type# | Message Type Name | Description |
---|---|---|
1 | PM.CredOwner | This is the Ownership Credential that is stored in the device TEE during the Device Initialize Protocol (DI), and updated in Transfer Ownership 2 Protocol (TO2). |
2 | PM.CredMfg | This is the Manufacturing Credential that is stored in the device TEE during the Device Initialize Protocol (DI). It is never changed afterwards. |
3 | PM.OwnershipProxy | The [Ownership Voucher] is used to convey the trust of the device in the factory to the new owner. |
4 | PM.PublicKey | This message is used by each successive owner in the supply chain to identify his public key to the previous owner. The previous owner signs the public key (and other information) to extend the ownership voucher. |
5 | PM.ServiceInfo | This message is used to save the key-value pairs that are sent as part of the TO2.ReceiveDeviceInfo and TO2.SendSetupInfo messages. |
6 | PM.DeviceCredentials | This message is used to store the device state for implementations that use a filesystem instead of a TEE. It may also be signed or encrypted (sealed) in these implementations, to improve security. |
Device Initialize Protocol (DI)¶
Type\# | Message Type Name | Message Contents | From | To | REST Transmission |
---|---|---|---|---|---|
10 | [DI.AppStart] |
|
Dev TEE | Mfg station | POST /mp/VVV/msg/102 |
11 | [DI.SetCredentials] |
|
Mfg station | Dev TEE | (post response, includes authorization token) |
12 | [DI.SetHMAC] |
|
Dev TEE | Mfg station | POST /mp/VVV/msg/12 |
13 | [DI.Done] | \-no body- | Mfg station | Dev TEE | (post response with token) |
Transfer Ownership Protocol 0 (TO0)¶
Type# | Message Type Name | Message Contents | From | To | REST Transmission |
---|---|---|---|---|---|
20 | [TO0.Hello] |
|
New Owner Client | Rendezvous Server | POST /mp/VVV/msg/20 |
21 | [TO0.HelloAck] |
|
Rendezvous Server | New Owner Client | (post response, includes authorization token) |
22 | [TO0.OwnerSign] |
|
New Owner Client | Rendezvous Server | POST /mp/VVV/msg/22 |
25 | TO0.AcceptOwner |
|
Rendezvous Server | New Owner Client | (post response with token) |
Transfer Ownership Protocol 1 (TO1)¶
Type\# | Message Type Name | Message Contents | From | To | REST Transmission |
---|---|---|---|---|---|
30 | [TO1.HelloSDO] |
|
Device TEE | Rendezvous Server | POST /mp/VVV/msg/30 *GUID added to help token creation* |
31 | [TO1.HelloSDOAck] |
|
Rendezvous Server | Device TEE | (post response, includes authorization token) (please see section §) |
32 | [TO1.ProveToSDO] |
|
Device TEE | Rendezvous Server | POST /mp/VVV/msg/32 |
33 | [TO1.SDORedirect] |
|
Rendezvous Server | Device TEE | (post response with token) |
Transfer Ownership Protocol 2 (TO2)¶
Type# | Message Type Name | Message Contents | From | To | REST Transmission |
---|---|---|---|---|---|
40 | [TO2.HelloDevice] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/40 |
41 | [TO2.ProveOpHdr] |
|
New Owner Client | Device TEE | (post response, includes authorization token) Note: In this message, the pk tag must have the actual Owner key (not PKNull) to allow Device to verify signature immediately. |
42 | [TO2.GetOpNextEntry] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/42 |
43 | [TO2.OpNextEntry] |
|
New Owner Client | Device TEE | (post response with token) |
44 | [TO2.ProveDevice] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/44 Note: For EPID, "pk" contains EPID group number. Otherwise, it is PKNull. |
45 | [TO2.GetNext DeviceServiceInfo] |
|
New Owner Client | Device TEE | (post response with token) |
46 | [TO2.Next DeviceServiceInfo] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/46 |
47 | [TO2.SetupDevice] |
|
New Owner Client | Device TEE | (post response with token) Note: This is the “owner2” key, the replacement for the manufacturer’s key in the DI Protocol. It must not be PKNull. |
48 | [TO2.GetNext OwnerServiceInfo] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/48 |
49 | [TO2.Next OwnerServiceInfo] |
|
New Owner Client | Device TEE | (post response with token) |
50 | [TO2.Done] |
|
Device TEE | New Owner Client | POST /mp/VVV/msg/50 |
51 | [TO2.Done2] |
|
New Owner Client | Device TEE | (post response with token) |