OSCORE based security

Object Security for Constrained RESTful Environments [OSCORE] is an application layer security protocol protecting CoAP message exchanges.
Note: OSCORE is a standalone security mode and is not supported with TCP for now.
For LWM2M 1.1 devices, the use of OSCORE in CoAP is indicated with the OSCORE option present in the CoAP message [OSCORE]. It operates by transforming (encrypting and so on) an unprotected CoAP message into a protected CoAP message using the compact secure message format COSE. The protected CoAP message is sent instead of the unprotected message, and is verified and transformed back to the original message at the receiving end.
               +-----------------------------------+
               |            Application            |
               +-----------------------------------+
               +-----------------------------------+  \
               |  Requests / Responses / Signaling |  |
               |-----------------------------------|  |
               |               OSCORE              |  | CoAP
               |-----------------------------------|  |
               | Messaging Layer / Message Framing |  |
               +-----------------------------------+  /
               +-----------------------------------+
               |          UDP / TCP / ...          |
               +-----------------------------------+

For this, the OSCORE object 21 has to be written as part of the bootstrap script, as well as an object link for the same has to be provided as part of the security object resource 17.

To perform the encryption/decryption, it requires that the client and server establish a shared security context used to process the COSE objects.

The security context is the set of information elements necessary to carry out the cryptographic operations in OSCORE. There are a set of input parameters required to derive the security context which are:

  • AEAD Algorithm: The COSE AEAD algorithm to use for encryption.
  • HKDF Algorithm: An HMAC-based key derivation function used to derive the Sender Key, Recipient Key, and Common IV.
  • Master Secret: Variable length, random byte string used to derive AEAD keys and Common IV.
  • Master Salt: Optional variable-length byte string containing the salt used to derive AEAD keys and Common IV.
  • ID Context: Optional variable-length byte string providing additional information to identify the Common Context and to derive AEAD keys and Common IV.
  • Sender ID: Byte string used to identify the Sender Context, to derive AEAD keys and Common IV, and to contribute to the uniqueness of AEAD nonces. Maximum length is determined by the AEAD Algorithm.
  • Recipient ID: Byte string used to identify the Recipient Context, to derive AEAD keys and Common IV, and to contribute to the uniqueness of AEAD nonces. Maximum length is determined by the AEAD Algorithm.
  • Replay Window (Server only): The replay window used to verify requests received.

The above parameters are provided as part of the bootstrap script, so that the context is formed at the client-end and server-end at the time of the bootstrap. So once the device is bootstrapped with OSCORE, the registration request is sent with OSCORE protection.

As OSCORE is an optional parameter, in case the client does not want to use OSCORE, it can set the flag to false as part of the registration update.

Sample OSCORE script

var pskId = client.getPskId();
var psk = client.generatePsk();
var reguri = client.getRegistrationServerUri();
var endpoint = client.getEndpoint();
var masterSecret = "fhfojfjlflslfdefrrevgv";
var clientType = new Boolean(false);
var aesAlgo = 10;
var kdfAlgo = -10;
var replay_size = 1;
var sender_id ="100";
var recipient_id = "200";
var master_salt = "hfoewfe";
var contextId = "10";

var oscorePayload = "{\"e\":[{\"n\":\"0\",\"sv\":\"" + masterSecret + "\"},{\"n\":\"1\",\"sv\":\"100\"}, {\"n\":\"2\",\"sv\":\"200\"}, {\"n\":\"3\",\"v\":10}, {\"n\":\"4\",\"v\":-10}, {\"n\":\"5\",\"sv\":\"" + master_salt + "\"}]}";
var response = lwm2m.write('/21/0', oscorePayload);
client.createOscoreObject(endpoint, masterSecret, clientType, aesAlgo, kdfAlgo, replay_size, sender_id, recipient_id, master_salt, contextId);
var jsonRegSec = "{\"e\":[{\"n\":\"0\",\"sv\":\"" + reguri + "\"},{\"n\":\"1\",\"bv\":false},{\"n\":\"2\",\"v\":0},{\"n\":\"3\",\"sv\":\"" + pskId + "\"},{\"n\":\"5\",\"sv\":\""+ psk + "\"},{\"n\":\"10\",\"v\":1},{\"n\":\"17\",\"sv\":\"21:0\"}]}";
var jsonRegSrv = "{\"e\":[{\"n\":\"0\",\"v\":1},{\"n\":\"1\",\"v\":60},{\"n\":\"2\",\"v\":1},{\"n\":\"3\",\"v\":1000},{\"n\":\"5\",\"v\":84600},{\"n\":\"6\",\"bv\":true},{\"n\":\"7\",\"sv\":\"UQ\"}]}";

lwm2m.write('/0/1', jsonRegSec);
lwm2m.write('/1/1', jsonRegSrv);

client.setCredentials(pskId, psk);

output.set("responseCode", response.code);
output.set("responseStatus", response.status);

lwm2m.finished();

Limitation

For now, the supported Hash based Message Authentication Code (HMAC) algorithms are:
  • HKDF_HMAC_SHA_256
  • HKDF_HMAC_SHA_512