10.8. OSCORE
10.8.1. General description
Object Security for Constrained RESTful Environments (OSCORE, RFC 8613) is a security protocol protecting CoAP requests and responses using CBOR Object Signing and Encryption (COSE, RFC 8152). It provides a high standard communication security while remaining lightweight. Unlike DTLS and TLS, OSCORE is designed for resource-constrained devices. Encrypting only the message payload (and parts of the header) on the application layer allows to achieve:
Less power consumption due to less data being processed by time-consuming cryptographic algorithms and shorter messages being transmitted,
Smaller memory utilization by the software protocol stack,
Shorter computing time that enhances device responsiveness,
End-to-end security without data being unencrypted and re-encrypted by the network gateways,
Flexibility in transport protocols selection since OSCORE works with UDP, TCP, SMS and NIDD.
OSCORE encryption covers message payload and Request/Response Code. Most CoAP header fields (i.e. the message fields in the fixed 4-byte header) are required to be read and/or changed by CoAP proxies, so, in general, they can not be protected end-to-end if proxy support is required. Nevertheless, there is no hop-by-hop information encryption (which takes place in (D)TLS proxies) and only the pre-authorized endpoint (either target device or LwM2M Server) is able to decipher the message entirely. Even if the network becomes compromised, the data remains secure.
In solutions where the security is top-priority, OSCORE can be used together with
(D)TLS to attain double encryption realized on different protocol stack layers.
OSCORE commercial feature in Anjay comes mostly as an extension to avs_coap
submodule and as LwM2M OSCORE Object implementation (OSCORE module). It gives an
alternative to the security provided by the Transport Layer Protocols (TLS/DTLS)
or enhances it by providing additional encryption on the Application Layer and by
covering additional message frame fields.
Keying material stored in the OSCORE Object can only be set in the Bootstrap phase, that is, during a Factory Bootstrap, by an LwM2M Bootstrap-Server or by a Bootstrapper and SIM bootstrap.
10.8.2. Technical documentation
10.8.2.1. Enabling OSCORE support
If support for OSCORE is available in your version of Anjay, it can be enabled at
compile-time by enabling the WITH_AVS_COAP_OSCORE
macro in the
avs_coap_config.h
file or, if using CMake, by enabling the corresponding
WITH_COAP_OSCORE
CMake option.
There is also a possibility to use CoAP as defined in draft-ietf-core-object-security-08 (which is
referenced in the LwM2M 1.1 Technical Specifications). There is a minor difference
between the implementation of the protocol in this draft and the final version,
so if you want to be fully compliant with the LwM2M 1.1 standard, you might want to
use it. To achieve that, enable the WITH_AVS_COAP_OSCORE_DRAFT_8
macro in the
avs_coap_config.h
file or, if using CMake, enable the corresponding
WITH_AVS_COAP_OSCORE_DRAFT_8
CMake option.
Anjay provides a pre-implemented OSCORE Object module. You can enable it at compile-time
by enabling ANJAY_WITH_MODULE_OSCORE
macro in the anjay_config.h
file or,
if using CMake, by enabling the corresponding WITH_MODULE_oscore
CMake option.
It is not mandatory to use Anjay’s OSCORE Object implementation. However, this article
and example will focus on using it.
Note
To provide your own object implementation, you need to prepare handler functions similarly to Custom LwM2M objects.
10.8.2.2. Encryption and decryption backend
OSCORE extension in avs_coap
module does not implement any encryption algorithms.
It relies on a cryptographic library used as a (D)TLS backend selected via CMake option
at the compile time.
Important
Important
If a custom (D)TLS backend library is used, make sure it supports AEAD and HMAC Algorithms mentioned above.
The cryptographic algorithms are used to encrypt the CoAP message payload. CoAP message code is protected by writing the original value into an encrypted COSE object and setting a valid but not relevant code into the CoAP header.
10.8.2.3. Installing and configuring OSCORE Object
If OSCORE is enabled and used, OSCORE Object Instance that holds keying parameters
applied to communication with a specific server has to be linked in the corresponding
Security Object Instance. The object link is realized by a proper setting
anjay_security_instance_t.oscore_iid
field during Security Object Instance creation.
anjay_oscore_instance_t oscore_instance = {
.master_secret = "Ma$T3Rs3CR3t",
.master_salt = "Ma$T3Rs4LT",
.sender_id = "15",
.recipient_id = "25"
};
anjay_iid_t oscore_instance_id = ANJAY_ID_INVALID;
if (anjay_oscore_add_instance(anjay, &oscore_instance,
&oscore_instance_id)) {
return -1;
}
anjay_security_instance_t security_instance = {
.ssid = 1,
.server_uri = "coap://eu.iot.avsystem.cloud:5683",
.security_mode = ANJAY_SECURITY_NOSEC,
.oscore_iid = &oscore_instance_id
};
anjay_iid_t security_instance_id = ANJAY_ID_INVALID;
if (anjay_security_object_add_instance(anjay, &security_instance,
&security_instance_id)) {
return -1;
}
10.8.2.4. Persisting OSCORE state
The OSCORE state can be persisted and restored similarly to other Anjay’s pre-implemented objects. Let’s reuse and extend Persistence support tutorial to provide an example.
Note
When calling anjay_security_object_restore()
, a check is performed
if a linked OSCORE Object Instance ID is a valid entry in the Data Model.
Therefore the OSCORE Object has to be restored first.
if (avs_is_err(anjay_oscore_object_persist(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not persist OSCORE Object");
goto finish;
}
if (avs_is_err(anjay_security_object_persist(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not persist Security Object");
goto finish;
}
if (avs_is_err(anjay_server_object_persist(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not persist Server Object");
goto finish;
}
if (avs_is_err(anjay_oscore_object_restore(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not restore OSCORE Object");
goto finish;
}
if (avs_is_err(anjay_security_object_restore(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not restore Security Object");
goto finish;
}
if (avs_is_err(anjay_server_object_restore(anjay, file_stream))) {
avs_log(tutorial, ERROR, "Could not restore Server Object");
goto finish;
}
Note
The full code for the following example can be found in the
examples/commercial-features/CF-OSCORE
directory in Anjay sources. Note that
to compile and run it, you need to have access to a commercial version of
Anjay that includes the OSCORE feature.
Important
OSCORE support in Coiote DM LwM2M Server is currently a work in progress. Provided example based on connection with EU Cloud Coiote DM instance is only a demonstration that will not yet work out of the box.