The usual attack on Sigfox network is related to the “security”. Behind this large concept, for real, the only point is related to the use of clear payload over the air. As a consequence some are extending this to the possible replay after 2048 frames so regarding a standard use of Sigfox is will be about 6 month later…
That said, for real, all of this is just ignorance from these pseudo “security” experts and developer laziness. Don’t beat me for saying that, I’m part of the lazy developer, the only difference is I’m not complaining and I’m aware the solution is in my own hands.
Because, for real, the payload encryption exists as documented in the post I’ve published on May 2017 and detailed on the Feb 2017 technical security paper published by Sigfox or like in this document.
So saying the Sigfox is not proposing payload encryption is wrong and this option is also fixing any 6 months later message replay. It’s like saying WiFi is not secured because you can create an open-network.
So now, let’s see why encryption is not the default option, why a network encryption standard is not the best option and then see how to stop to be a lazy developer and make encryption working.
Why default encryption has not been chosen
Encryption for IoT is not really encryption for web surfing, I mean the personal information transferred over IoT protocol is not exactly the same as on Internet when we are considering LPWA. Here are the reasons:
- The device ID is a kind of random number and can’t be used to find your personal identity as an IP address is. Basically if you don’t publish it, there is no reason to identify you.
- Even Sigfox is actually able to locate a device only with a 1km precision. This makes large possibility before finding you.
- Because most of the data you transmit over Sigfox are not sensitive… like my office temperature is not really a sensitive stuff….
When considering personal attached devices over BLE, I would honestly have a totally different speech.
That said it means there a large area where the data can be considered as sensitive and that’s why the payload encryption is a needed feature, I will never say this differently. “Need” just don’t means “must have”.
So assuming most of devices won’t be sensitive, regarding the target objective to save energy, use small and low cost MCU for getting the best of the LPWA technology, the default setting has been decided to be clear payload transport. Then it’s on your own to decide to encrypt or not.
Why standard encryption is not the best approach
On top of what we’ve previously seen, I would add the following elements to have in mind: let’s consider objects will be on the fields for 5 to 10 years. On the fields these objects have no way or being upgraded with fresh new firmware. What will happen when the encryption selected for all will be broken ? This will become another WiFi WEP history… something broken 10 years ago and still in production in a lot of areas. So my feeling is: “never trust the standard /global encryption for long term security”.
I do not say Sigfox solution is not secure or not to be used, I mean if you do not want to be part of a potential future global security breach, you may think about implementing you own encryption on top of it. If you are a bit paranoid you can use multiple solutions and remotely switch from one to another. You see there is no limit on security development. Security, data protection is a compromise, you decide, regarding data sensitivity, time you have, energy you have and who have an interest against you.
Basically this is something you can read on LoRaWan forum: if encryption is the default for communications, experts recommend to implement your own underlaying encryption method.
Advantage of encryption: they can potentially be cumulative.
Some IoT payload encryption challenges
On IoT network, using encryption with key exchange based on public/private key is not yet something you can imagine. The computation power you have on MCU is really light and the network bi-directional communications are a real issue because of duty-cycle and communication reliability particularly in downlink (whatever the technology is). As a consequence, usually, device and server-side are sharing a secret key. This key is used for encrypting the messages.
To protect your communication, you need to ensure a same message will not be encrypted the same way on every communication otherwise the decryption will be easy as the key determination will be much simpler.
In another end as you can loose many messages, you need to have a sync mechanism in place for managing it. This sync mechanism starts to be complex if you are not able to determine if the received & decrypted frame is valid or not. The sync can be lost and you may have trouble ! This can be managed by some extra bits you can or can’t have.
You can also use the same key on every transmissions (so the same clear payload will gives the same encrypted payload) or making a similar way with a changing element like the sequence id. This approach is resolving the previously seen desynchronization point but will reduce the security aspects and allow later replay. So this need to be implemented with a key change procedure you execute on regular basis. Here is the complexity to manage as ensuring a communication has been send and received both side is so complex. (you can take a look to my Sigfox downlink blog post about this point).
As an example LoRaWan is implementing a key exchange during the connect phase for later communications. To keep it secured this key should be renewed with regular disconnection/reconnections with having the risk to not be able to reconnect in a situation you were able to reach the network (uplink) but not to receive communications from it (downlink). This is because in LPWAn, sending area is larger than receiving area.
Next to these considerations, you also need to understand encryption is scrambling the bits so depending on the selected protocol you need a specific payload size to apply the algorithm. Sigfox is a 1bit to 96bits frame size protocol. The way you encryption algorithm must be compatible otherwise it will not work: like moving bits out of the frame size.
How does Sigfox encryption service work ?
So as we, now, understand the encryption challenge, let’s consider what Sigfox propose as a standard encryption protocol.
Firstly the encryption is made from the device to Sigfox network kernel. It means at radio level. The payload is decrypted before being stored in the backend. So this encryption is transparent for your application (it doesn’t care about it). This is good for radio protection but leaves your data visible from the backend and your application.
If you do not want Sigfox to watch your data you need to implement your own encryption solution or use the standard one with a key Sigfox will not know, so you will apply the decryption on your server side. That said you will also have to implement the synchronization mechanism as explained previously.
For encrypting the communications, the device will use a pre-shared key. This one can be simply derived from the private key any Sigfox device uses for HMAC (the NAK key) or a custom one stored in device flash or stored in a secure element. Depends on what kind of physical attacks you want to be protected against. Once this shared key is existing and known both side, this key will be used with a specific “counter” value. The “counter” value will be encrypted with AES128 standard thanks to the shared key. This will generate a new 128b value you can’t predict until you know the shared key and “counter” value. The “counter” value contains different static & device specific values and a sequential counter.
The given value will be used as a mask for a simple XOR function to scramble the payload. This XOR will switch some of the payload bits. This approach allows to scramble payload whatever its size is. This way even with 128b AES you can proceed 96bits (or less) of the frame. This approach does not mix/rotate the bits in the frame.
This is described in the documentations with the following schema:
As you can see we need two information to be shared: the Key (Ke) and the CTR (previously identified as “counter”). CTR is modified on every frame. In case of frame loss the receiver can easily re-sync CTR with the sequence number – but sequence number and CTR may be different and have different modulus to avoid any frame repetition at any-time. For this, Sigfox uses the 12bits Sequence ID and it adds extra bits. I will name these 8 extra bits as CycleID. The CycleID may increment every times the sequence ID overflows. The following procedure is used to create the Sigfox CTR:
- 1 – Let’s consider V1 et V2 (16 bytes each) made by getting the deviceID and shift it 1 bit on the right. Add a bit 1 (for V1) and a bit 0 (for V2) upfront. The device ID representation is LittleEndian ( 00112233 ) will produce 1 | 33 22 11 00 …
- 2 – Transform V1 and V2 into W and Ke thanks to AES128-ECB transformation using the device internal KEY (NAK). Ke will be the key used to encrypt the CTR with AES.
- 3 – Create the CTR vector with the following elements: take the first bytes of W and add for the 5 last quartet the cycleID and the sequence ID.
According to later discussion, the W13 quartet seems to not comes from the W calculation. Its value seems to be 0000 for uplink and 0001 for downlink. (Thank you Loïc F. for this update proposal, result of newer tests).
- 4 – Then the CTR vector is encrypted with AES-ECB using the Ke key.
- 5 – This result is used to scramble the payload with XOR function. The previously calculated result : Encrypted Payload = PlainTextPayload XOR AES(CTR,Ke)
- 5 – Calculate the MAC of the frame with the following vector
The vector size vary depending on the payload size. It can be 16 or 32 bytes long. The difference with a non encrypted frame is the use of CycleID byte in the sequence. A non encrypted frame will not have this byte present. As a consequence in case of CycleID desynchronization between device and Sigfox backend the MAC will be invalid and the frame will be rejected. The frame sent without encryption will also be rejected. There is no risk to have an invalid decryption.
In the Sigfox library, the CycleID value is re-synced thanks to a OOB message sent on regular basis (2 repeats). I’ve able to verify this OOB frame is clear text so CycleID is not a secret value. It just protect against frame replay.
This Sigfox implementation is similar to the LoRaWAN encryption protocol. The main difference is LoRaWan is negotiating new Ke during the connect phase. Sigfox is using a key derived from the internal Key used for HMAC authentication. In LoRaWan the CTR is created from some static elements, the device ID and the equivalent of the sequence ID (w/o modulus)
Side note, after discussion, it seems the MAC vector indicated could miss some elements. Basically the encryption add the CycleID (also call RoC) in front of the classical MAC vector. So potentially we may have, between CycleID and Seq ID the fields LI, BF, REP (I’m not 100% sure of the meaning of each). So this side note is more about “you need to check this part if you want to implement it”.
What about downlink ?
I’ve been able to verify downlink is also encrypted with Sigfox native solution: the process is exactly the same. The sequence ID used for decrypting is the same as the associated uplink (this makes sense).
The corresponding downlink confirmation OOB is also encrypted as a normal uplink message.
How to start using Sigfox encryption?
So basically the problem of communication encryption on Sigfox is not due to the network or protocol. It’s due to the implementations. That’s said the truth is if you want to implement encryption you will have to manage it on your own. For real none of the Sigfox Modem I’m usually using are implementing or documenting how to use the encrypted mode. Telecom Design TD120X, Wisol Sfm10, ATA8520 (Mkrfox1200), none of them are proposing a way to activate the encrypted payload.
So we need to go to a low level to implement it: directly use the Sigfox library. This can be done with the STM32+S2LP development kit. The following picture shows the architecture:
You can see in this picture the integration of the security encryption between the Sigfox library and the overall solution. The library requires an AES implementation and potentially use a Secure Element to store the secret keys.
To use encryption you need to have a device with a payload encryption certification. Honestly I do not understand why most of the modem does not implement encryption, at least as an option… as a consequence if you want to use encryption it is a bit a mess to find a platform supporting it. Basically any platform where you directly instantiate the Sigfox library like STM2/S2LP or Murata STM32/Semtech will work perfectly. Then you need to ask Sigfox support to activated encryption on the device. This is possible if the CRA (Device certificate) is validated for encryption ; STM32/S2LP may be soon.
Once done you can transmit encrypted payload. To make it simple you can access the source code of my sample demo on GitHub. It is based on the Disk91 IoT SDK, basically you just need to modify the configSigfox.h file to add __SIGFOX_ENCRYPT_SIGFOX flag into the ITSDK_SIGFOX_ENCRYPTION setting and the sent frames will be encrypted.
There is no more to do ! So it is easy isn’t it ?!?
The advantage of the Sigfox encryption is to have seamless solution. The synchronization are managed on its own and in case of desynchronization the frame are trashed and you will have no risk of receiving invalid payload. The disadvantage is the lack of implementation in the usual modem. For this reason you may want to implement your own encryption solution.
I would have say, no need to tell the Sigfox native encryption is free of charge but as it has been asked, here is the response from Sigfox:
How can I make my own encryption solution
There is different ways to encrypt your payload, the one seen previously, used by Sigfox and LoRaWan, are the more easy to use: it works with any payload size. The final encryption is just an “unpredictable” bit switching with no bit scrambling. It is not AES encryption but CTR encryption using AES128 to generate the Block Cipher Encryption. The advantage : 2 identical frames sent consecutively will have give 2 different frames.
You can easily implement it by yourself: you generate the Ke element as a shared secret between you device and the server. Make sure you have a specific one per device and you keep it secret. Create your CTR based on the Sequence Id + whatever you want static or derived from the device id. There is nothing complex here, everything is static you just need to have a sequence ID without modulus.
You can also look at an encryption allowing to scramble bits in a data block (like AES). In this case you need to have an encryption solution managing block size compatible with the data you want to exchange. As an example AES128 works with 128bits blocks. The maximum payload size for Sigfox payload is 96bits. So this is not working. As the frame size for Sigfox are 4bytes, 8bytes, 12bytes you need to use encryption algorithm working on 32bits blocks (4bytes).
An algorithm like Speck can be used on different word size from 32b to 128b. It’s a possible good candidate for a Sigfox payload encryption. An implementation can be found in this Github repository. The key size for 32b blocks is 64b, the size of a Sigfox downlink. The other important parameters to take into account are the code size, the needed RAM and the Time to encrypt (corresponding to an associated power consumption). As an example for Speck, some information can be found on Internet. Code size is about 0.5KB, Ram needed is about 60B. Processing time is 3s on an AVR according to some publication. You can see encryption is not really a question of software cost, it can be eventually a question of power cost, mainly when you have a low-speed MCU. Speck choice is controversial because this solution came from NSA. In my point of view, if you do not want to protect against United State government it has many advantages.
With this approach two identical frames will give an identical result. So it is recommended to change the Key on regular basis. As already explained the main complexity comes to that point. But it still something feasible with a little work.
The use of SPECK32 + AES128-CTR is also possible as you can see in the full running example accessible on my Sigfox encryption demo repository on GitHub.
The AES-ECB (CTR) method for encryption are doing a good job but in my point of view as soon as you know a part of the plain text it sounds at risk. When creating a communication protocol you usually have some header for common frame and these header are static value you know. This is reducing, frame after frame the possible key candidates. I actually don’t know what is the related risk but it needs to be considered. This is valid for all the method based on AES seen before, as for Sigfox and LoRaWan.
Taking a look to AES-OFB approach as Pascal L. (thank you Pascal) proposed to me could be an improvement compatible with the IoT/LPWAn context. In this approach an IV vector is added. This IV is calculated from the previous AES(Ke,CTR). As it is independent of the data previously transmitted it can be calculated in the kernel network (or backend) even if some frames are lost during the communication. I’ll later try an implementation ;).