CC2538DK board and encryption in the "default" example

Hi all,

We've got a project where we're considering using the RIOT-OS microkernel in a 6LoWPAN product and have a desire to use Link-Layer encryption. Thus, I'm experimenting with a couple of boards to see if I can get this working.

I noticed discussion of various CFLAGS needed. The changes I've made:

diff --git a/examples/default/Makefile b/examples/default/Makefile index 2d2a457..4fefd8c 100644 --- a/examples/default/Makefile +++ b/examples/default/Makefile @@ -23,6 +23,7 @@ RIOTBASE ?= $(CURDIR)/../.. # which is not needed in a production environment but helps in the # development process: CFLAGS += -DDEVELHELP +CFLAGS += -DCRYPTO_AES

# Change this to 0 show compiler invocation lines by default: QUIET ?= 1

So that by rights, should turn on AES.

I managed to get the code compiled easy enough and am able to flash it via the JTAG interface (have to use TI's Uniflash tool for that, openocd doesn't seem to support it). The boards start just fine and I'm able to send clear-text data from one to the other.

Great. Now to turn on link-layer encryption. I see there are some options there:

ifconfig help

ifconfig help

usage: ifconfig [<if_id>] usage: ifconfig <if_id> set <key> <value>       Sets an hardware specific specific value       <key> may be one of the following        * "addr" - sets (short) address        * "addr_long" - sets long address        * "addr_short" - alias for "addr"        * "channel" - sets the frequency channel        * "chan" - alias for "channel"        * "csma_retries" - set max. number of channel access attempts        * "cca_threshold" - set ED threshold during CCA in dBm        * "nid" - sets the network identifier (or the PAN ID)        * "page" - set the channel page (IEEE 802.15.4)        * "pan" - alias for "nid"        * "pan_id" - alias for "nid"        * "power" - TX power in dBm        * "retrans" - max. number of retransmissions        * "src_len" - sets the source address length in byte        * "state" - set the device state        * "encrypt" - set the encryption on-off        * "key" - set the encryption key in hexadecimal format

usage: ifconfig <if_id> mtu <n> usage: ifconfig <if_id> [-]{promisc|autoack|ack_req|csma|autocca|cca_threshold|preload|iphc|rtr_adv} usage: ifconfig <if_id> add [anycast|multicast|unicast] <ipv6_addr>[/prefix_len] usage: ifconfig <if_id> del <ipv6_addr>

Right, lets try turn it on:

ifconfig 4 set key 0123456789abcdef0123456789abcdef

ifconfig 4 set key 0123456789abcdef0123456789abcdef

Notice: setting 128 bit key.error: unable to set encryption key

ifconfig 4 set encrypt on

ifconfig 4 set encrypt on

error: unable to set encryption

Now I'm aware that the CC2538 is alleged to have "basic" support, am I getting this message because link-layer encryption is one of the missing pieces, or is there something I have missed?

Now I'm aware that the CC2538 is alleged to have "basic" support, am I getting this message because link-layer encryption is one of the missing pieces, or is there something I have missed?

Okay, I've just tried pulling the latest git HEAD, and re-building, still get the same thing:

main(): This is RIOT! (Version: 2017.04-devel-1063-gfb041-rikishi)

Welcome to RIOT!

ifconfig 4 set key 0123456789abcdef0123456789abcdef

ifconfig 4 set key 0123456789abcdef0123456789abcdef

Notice: setting 128 bit key.error: unable to set encryption key

ifconfig 4 set encrypt on

ifconfig 4 set encrypt on

error: unable to set encryption

Last commit is:

commit fb0412097bd5e2fd5421e98a2670a0496a36ea5c Merge: 9ab62b9 11d2677 Author: Alexandre Abadie <alexandre.abadie@inria.fr> Date: Thu May 18 18:01:33 2017 +0200

    Merge pull request #7075 from haukepetersen/fix_minibit_programmerflashtoolvarname          boards: s/FLASHTOOL/PROGRAMMER/

I am using the ARM GNU GCC toolchain, 6-2017-q1-update:

$ arm-none-eabi-gcc --version arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q1-update) 6.3.1 20170215 (release) [ARM/embedded-6-branch revision 245512] Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Host here is Gentoo Linux. If there is something I've neglected to supply here, please tell me… I don't expect you all to be mind readers, but I am not one myself.

About the only clue I seem to have is in sys/shell/commands/sc_netif.c there's this code (lines 869-874):

    else if (strcmp("encrypt", key) == 0) {         return _netif_set_encrypt(dev, NETOPT_ENCRYPTION, value);     }     else if (strcmp("key", key) == 0) {         return _netif_set_encrypt_key(dev, NETOPT_ENCRYPTION_KEY, value);     }

The only reference I see to this is here:

$ grep -Rl NETOPT_ENCRYPTION * drivers/xbee/xbee.c sys/include/net/netopt.h sys/net/crosslayer/netopt/netopt.c sys/shell/commands/sc_netif.c

Am I to understand then by this that IEEE 802.15.4 link-layer encryption is only supported on XBee hardware?

Regards,

Okay, further digging. I actually downloaded the IEEE 802.15.4-2015 spec. Section 9 covers security and Annex C gives some worked examples.

In the frame header within the Frame Control Field byte, there is a single bit, Security Enabled, that decides whether there is security involved. Then there's the auxiliary security header.

The first byte in the ASH is the ASH control field, which contains sub-fields for:

- 3 bits: Security Level which defines how the frame is authenticated and encrypted.   Bit 2 turns encryption on/off   Bits 1 & 0 specify the authentication type:     0 = no authentication     1 = MIC 32     2 = MIC 64     3 = MIC 128   Mode 100b (encryption without authentication) is "deprecated"   in the 802.15.4-2015 standard and is marked as "reserved". - 2 bits: Key ID mode   0 = Implicit: there is no key ID   1 = Key ID stores just the key index (1 byte)   2 = Key ID stores 4-byte key source and 1-byte key index   3 = Key ID stores 8-byte key source and 1-byte key index - and some other control fields.

I see no reference to the above anywhere in the RIOT-OS sources.

Given the XBee seems to just have two commands that map directly to those two functions above, I would guess they use implicit mode (so Key ID mode = 0). *Clearly* they use one of the encrypted key modes, so 4, 5, 6 or 7 or else it'd be blatant false advertising.

In the interests of being compatible with this implementation of IEEE 802.15.4, and to minimise the changes needed to RIOT-OS, it'd be worth looking at adding some code that does frame payload encryption and can optionally take a third parameter that chooses the authentication mode.

This would in theory allow interoperability with such devices. It does look though that the features will need to be *added*, it isn't possible with RIOT-OS out-of-the-box.

Sadly, in the interests of expediency with my project, it does look like I need to look elsewhere.