Whole-stack secure CoAP operations and deployment story

For me to promote RIOT with CoAP on 6LoWPAN or IPSP as a full IoT solution that you can start using from your first maker projects and still get production quality IoT (and I don’t think one should go for less), I think that RIOT will need to incorporate a few more technologies, or make them usable out of the box.

I don’t know all the stepping stones on the road, and the requirements are in flux too, but in the “endeavours” category, that shouldn’t stop things.

Several components here involve trust anchors. When building the first networked hello world (and yes, I firmly believe that a networked hello world should already have all security in place), and out of the box, that can be keys managed in the local RIOT tree (as SUIT does now); going from hello world to production, these may move further out to other trusted infrastructure.

Right now, components are:

  • Roll-out: Right now the best we have on link layer encryption is preshared K1 and K2 material of RFC8180, IIUC.

    That’s kind of almost OK-ish security-wise (I’m not placing any elevated trust in L2 security, it’s more a “don’t be an open access point unintentionally” kind of thing), but has a terrible firmware upgrade story (roll out new K1/K2 material to everyone, then update the 6LBR?).

    A better way to do it is presented in RFC9031, with pairwise keys between the network JRC (registrar) and the node. (I have some hopes for an EDHOC version of that, but right now nothing on the radar as EDHOC isn’t ready either; BRSKI is yet another variant).

    As long as we offer a RIOT-based 6LBR, I think that should be able to host the JRC as well.

    When the 6lowpan to join (or a set thereof) is known at build time and hard-coded, pairwise keys would be generated at the build machine, and either distributed live to the JRCs, or installed there with the next firmware upgrade.

  • Firmware upgrades: We have SUIT and riotboot, that should largely be enough.

    (I personally don’t care so much about the local verifiability mcuboot & co give, because usually whoever can alter the firmware can also alter the bootloader; game changes when remote attestation comes into play).

    I think that we should migrate default setups towards being remote updatable. As long as users just do hello-world, it doesn’t (if it does: shouldn’t) hurt to have riotboot in place – but as soon as networking is established, plugging in for upgrades should be optional, and the tutorial experience should reflect that.

  • Communication authentication and encryption: DTLS is in-tree now; OSCORE unfortunately not due to the complexity of multi-transport CoAP.

    Using one of these should become transparent and default when using RIOT, and resources that are not explicitly public services should be locked down for unauthorized access (see next).

  • Authorization model: Any exposed resource, especially those in the examples, should check for authentication.

    A trust relation with the flashing device can be established out of the box. Setting up any more can involve:

    • ACE, delegating decisions to an authorization server (AS). That AS can easily be unconstrained, and even be part of the build infrastructure.

    • EDHOC, which can use certificates (X.509 or CWT) down to a trust root.

    • DTLS X.509 (or CWT, if that ever got followed up on) certificates

    The infrastructure in RIOT or the CoAP libraries should make it straightforward to set up trust relations between servers and clients.

Did I miss any?

(Many technologies mentioned here may also pop up in my summit talk, which is certainly no coincidence)

3 Likes

Some components of this may need an established device configuration storage (which AIU we currently leave to applications). Without that, any new flashing-with-credentials (eg. to join a network) would mean creating a fully new device identity, and that might overwhelm a constrained JRC.

The process of getting credentials into builds will also mean that some of the build infrastructure will need extensions; we can’t flash the same secret onto two different devices, can we?

Thanks for bringing this up. This is also a big issue we face currently in the W3C WoT working group. A lot of smart home deployments just use some cloud middleware in order to provide security. In the industry on the other hand the situation doesn’t look as good. A lot of deployments are not secured at all. At best L1/L2 security. So, I agree, if we provide a full solution, this could be a big selling point for RIOT.

I am not very happy with the trend using some kind of cloud applications in order to have proper security. I think the biggest point for security in local networks at the moment is the out-of-band key sharing mechanism. Quite often that means flashing the key into the firmware and trusting an non transparent entity. I would rather prefer to have a secure element and let the device generate the key itself. So we are currently discussing, if DID could be the missing piece for sharing keys in a proper way. So, I probably would put that on your list as well.

