Message structure: Single Packet
Single Packets contain standard IoTize data and/or commands, and also authentication and decryption information to execute these commands or read this data outside a classic session (Login, session key, etc.)
Single Packets are normally used in classic sessions in these cases:
Data Logging: current values of the data grouped into a bundle can be stored into encrypted packets in the IoTize Non-volatile Memory.
Firmware update: the firmware can be updated by a new release from IoTize (with the agreement of the administrator).
Delayed Relay: when a relay (smartphone, potentially malicious) acts as a relay without being able to connect simultaneously to IoTize and the client (cloud), it is necessary to communicate through encrypted Single Packets.
Token: when a TokenServer is used to grant temporary accreditations to users, the Token must be encapsulated in a Single Packet
There are other possible uses for Single Packets. Potentially, they could completely replace the classic session. However, their size and encryption method make them more expensive in terms of computing time, memory and bandwidth. They should therefore only be used when necessary, and preferred in session mode (standard) when possible.
The messages all have the same structure:
Any encryption excludes SendTime and header1, but includes everything else.
|SendTime||4 bytes||Date/Time of sending in relative number of seconds.|
SendTime is NOT buffered, and is NOT used for CRC, crypto or other. It is added to the package at the time of shipment, and will be different if re-shipped. A second Time can be included in the data (for example LogTime for DataLogging).
Header1 consists of 12 unencrypted binary bytes, 32 ASCII-Hex characters:
|PacketLength||2 bytes||Total packet size in bytes, NOT including SendTime (but including PacketLength and the rest of the header)|
|PacketId||2 bytes||Identifier. Counter that is incremented for each DATALOG packet. This reference will be used, among other things, to acknowledge receipt in order to destroy the packets sent.|
|ConfigVersion||4 bytes||Version of the configuration as specified in the design document[Design - KEOLink.odt - 5.4.1 Object Interface - Resource ID 1024//10]. It is used by the server to ensure data consistency in case of configuration changes.|
|PacketType||1 byte||Message status: partially consistent with the Settings resource of the DataLogging object.
|UserId||1 byte||Information about the sender of the package. Will distinguish a packet issued by the Token Server from a packet issued by the Cloud Server or other, in order to derive the (de)encryption key and access rights.|
|Salt||2 bytes||Random number|
UserId is 1 byte but GroupID lwm2m is 2 bytes. Their relationship is:
UserID < 0x80 => GroupID = UserID
UserID > 0x80 => GroupID = 0xFF00 + UserID
UserID = 0 => Packet not encrypted, without rights (but extended if bit1 of type is 1)
UserID = 0x80 => Error ! (code reserved for future use, prohibited at this time)
Header1 is always in plain text and allows:
To determine the key that is used to code the content (salt, config,...).
Check that a message is not replayed (counter, time,...)
Check if it needs to be subject to special upstream processing (Acknowledge)
The rest of the package (Header2 + Data + CRC) can be encrypted.
Note: Following encryption, the length of the encrypted area may vary (typically, 16-byte alignment). Therefore, the difference between PacketLength and Datasize is unpredictable, contrary to what the tables above might suggest. In the case of an unencrypted packet, the difference between these two lengths is fixed.
Header2 consists of 6 binary bytes or 12 ASCII-Hex characters:
|LogTime||4 bytes||Date/Time of the recording in relative seconds.|
|Datasize||2 bytes||Message size (Data)|
Unlike Header1, Header2 can be encrypted.
Note: Following encryption, the length of the encrypted area may vary (typically, 16-byte alignment). Therefore, the difference between PacketLength and Datasize is unpredictable, contrary to what the above table might suggest. In the case of an unencrypted packet, the difference between these two lengths is fixed.
Note: Like PacketLength, DataSize can be a number of bytes (unencrypted data) or a number of 16-byte blocks (encrypted data) depending on the value of bit-1 of the packet type.
Note: other types of packages have other Header2 formats.
This depends on the type of package (DataLog, Event, Command,...).
Placed at the end of the package before encryption
|Pad||Round ( DataSize + 10) - (DataSize + 10)||Bytes of insignificant content, potentially necessary to align the size of the encrypted area with a multiple of 16 (if encrypted) or 4 (if unencrypted).|
|CRC||4 bytes||CRC or HMAC of the complete package except SendTime, PacketLength, CRC|
Pad: Encryption requires the encrypted area to be a multiple of 16 bytes (128 bit). The CRC operates in multiples of 4 bytes, so it is possible to add up to 15 bytes of padding to make the encrypted area size a multiple of 16 bytes. The content of the padding is not significant,and is not interpreted upon receipt, but it participates in the verification of the packet by being included in the CRC. It may be useful for the transmitter to fill it with random values, to hinder attackers, it could also be filled with constants (all at 0 or all at FF). However, it should not be filled with "stack remnants", or other potentially significant information, that will be seen by the receiver and could provide safety-compromising information.
Sizeof(Pad) = Round16 ( DataSize + sizeof(header2) + sizeof(CRC)) = Round16 ( DataSize + 10)
CRC: The CRC is a 32-bit field. By default, CRC32-Ethernet is used (polynomial = 0x4C11DB7).
Everything is encrypted except SendTime and PacketLength (a key is derived from the common master-key + salting). In the descending direction, it is a POST command in lwM2M format that will be reinjected.
The algorithm is the default AES-128.
See the following paragraph for the construction of the encryption key.
Encryption key: SinglePacketKey
SinglePacketKey is the result of hashing the password stored in the configuration file for the Profile referenced by'UserId').
//Todo : hash algorithm to be described.....
Complete unencrypted single packet
|SendTime||SendTime||4 bytes||Date/Time of sending in relative number of seconds.|
|Header1||PacketLength||2 bytes||Total packet size in bytes, NOT including SendTime. The CRC/HMAC starts here.|
|Header1||PacketId||2 bytes||Packet identifier.|
|Header1||ConfigVersion||4 bytes||Configuration version.|
|Header1||PacketType||1 byte||Message type|
|Header1||SenderId||1 byte||Identifier of the issuer|
|Header1||Salt||2 bytes||To salt a random number.|
|Header2||LogTime||4 bytes||Date/Time of the recording in relative seconds.|
|Header2||Datasize||2 bytes||Message size (Data)|
|Depends on the type of package|
|CRC||Pad||Round4 ( DataSize + 10) - (DataSize + 10)||Bytes of insignificant content, potentially necessary to align the size of the area verified by CRC with a multiple of 4.|
|CRC||CRC||4 bytes||CRC of the complete package except SendTime, PacketLength, CRC and Pad|
Complete encrypted single packet
|Used by hashkey (h)||h||h||h||h||h||h|
|Used by encryption (e)||e||e||e||e||e|
|Used by CRC (c)||c||c||c||c||c||c||c||c||c|
The key (hashage) uses the Header1 fields.
The encrypted area is the Header2 + Data + CRC fields.
The CRC uses fields PacketId throught to Pad inclusive.