8.4. Custom (D)TLS layers
8.4.1. Introduction
avs_crypto
and avs_net
include full-featured, ready-to-use integrations
with the TLS and DTLS protocols, using either
OpenSSL or Mbed TLS,
as well as a basic implementation that supports the PSK mode only, using
tinydtls.
These integrations use the avs_net
socket APIs underneath, so if the socket
layer is implemented properly (either using the default implementation or by the
user, as described in the previous chapter), all the
necessary security features will work properly.
However, in modern embedded development, it is sometimes desirable to offload all TLS processing - for example, a cellular modem may provide integrated TLS implementation, controlled e.g. via AT commands. For this reason, a user-provided implementation of TLS and DTLS “sockets” may be provided instead.
This chapter is a guide for implementing all the features used by Anjay for TLS communication. The examples recreate an integration with OpenSSL 1.1.1, simplified compared to the default one, but they are also intended to provide a reference for integrating with any other TLS API.
8.4.2. Theory of operation
TLS and DTLS integration in Anjay is based on the same avs_net
socket APIs
as the basic unencrypted TCP and UDP sockets, with a couple of minor
adjustments:
The configuration structure passed when creating the socket is different (
avs_net_ssl_configuration_t
instead ofavs_net_socket_configuration_t
), and contains the security configuration, including keys and certificates used for communication.The
connect
andaccept
(if supported) operations are expected to perform the TLS/DTLS handshake.Dedicated option keys for the
get_opt
/set_opt
operations control additional TLS/DTLS features:AVS_NET_SOCKET_OPT_SESSION_RESUMED
may be queried to check whether the handshake resulted in a new session, or a resumption of an existing one - this is used by Anjay to check whether a Register operation is necessaryAVS_NET_SOCKET_OPT_DANE_TLSA_ARRAY
may be used to specify additional peer certificate data for validation according to the DANE mechanism - LwM2M 1.1 specifies an almost identical flow for verifying the server certificate
The
AVS_NET_SOCKET_OPT_INNER_MTU
option shall take the DTLS header overhead into account.Additional
decorate
operation may be provided to support securing communication over a pre-existing unencrypted socket - this is currently used by the SMS commercial feature of Anjay to provide security for the SMS transport.
8.4.3. List of functions to implement
Support for custom TLS layer needs to be enabled in the compile-time configuration first:
When using CMake, use
-DDTLS_BACKEND=custom
when configuring Anjay.When using another build system, enable
AVS_COMMONS_WITH_CUSTOM_TLS
and disableAVS_COMMONS_WITH_MBEDTLS
,AVS_COMMONS_WITH_OPENSSL
andAVS_COMMONS_WITH_TINYDTLS
inavs_commons_config.h
.Usually you should also disable
AVS_COMMONS_WITH_AVS_CRYPTO_ADVANCED_FEATURES
inavs_commons_config.h
. You will most likely want to disable features related to OSCORE and EST if you are using a version of Anjay that includes these commercial features.If you need OSCORE or EST, you will need to implement advanced cryptographic functions related to AEAD, HKDF and processing various crypto-related file formats, that are normally provided by OpenSSL or Mbed TLS. This is not thoroughly supported and not covered by this documentation at the moment.
Implementations of the following functions will need to be provided:
_avs_net_create_dtls_socket
- a function with the following signature:avs_error_t _avs_net_create_dtls_socket(avs_net_socket_t **socket, const void *socket_configuration);
socket_configuration
argument is a pointer toconst avs_net_ssl_configuration_t
struct cast tovoid *
.Otherwise the function has similar semantics and requirements to the
_avs_net_create_udp_socket
function described in Networking API._avs_net_create_ssl_socket
- only required if thefw_update
module should support HTTPS transfers, or if support for CoAP over TCP is desired. Otherwise, it can be safely implemented asreturn avs_errno(AVS_ENOTSUP);
.avs_error_t _avs_net_create_ssl_socket(avs_net_socket_t **socket, const void *socket_configuration);
socket_configuration
argument is a pointer toconst avs_net_ssl_configuration_t
struct cast tovoid *
.Otherwise the function has similar semantics and requirements to the
_avs_net_create_tcp_socket
function described in Networking API._avs_net_initialize_global_ssl_state
- a function with the following signature:avs_error_t _avs_net_initialize_global_ssl_state(void);
The function should return
AVS_OK
on success and an error code on error. It should initialize any global state that needs to be kept by the TLS implementation, and initialize external libraries if necessary. If there is no such global state or it is initialized elsewhere, it is safe to implement this function as a no-op (return AVS_OK;
)._avs_net_cleanup_global_ssl_state
- a function with the following signature:void _avs_net_cleanup_global_ssl_state(void);
The function should clean up any global state that is kept by the TLS implementation. If there is no such global state or it is managed elsewhere, it is safe to implement this function as a no-op.