Looking forward to hear your talk.

1 Like

I would like to add:

  • headless operation

For development, the shell is immensely useful. For deployments, not so much. IMO, we need to work on RIOT being usable without shell.

What I think that includes (non-exhaustive):

  • provide seamless network (auto-)configuration for the network (for any network size),
  • some persistent pairing/onboarding solution including security etc. This overlaps with “rollout”.
  • provide a way to get basic runtime/diagnostic information from a device over the network, and for nodes to announce themselves. CoAP-RD? shell commands over CoAP? (wink @chrysn :slight_smile: )
  • (fix pm with shell enabled, or provide a “headless” configuration that is usable)

I had some “headless” deployments in the past, where the node was only accessible via CoAP. It’s just a matter of not adding the shell module, so, to a degree, I think this is already possible quite easy :-).

We have DHCPv6 IA_NA now which is a big step for non-SLAAC deployments. An with the DHCPv6 relay agent this can even be used multi-hop.

Sounds an awful lot like what SLIPMUX is also proposing :wink: I think a good first step into that direction is abstracting the output of shell commands that it can be redirected somewhere else other than STDOUT (i.e. getting rid of printfs and putss in shell_commands. Maybe using turo?

I would rather prefer to have a secure element and let the device generate the key itself.

+1 for local generation; on secure elements I’m not sold. (It’s good to have them as options, but for most applications a security model of “if someone takes over the device, they own it and can long-term impersonate it” can be good enough). At any rate, it’s up to the security model (and not the local implementation) to ensure that the privileges leaked by a compromised device are minimal.

So we are currently discussing, if DID could be the missing piece for sharing keys in a proper way. So, I probably would put that on your list as well.

As far as I understand DIDs (which is not very far), they can serve as expressions of cryptographic properties. Might be an option for exchange of trust, but that doesn’t solve the fundamental bootstrapping problems. (Which are, in one direction: that the device either TOFUs you after you physically reset it, or the device only ever trusts you if you present an out-of-band proof of possession. And in the other direction: Do you trust a device you can’t rebuild the firmware for?).

headless operation

Oh my, this might explain why I’m always rooting so hard for things like IPv6 PD: I never considered that the shell might for some use cases be a means of deployment. (The only ever mutating ifconfig commands I’ve issued were for quickly trying something out before changing it in the firmware).

Headless definitely needs to be a part of the story here. Network autoconfiguration too (gotta look up that IA_NA; I always had SLAAC in my books as the superior solution with DHCPv6 for the few things SLAAC and ND can’t do (yet or because state is involved))

(As for how to use the shell remotely, I’d like to spin that off into a different thread.)

<mod hat>See CoAP remote shell?</mod hat>

1 Like

There are so many things here which I badly want to thumbs up, that I don’t really even know where to start.

I agree completely with “hello world” needs to come with security batteries included. That means provisioning, onboarding, configuration, and debugging. There are many missing bits, but perhaps the most pressing missing bits are opinion: flexibility here is not a good thing because it leads a lot to confusion. One reason why I’m targeting my work for both FreeRTOS and RIOT-OS is because I really think that we need to get the security into the Adafruit target audience. Like Napster, the next IoT killer device will not come from someone who knows who the IETF is. {Napster guys didn’t know about network byte order, for instance}

RFC9031 is a good start. It’s taken too long to get to RFC because of dependency issues at the RFC-editor level. The K1/K2 key mechanism is appropriate for a vertical IoT operator: e.g., company X that makes some custom devices in house and then deploys them in their own infrastructure. To a very limited extent it supports larger customers of who direct order from a vendor… This is because of the need securely provision and transfer the symmetric keys to the customer.

So, this brings up to me, the provisioning aspect. If the customer is willing to one-touch the device with a cable, then the symmetric keys can be provisioned at that time. End-operator/customers who are buying bare hardware and doing their own flashing are in the position to that already. Most of the experimenters who use RIOT-OS are already in that position, which is why the RFC9031 model works well. And as you say, an EDHOC version of this would be nice, and I tried to provide for that upgrade in RFC9031.

The current BRSKI version of RFC9031 is draft-ietf-anima-constrained-voucher and draft-ietf-ace-est-coaps, and alas, it uses DTLS and it’s much fatter on the wire with many more round trips than RFC9031. Still, I hope to finish that code for ESP32 this year. (It’s partially in Rust)

I am trying (through medication induced brain fog) to do some practical design on flash layout for ESP32 such that we can provision IDevID into them in a way that is not erased by updates of firmware. The IDevID provisioning process could occur before final firmware, or after final firmware.

The hardest part, in my opinion, about getting RPL/RFC6550 to work is the debugging aspect. We need a telemetry, and yeah, Shell over CoAP would probably help a lot. We effectively need a proxy version of it, such that one can reach out to the device you have a route to, and then, using it, use IPv6 LL to talk to the devices adjacent which are not, for reasons not yet known, inquire about their RPL status.

Having an 802.15.4 USB dongle that can speak to your smartphone, or some RIOT-OS device with an LCD screen and a SPEAKER such that one could, literally, use the sonar mode of ping, would also help people debug stuff. This needs to be a standard debug equipment the same way that RJ45 cable testers exist. https://www.amazon.ca/iMBAPrice-Network-Cable-Tester-Phone/dp/B01M63EMBQ/ref=sr_1_6?crid=ED8HDYNQRINZ&dchild=1&keywords=RJ45+cable+tester&qid=1630267293&sprefix=35ft+%2Caps%2C177&sr=8-6

I had a stack of CHIP CHIP (computer) - Wikipedia computers, including: CHIP (computer) - Wikipedia that I had added a 802.15.4 to, which I felt would make an ideal device, but CHIP is dead…

What I see is that we need to improve our flashing tools to make them able to deal with deploying (and updating) firmware with IDevID creation. I don’t quite know how this will look in the end. I do envision a situation with some kind of 8-port USB hub attached to something slightly more physically durable than a RPI {the small computers tend to fall off the table, because the cables are too heavy…}. But, there are companies that do provisioning of devices in the factory today, and some interaction with them would be good.

I’d like to get rid of SLIP and replace with PPP. The small amount of IPCP/IP6CP state machine is easier to code/understand than the hacks that SLIP deals with.

I’ve been down this road with contiki, but I didn’t make much progress. SLIP is not in the kernel of most desktops, and we have this awful layer of stupid, often hard to port, code in between doing tunnels, etc.

We can readily do the PPPmux by easy modifications to pppd. We get address assignment sensibly. For many environments, putting the RPL root on a Linux host makes sense. While 802.15.4 radios are available in a variety of forms for Linux (USB, I2C, …), the problem is that it’s hard to get the Linux kernel to respond to the required timing to do 6TISCH properly… so having a single device acting as a bridge works best in my opinion. The INRIA/Openmote guys did a “shield” for RPI that held an openmote. This also solves the “sonar” debugger that I mentioned elsewhere in the thread.

Are there any concrete proposals on how to use that with the IETF stack? The Cable is usually USB, and getting network as we use it in there is hard to do portably. Plus half of today’s provisioning devices (cell phones) don’t have this kind of cable port any more.

So I was thinking more along the lines of untrusted network (given permission to use power by local button press) and then some unidirectional confirmation of identity – EAP-NOOB has some ideas there with cameras reading out blinking LEDs (or, as you later mention, beep the speaker), but I don’t think they provide the full solution, and TBH I’m unsure I want EAP in a minimal setup.

each out to the device you have a route to, and then, using it, use IPv6 LL to talk to the devices adjacent which are not, for reasons not yet known, inquire about their RPL status

That should really be straightforward: From CoJP we’ll already have stateless proxies, and’ll just need them to understand authorized access and other addresses than the single .arpa one.

Come to think of it, GET to [ff02::fd] with Uri-Host: fe80::10:ca1 should just do, with follow-ups sent to whoever responded :slight_smile: (OK sure it’s not that trivial b/c group security…).

802.15.4 USB dongle that can speak to your smartphone

Yeah, that could be a default application: a 6LBR build that hooks into any network provided by the USB host, and in parallel (TBD) opens up … maybe a CoAP-over-BLE proxy? to configure it, so you can either plug it into the PC or just an outlet, CoAP in from the browser … tell it (or maybe default) to announce a ULA root, and go from there…

8-port USB hub attached to something

Well any small series things are done one-by-one anyway, and any kind of series production runs through factory tests in which the one single flashing can be done. What would be done with an octopus?

Are there any concrete proposals on how to use that with the IETF stack? The Cable is usually USB, and getting network as we use it in there is hard to do portably. Plus half of today’s provisioning devices (cell phones) don’t have this kind of cable port any more.

iPhone 12 still has a USB/Lighting port. Are there Android phones that lack USB? I’ve never seen one. I can see how people might want to get rid of it for water resistance.

That’s why I suggested that maybe the entire IPv6 stack has to go into the application, because getting the OS to talk to the device may be difficult.

> So I was thinking more along the lines of untrusted network (given
> permission to use power by local button press) and then some
> unidirectional confirmation of identity -- EAP-NOOB has some ideas
> there with cameras reading out blinking LEDs (or, as you later mention,
> beep the speaker), but I don't think they provide the full solution,
> and TBH I'm unsure I want EAP in a minimal setup.

The NOOB part is good, it’s the EAP part that is hard to arrange.

>> each out to the device you have a route to, and then, using it, use
>> IPv6 LL to talk to the devices adjacent which are not, for reasons not
>> yet known, inquire about their RPL status

> That should really be straightforward: From CoJP we'll already have
> stateless proxies, and'll just need them to understand authorized
> access and other addresses than the single .arpa one.

I hadn’t thought to use the stateless proxy in the other direction. It’s a good idea.

> Come to think of it, GET to \[ff02::fd] with Uri-Host: fe80::10:ca1
> should just do, with follow-ups sent to whoever responded :-) (OK sure
> it's not *that* trivial b/c group security...).

:slight_smile:

>> 802.15.4 USB dongle that can speak to your smartphone

> Yeah, that could be a default application: a 6LBR build that hooks into
> any network provided by the USB host, and in parallel (TBD) opens up
> ... maybe a CoAP-over-BLE proxy? to configure it, so you can either
> plug it into the PC or just an outlet, CoAP in from the browser
> ... tell it (or maybe default) to announce a ULA root, and go from
> there...

I’m confused by this. Is this 6LBR talking to the network, or is it being configured?

>> 8-port USB hub attached to something

> Well any small series things are done one-by-one anyway, and any kind
> of series production runs through factory tests in which the one single
> flashing can be done. What would be done with an octopus?

It’s about the initial flash of the devices. Doing more than one means that one can overlap the recognition/download/provisioning/validation with the unpacking+repacking of the devices.

Yeah, but who has OTG cables around? But granted, they could be shipped, and become more commonplace.

That’s why I suggested that maybe the entire IPv6 stack has to go into the application, because getting the OS to talk to the device may be difficult.

Comparing to the Bluetooth situation (where, too, there is defined networking but getting the OS to talk to it is … meh), that’d be the Fitbit Golden Gate approach. The alternative is to have specific CoAP-over-X specifications. The pros and cons need weighing case-by-case (in BLE even 6lo-ish headers would be high overhead); once “IPv6 in the application stack” is established as something non-scary, IP-over-application-layer-USB might be a good option.

The NOOB part is good, it’s the EAP part that is hard to arrange.

Yes. There is coap-eap, but I’m not convinced that NOOB warrants pulling the whole EAP in.

[a default application]

I’m confused by this. Is this 6LBR talking to the network, or is it being configured?

It’s not fully thought through; I’m envisioning this as a generic tool that does have one trust relation (to the owner’s end user device). It acts according to its surroundings (if you plug it in to a PC that brings the netif up, you obviously want to route over it); it can be used to act as anything from a network adapter (via USB to bluetooth) up to a 6LBR that can be left in the system.

This’d go well especially with RIOT’s board flexibility: Whichever netifs are there can be used. Doesn’t matter whether it’s USB networking or whether ther’s an Ethernet adapter on it. Got Bluetooth? Fine, advertise CoAP-over-BLE (with a proxy to get to the netifs) or Golden Gate. Got DOSE or 6loBAC? Should probably work too.

I also wanted to take this direction 5 years ago. In fact, [Link layer] GNRC PPP by jia200x · Pull Request #5470 · RIOT-OS/RIOT · GitHub is still there (among the cobwebs). It would still be possible though to bring it back to life

There’s also no IEEE 802.15.4 stack. RIOT only deals with (secure) IEEE 802.15.4 frames, but there’s no way to do commissioning/joining, discovery, etc. As it is, it’s hard to deploy a secure network with many IEEE 802.15.4 nodes and roles (coordinators, sleepy end devices, etc).

I started some time ago writing a IEEE 802.15.4 MAC but quickly abandoned it after working with OpenDSME, which provides both Channel Frequency Time Slotted communication as well as standard CSMA-CA. I’m already porting it to RIOT and plan to integrate it to GNRC and the other network stacks. I plan to open a PR as soon as there’s something usable.

1 Like

Only issue AFAIK is that there is no official IPv6-over-X-spec for that, right?

I might be missing some context for OpenDSME, but isn’t the path towards a fuller IEEE 802.15.4 stack to integrate OpenWSN better up to the point where RIOT does full 6TiSCH?

1 Like

There’s yet no official spec for IPv6 over DSME slots, same as there’s no spec for IPv6 over regular IEEE 802.15.4 GTS slots. However, it’s still possible to run 6LowPAN on top of DSME during CAP, analogue to Beacon-enabled IEEE 802.15.4. We would still get all the benefits (Discovery, association, etc).

I might be missing some context for OpenDSME, but isn’t the path towards a fuller IEEE 802.15.4 stack to integrate OpenWSN better up to the point where RIOT does full 6TiSCH?

TSCH is only one of the operation modes of IEEE 802.15.4 2012e. The same for DSME (in fact introduced together with TSCH). Both operation modes benefit of a time slotted channel hopping pattern (although DSME also supports simultaneous CAP access, let’s say, CSMA-CA).

It’s of course desirable to have full 6TiSCH support for RIOT, but I wouldn’t rule out other IEEE 802.15.4 operation modes. Not every IEEE 802.15.4 deployment requires TSCH or DSME and in fact, standard IEEE 802.15.4 can easily support 10 years of battery life with Sleepy End Device roles and provide security. E.g Thread nodes run non-beacon IEEE 802.15.4.

Also, as it is, it’s hard to run OpenWSN for many deployments because half of the RPL implementation runs on a Linux environment (IIRC it was the OpenWSN Visualizer). I did some work a couple of years ago to isolate the TSCH MAC layer, but at that time the layers were way too messy to have a clean integration. I hope this changes at some point.

Also, as it is, it’s hard to run OpenWSN for many deployments because half of the RPL implementation runs on a Linux environment (IIRC it was the OpenWSN Visualizer). I did some work a couple of years ago to isolate the TSCH MAC layer, but at that time the layers were way too messy to have a clean integration. I hope this changes at some point.

+1, I retook @jia200x a bit more recently in this poc, but it’s already badly out of sync. In any case, OpenWSN is not being developed very actively lately either on our side or on theirs, @miri64 showed some interest in this offline a while ago but I’m not sure she still is, on my side I’m not working on this pkg anymore, and probably won’t be doing so anytime soon.

My interest is more into the same direction I understood @chrysn’s proposal: Use only the MAC layer of OpenWSN. Due to timing constraints I won’t really be able to work on that either. But maybe with the 802.15.4 HAL this turns out to be easier and less time-intensive.

1 Like