I am designing an IoT system based on Silicon Labs EFR32 MCUs with hardware accelerated support for SHA-256, AES-128-CBC and ECC (m255) computation. The system will communicate over a proprietary radio communication protocol in an untrusted environment, and both flash and ram footprint and the number of exchanged messages is vital to be kept low.

The DTLS functionality described in https://www.rfc-editor.org/rfc/rfc6347 is massively overweight for my application, which has the following features and needs:

  • micro-controller to micro-controller communication using proprietary radio (not LoRa, Zigbee or similar) in a hostile environment, radio is slow and costly in terms of battery life
  • non-blocking SW model with callbacks and timer hooks
  • physical channel: unreliable delivery, active attacker/listener, reordering and replay; similar to UDP.
  • client/server model with client verification similar to HelloVerifyRequest/ClientHello in DTLS to avoid DOS attacks on the other radio devices
  • exclusive use of TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 (m255) known at production time
  • known maximum MTU size for radio channel
  • pre-installed public/private key-pair in both peers in compact binary form (no ASN.1 or X.509 code), identical to both peers having each other's certificates without negotiation, with eternal validity
  • no IP, not be reachable online, communication between two micro-controllers that use a proprietary protocol for communication
  • pause/start the tunnel without it closing when no traffic comes in the paused state. Shouldn't renegotiate when in paused state, but keep using the session keys until either age-limit or data-limit hit. Needs to be possible to wake up by an unencrypted agent
  • one bi-directional secure, mutually authenticated application-layer traffic tunnel using ECDHE/ECDSA, no port-numbers needed.
  • client knows unique serial number of server, server knows only it's own serial number
  • keep-alive signaling; successful payload message transfer should be seen as keep-alive equivalent to reduce message volume
  • renegotiate session keys when either age-limit or data-limit hit
  • client knows the unique serial number of the server, needs to do server device discovery among potentially many devices both after and before session establishment. That a device has been seen is not considered secret information

When I look at what already finished functionality mbed DTLS has, it looks like I can't get it to not exchange certificates between peers or negotiate the cipher suite (despite knowing the only valid setting in production). I want to cut out all the unnecessary, already known flights of messages to reduce both setup time and battery consumption.

I want to have two interfaces towards my L1 radio layer where only a rough selection of incoming traffic has been performed: send() and receive(), which should be asynchronous and non-blocking.

The code and RAM size for ASN.1 decoding and parsing is massive for my application, so I want only the 256+256 bits of the public/private key-pair, and the known unique serial number of the peer to be stored instead of doing ASN.1 and X.509 parsing.

Is there any way to obtain the features that I want, or do I need to write this code myself, implementing heartbeat signaling, session establishment/renegotiation, application layer tunnel traffic encryption/authentication/decryption, etc based on mbed tls DTLS primitive functions?

Is there any known example of a similar scenario that I can look at? Any list of good advices to follow in order to avoid creating exploitable weaknesses in my implementation?

Thankful for any helpful input /Daniel Nilsson

  • 2
    $\begingroup$ Yes, you could replace the X.509 based authentication, although having parsed X.509 certificates on a smart card, I wonder if it is strictly necessary - you could strip down the X.509 parsing; you probably only need specific information from it (hint: look at stream parsing, similar to what is used for XML). You could also look into authentication with a pre-shared key . Or use a more lightweight transport protocol, of course. $\endgroup$
    – Maarten Bodewes
    Mar 9 '18 at 12:38
  • 2
    $\begingroup$ You may also note that there is a standard to use raw public keys in (D)TLS called RFC7250. $\endgroup$
    – SEJPM
    Mar 9 '18 at 12:59
  • $\begingroup$ @SEJPM That single sentence could be an answer I suppose. But with the remark that some kind of trust in the public key(s) must of course be established one way or another. If I remember correctly some kind of statement to that affect is also in the RFC. $\endgroup$
    – Maarten Bodewes
    Mar 9 '18 at 14:37
  • $\begingroup$ @MaartenBodewes Go ahead and post an answer, I may not be able to for a couple of days. $\endgroup$
    – SEJPM
    Mar 10 '18 at 0:31

You can write your own protocol instead of using DTLS. But there's no realistic chance that you'll get it right. Designing a secure protocol is hard, and you should definitely use a proven and tested one rather than roll your own.

You can do DTLS with raw public keys, which would avoid X.509 altogether. This saves a number of things: code size, RAM usage (but not a lot, compared to a self-signed certificate), and handshake message size. You still need two round trips to establish a session using raw public keys. This does have security and deployment drawbacks: you have to distribute all the peers' public keys before you can start communicating, and you have to manage repudiation on your own.

If you find an implementation of it, that is. Mbed TLS doesn't support it, although there's an old pull request for it. Reportedly tinydtls can do it.

Do use session caching and resumption whenever possible. Session resumption removes the cost of public-key cryptography and reduces the number of round trips to start the connection from 2 to 1.

TLS 1.3 will let you establish a session with a single round trip, but DTLS 1.3 isn't ready yet.

In the absence of a usable implementation of DTLS with raw public keys, you may be forced to partially roll your own: use DTLS with pre-shared symmetric keys (this is widely supported by (D)TLS implementations), and use a separate protocol to distribute the symmetric keys. But it would be safer to achieve this by using DTLS to effectively distribute the symmetric keys, and session resumption to avoid doing asymmetric cryptography every time.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.