Securing wireless protocols using LoRaWAN as an example
Hi, Habr.
I would like to once again talk about how the basic (read: minimum necessary) level of data security in wireless networks used in IoT devices is provided, using the LoRaWAN as an example.
Why LoRaWAN? Firstly, because it is a well-described and well-developed standard that should be guided as a reference if you are developing some kind of your own wireless protocol. Secondly, because it is a very native and typical IoT solution; You can, of course, disassemble security in Wi-Fi or LTE, but for most developers this will be a futile analysis: it is unlikely that you will need to write your own Wi-Fi implementation. Thirdly, it is low-power IoT devices in which developers save every byte that often turn out to be the most leaky - here LoRaWAN gives a good idea of how to save bytes, and not be attacked. Fourth, finally
Messaging on the LoRaWAN between the server and the device
Although the messaging scheme in LoRaWAN in the picture looks pretty simple - this simplicity is misleading: it has a lot of work to do, and not a single pixel in it is superfluous. Now you will understand why.
We will analyze using LoRaWAN 1.0.2 as an example and dance against possible threats - for a good developer should always think not about how his system is protected, but about how it can be broken. Otherwise, someone else will think about it for him.
So, what are the main threats in the wireless network - and how to protect yourself from them?
The simplest threat is a regular data interception: Since radio waves propagate uncontrollably, then absolutely anyone can take a receiver tuned to the desired range and type of modulation, and listen to everything that you transmit.
The easiest way to protect against this is data encryption.
In LoRaWAN, user data is encrypted using the AES-128 algorithm with a key length of 128 bits (16 bytes), respectively. AES is a reliable algorithm, however, on minimally modern microcontrollers that do not even have a hardware encryption block, its use does not entail significant overhead: on a Cortex-M3 with a frequency of 48 MHz, one 16-byte block is encrypted in about 100 μs from scratch.
In some cases, an attacker does not need to know what exactly you are transmitting there. For example, if you have a sensor of a closed window that transmits one thing, and an open one - that is another, then you can record one without going into the details of its contents, muffle the sensor, and so that the system does not suspect something was wrong due to the lack of packets from the sensor - broadcast the previously recorded message.
In LoRaWAN, a counter is added to each packet. If a packet arrives at the network server with a counter equal to or less than the previous one, then this packet is simply discarded. With two bytes per meter and a typical IoT-system speed of message transmission, it will last for a very long time - for example, even a household weather station that transmits temperature every minute will overflow it only after a month and a half (LoRaWAN allows a 4-byte counter at all).
There is, however, an obvious problem - after an overflow, a packet with number 0 will come from the device, which, obviously, will be less than any other number, but the network server should perceive it correctly and start the packet counting again. In addition, the device can reset the counter by simply rebooting.
This is achieved in one of two ways:
Both schemes are used in LoRaWAN depending on how the device is activated - OTAA or ABP (we will talk about them below). The first option is used for OTAA, and the device is also given new encryption keys - so even an attacker who has spent a month and a half under your weather station will not be able to transmit any previously recorded packets so that the system accepts it.
For ABP, in which there is no registration procedure in the network, the second option is used - however, if the counter overflow period significantly exceeds the estimated device life, and it can be disabled. In the event of an accidental reboot after sending each packet, such an end device stores the counter value in non-volatile memory.
The second scheme, of course, is less secure, but in practice it is permissible - an attacker needs to record not any packet in it, but specifically zero. If desired, you can make its contents different from all other packages - for example, transmit not data in it, but information about the type and settings of the device; then its interception and repetition will not give anything reasonable.
Counterfeit counter
However, the question immediately arises - what if the counter is faked? You can put it in the encrypted part of the packet, but then the real amount of user data will decrease by two bytes. You can encrypt not only user data, but then, firstly, you have to adapt to the 16-byte block size, and secondly, the load on the network server will increase, which will have to decrypt it first for any actions on the package (in the scheme, when only user data is encrypted, if the package is ignored formally, then nothing needs to be decrypted).
It is obvious that it does not matter to us whether the attacker knows the package number or not - in the scheme with network re-registration (OTAA) this knowledge will not help him at all, and in ABP he will wait a very long time by the sea for the weather, i.e. the next arrival of the packet with the number N-1.
Therefore, it is quite enough not to let him change this number.
To do this, the entire package in LoRaWAN is signed with a cryptographic signature - AES-CMAC, this signature in the standard is called MIC, Message Integrity Code. It checks that the entire package , including all headers and data, has reached the server unchanged.
That is, having accepted the next package, we can quickly look into its counter (sender address, etc), and if it is ours and correct, then already verify the signature (spending additional resources on it), and if the signature is also correct - decrypt the data and transmit them further.
Tracking unchanging data
Unfortunately for us, it’s not enough to prevent an attacker from understanding the data or at least repeating it - in some cases it will be enough for him to understand that they are not changing. A textbook example is home water meters: if you just want to find out if the owners are at home, it doesn't matter to you exactly how many liters there are, it’s important for you to know if this value is increasing .
Obviously, data encryption is a reversible procedure (they can be decrypted), which means that the same data encrypted with the same key always looks the same. When receiving packets from a water meter, whose readings do not change, you can, without decrypting the packet , understand that they do not change.
To deal with this is quite simple - either the data or the key must change. To change the data, you can add salt to them - a few random bytes that are simply thrown away after decryption. Unfortunately, 16 bytes of a packet are already sparse, so in the general case we don’t want to spend 2-4 bytes of them on actual garbage.
LoRaWAN uses a trickier scheme . Remember we have a packet counter? So, this particular counter plus information about the device and the packet (short address of the device on the LoRaWAN network, data transfer direction, 16-byte counter) are encrypted using AES algorithm, and the XOR result is with the user data packet.
As a result, the payload bytes are not wasted, and each message looks different regardless of whether the load has changed or not.
PS There is another option, a little simpler: use the message counter as the last N bytes of the key. In this case, the key will be new each time, but because Since the server knows the value of the message counter (it is in the unencrypted part of the message), it will be able to restore it. Minus - if your package consists of several 16-byte blocks, and they have the same data, then after encryption they will remain the same.
The attacker has learned the encryption key
It’s a very real situation - IoT is characterized by the use of a large number of devices, over which you can generally not have reliable control over access to outsiders (and if you are also a network operator, then your customers are by definition outsiders for each other).
Therefore, if all your devices have the same encryption key, the owner of any of them can listen to the traffic of any other device (generally speaking, if he has the ability to modify the firmware, then for such an operation you may not even know the key explicitly - let the new firmware takes it from the same place as the old one, and just gives us other people's data).
LoRaWAN implements two schemes for using keys, individual for each device:
There are at least two keys in total - AppSKey, which encrypts user data, and NwkSKey, which signs the message.
Obviously, the OTAA scheme is more convenient and reliable - the keys can change as often as you want, they are guaranteed to be unique and not known to anyone except the network server. In ABP, the keys never change, the uniqueness depends on the conscientiousness of the device manufacturer (for example, we generate these keys from the unique ID of the microcontroller, so the probability of their coincidence on the two devices is negligible), and they must be stored explicitly somewhere, so when connecting the device to the network register them on the server.
However, the procedure for obtaining keys in OTAA is a separate story, which, if implemented inaccurately, can give rise to several more types of attacks.
Obviously, if new keys are generated each time during registration on the network, then they must be synchronized between the device and the server, which means that an attacker can intercept them, thereby breaking all the protection.
Therefore , LoRaWAN devices have a third key - AppKey, tightly wired into the device and used at one single moment: when registering on the network. With it, an exchange of session keys between the device and the server is signed.
Ideally, the AppKey should be unique for each device, but in many cases the use of the same AppKey is allowed - since it is needed only once, this can be recognized as valid.
AppKey before connecting the device is entered in its settings on the network server.
So, the device generates a registration request (JoinRequest), not encrypting it (it does not have any sensitive information), but signing it with the AppKey key. The network server, having received this packet and checking the sender address (whether this is our device at all) and then the signature, responds with the JoinAccept packet, in which it transfers the network settings - well, it actually confirms the registration.
Where do the AppSKey and NwkSKey keys come from?
This is the result of AES-128 encryption with the AppKey key of a combination of a random AppNonce number, key number (1 or 2), network ID, and another random DevNonce number sent by the server in the response:
Since both the device and the server after exchanging registration packets know all these parameters, they will generate the same keys. Thus, at no time will any keys be transmitted by radio on their own, but at the same time, the device and the server will receive unique encryption and packet signing keys.
But that's not all!
Yes, the registration event on the network is usually an infrequent thing, but imagine that an attacker was able to initiate and intercept it.
Then, if he simply sends the JoinRequest packet that he recorded, without changing anything in it, the server will respond to it with the JoinAccept packet, generating new keys. After this, the attacked device simply stops communicating with the server, because it did not initiate JoinRequest and does not see any reason to update the keys. That is, the same attack is repeated - but already on the registration procedure on the network.
An attacker will not be able to fake the data, because for this you need to know the keys, and to obtain them you need to know the AppKey, which he does not know. But to knock the device out of the network - he can.
To avoid this, during registration, the device sends a random number of DevNonce to the server (look, it is in the packages above). Besides the fact that keys are generated on its basis, it serves another purpose - the LoRaWAN server stores the DevNonce archive . If the device receives a repeated registration request with the DevNonce already used, the server will simply ignore it.
In turn, the device is obliged to generate a new DevNonce at each registration (that is, the circuit with the relay of conventional packets — “did not receive a response, spat out the same packet in the radio a second time” - does not work here, JoinRequest is re-created every time).
Although there was a lot of text and few pictures, even this is not a complete scheme of possible attacks on the radio alone (the questions about why, for example, the settings must be encrypted on the device, and we left the key with an individual key for each device outside the brackets, this is no longer about the radio). For example, in LoRaWAN 1.1, protection schemes have become even more complicated.
Nevertheless, this is a gentleman's set of any radio protocol that claims to have minimum worthy protection of information and at the same time is designed to work on low-power devices in low-speed networks. Moreover, this is a very good example of implementing not just a secure protocol, but a protocol written for low-power devices and minimizing the consumption of both airtime and computing power wherever possible without significant damage to security.
And if you are designing your own protocol for IoT, then the well-specified LoRaWAN, combined with an understanding of the basic methods of conducting attacks, provides an excellent opportunity to learn how to properly organize this protection.
I would like to once again talk about how the basic (read: minimum necessary) level of data security in wireless networks used in IoT devices is provided, using the LoRaWAN as an example.
Why LoRaWAN? Firstly, because it is a well-described and well-developed standard that should be guided as a reference if you are developing some kind of your own wireless protocol. Secondly, because it is a very native and typical IoT solution; You can, of course, disassemble security in Wi-Fi or LTE, but for most developers this will be a futile analysis: it is unlikely that you will need to write your own Wi-Fi implementation. Thirdly, it is low-power IoT devices in which developers save every byte that often turn out to be the most leaky - here LoRaWAN gives a good idea of how to save bytes, and not be attacked. Fourth, finally
Messaging on the LoRaWAN between the server and the device
Although the messaging scheme in LoRaWAN in the picture looks pretty simple - this simplicity is misleading: it has a lot of work to do, and not a single pixel in it is superfluous. Now you will understand why.
We will analyze using LoRaWAN 1.0.2 as an example and dance against possible threats - for a good developer should always think not about how his system is protected, but about how it can be broken. Otherwise, someone else will think about it for him.
So, what are the main threats in the wireless network - and how to protect yourself from them?
Interception of user data
The simplest threat is a regular data interception: Since radio waves propagate uncontrollably, then absolutely anyone can take a receiver tuned to the desired range and type of modulation, and listen to everything that you transmit.
The easiest way to protect against this is data encryption.
In LoRaWAN, user data is encrypted using the AES-128 algorithm with a key length of 128 bits (16 bytes), respectively. AES is a reliable algorithm, however, on minimally modern microcontrollers that do not even have a hardware encryption block, its use does not entail significant overhead: on a Cortex-M3 with a frequency of 48 MHz, one 16-byte block is encrypted in about 100 μs from scratch.
Data repeat
In some cases, an attacker does not need to know what exactly you are transmitting there. For example, if you have a sensor of a closed window that transmits one thing, and an open one - that is another, then you can record one without going into the details of its contents, muffle the sensor, and so that the system does not suspect something was wrong due to the lack of packets from the sensor - broadcast the previously recorded message.
In LoRaWAN, a counter is added to each packet. If a packet arrives at the network server with a counter equal to or less than the previous one, then this packet is simply discarded. With two bytes per meter and a typical IoT-system speed of message transmission, it will last for a very long time - for example, even a household weather station that transmits temperature every minute will overflow it only after a month and a half (LoRaWAN allows a 4-byte counter at all).
There is, however, an obvious problem - after an overflow, a packet with number 0 will come from the device, which, obviously, will be less than any other number, but the network server should perceive it correctly and start the packet counting again. In addition, the device can reset the counter by simply rebooting.
This is achieved in one of two ways:
- Before sending such a package, the device must undergo the registration procedure on the network (in the LoRaWAN network, this procedure is called Join)
- the server allows the arrival of the next packet with number 0, while the countdown starts anew
Both schemes are used in LoRaWAN depending on how the device is activated - OTAA or ABP (we will talk about them below). The first option is used for OTAA, and the device is also given new encryption keys - so even an attacker who has spent a month and a half under your weather station will not be able to transmit any previously recorded packets so that the system accepts it.
For ABP, in which there is no registration procedure in the network, the second option is used - however, if the counter overflow period significantly exceeds the estimated device life, and it can be disabled. In the event of an accidental reboot after sending each packet, such an end device stores the counter value in non-volatile memory.
The second scheme, of course, is less secure, but in practice it is permissible - an attacker needs to record not any packet in it, but specifically zero. If desired, you can make its contents different from all other packages - for example, transmit not data in it, but information about the type and settings of the device; then its interception and repetition will not give anything reasonable.
Counterfeit counter
However, the question immediately arises - what if the counter is faked? You can put it in the encrypted part of the packet, but then the real amount of user data will decrease by two bytes. You can encrypt not only user data, but then, firstly, you have to adapt to the 16-byte block size, and secondly, the load on the network server will increase, which will have to decrypt it first for any actions on the package (in the scheme, when only user data is encrypted, if the package is ignored formally, then nothing needs to be decrypted).
It is obvious that it does not matter to us whether the attacker knows the package number or not - in the scheme with network re-registration (OTAA) this knowledge will not help him at all, and in ABP he will wait a very long time by the sea for the weather, i.e. the next arrival of the packet with the number N-1.
Therefore, it is quite enough not to let him change this number.
To do this, the entire package in LoRaWAN is signed with a cryptographic signature - AES-CMAC, this signature in the standard is called MIC, Message Integrity Code. It checks that the entire package , including all headers and data, has reached the server unchanged.
That is, having accepted the next package, we can quickly look into its counter (sender address, etc), and if it is ours and correct, then already verify the signature (spending additional resources on it), and if the signature is also correct - decrypt the data and transmit them further.
Tracking unchanging data
Unfortunately for us, it’s not enough to prevent an attacker from understanding the data or at least repeating it - in some cases it will be enough for him to understand that they are not changing. A textbook example is home water meters: if you just want to find out if the owners are at home, it doesn't matter to you exactly how many liters there are, it’s important for you to know if this value is increasing .
Obviously, data encryption is a reversible procedure (they can be decrypted), which means that the same data encrypted with the same key always looks the same. When receiving packets from a water meter, whose readings do not change, you can, without decrypting the packet , understand that they do not change.
To deal with this is quite simple - either the data or the key must change. To change the data, you can add salt to them - a few random bytes that are simply thrown away after decryption. Unfortunately, 16 bytes of a packet are already sparse, so in the general case we don’t want to spend 2-4 bytes of them on actual garbage.
LoRaWAN uses a trickier scheme . Remember we have a packet counter? So, this particular counter plus information about the device and the packet (short address of the device on the LoRaWAN network, data transfer direction, 16-byte counter) are encrypted using AES algorithm, and the XOR result is with the user data packet.
As a result, the payload bytes are not wasted, and each message looks different regardless of whether the load has changed or not.
PS There is another option, a little simpler: use the message counter as the last N bytes of the key. In this case, the key will be new each time, but because Since the server knows the value of the message counter (it is in the unencrypted part of the message), it will be able to restore it. Minus - if your package consists of several 16-byte blocks, and they have the same data, then after encryption they will remain the same.
The attacker has learned the encryption key
It’s a very real situation - IoT is characterized by the use of a large number of devices, over which you can generally not have reliable control over access to outsiders (and if you are also a network operator, then your customers are by definition outsiders for each other).
Therefore, if all your devices have the same encryption key, the owner of any of them can listen to the traffic of any other device (generally speaking, if he has the ability to modify the firmware, then for such an operation you may not even know the key explicitly - let the new firmware takes it from the same place as the old one, and just gives us other people's data).
LoRaWAN implements two schemes for using keys, individual for each device:
- Over The Air Activation, OTAA - keys are generated by the network server every time a device is registered in it
- Activation By Personalization - keys are set by the manufacturer and stored on the device, never changing
There are at least two keys in total - AppSKey, which encrypts user data, and NwkSKey, which signs the message.
Obviously, the OTAA scheme is more convenient and reliable - the keys can change as often as you want, they are guaranteed to be unique and not known to anyone except the network server. In ABP, the keys never change, the uniqueness depends on the conscientiousness of the device manufacturer (for example, we generate these keys from the unique ID of the microcontroller, so the probability of their coincidence on the two devices is negligible), and they must be stored explicitly somewhere, so when connecting the device to the network register them on the server.
However, the procedure for obtaining keys in OTAA is a separate story, which, if implemented inaccurately, can give rise to several more types of attacks.
Interception of generated keys
Obviously, if new keys are generated each time during registration on the network, then they must be synchronized between the device and the server, which means that an attacker can intercept them, thereby breaking all the protection.
Therefore , LoRaWAN devices have a third key - AppKey, tightly wired into the device and used at one single moment: when registering on the network. With it, an exchange of session keys between the device and the server is signed.
Ideally, the AppKey should be unique for each device, but in many cases the use of the same AppKey is allowed - since it is needed only once, this can be recognized as valid.
AppKey before connecting the device is entered in its settings on the network server.
So, the device generates a registration request (JoinRequest), not encrypting it (it does not have any sensitive information), but signing it with the AppKey key. The network server, having received this packet and checking the sender address (whether this is our device at all) and then the signature, responds with the JoinAccept packet, in which it transfers the network settings - well, it actually confirms the registration.
Where do the AppSKey and NwkSKey keys come from?
This is the result of AES-128 encryption with the AppKey key of a combination of a random AppNonce number, key number (1 or 2), network ID, and another random DevNonce number sent by the server in the response:
NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce)
AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce)
Since both the device and the server after exchanging registration packets know all these parameters, they will generate the same keys. Thus, at no time will any keys be transmitted by radio on their own, but at the same time, the device and the server will receive unique encryption and packet signing keys.
Interception of a data stream on itself
But that's not all!
Yes, the registration event on the network is usually an infrequent thing, but imagine that an attacker was able to initiate and intercept it.
Then, if he simply sends the JoinRequest packet that he recorded, without changing anything in it, the server will respond to it with the JoinAccept packet, generating new keys. After this, the attacked device simply stops communicating with the server, because it did not initiate JoinRequest and does not see any reason to update the keys. That is, the same attack is repeated - but already on the registration procedure on the network.
An attacker will not be able to fake the data, because for this you need to know the keys, and to obtain them you need to know the AppKey, which he does not know. But to knock the device out of the network - he can.
To avoid this, during registration, the device sends a random number of DevNonce to the server (look, it is in the packages above). Besides the fact that keys are generated on its basis, it serves another purpose - the LoRaWAN server stores the DevNonce archive . If the device receives a repeated registration request with the DevNonce already used, the server will simply ignore it.
In turn, the device is obliged to generate a new DevNonce at each registration (that is, the circuit with the relay of conventional packets — “did not receive a response, spat out the same packet in the radio a second time” - does not work here, JoinRequest is re-created every time).
Conclusion
Although there was a lot of text and few pictures, even this is not a complete scheme of possible attacks on the radio alone (the questions about why, for example, the settings must be encrypted on the device, and we left the key with an individual key for each device outside the brackets, this is no longer about the radio). For example, in LoRaWAN 1.1, protection schemes have become even more complicated.
Nevertheless, this is a gentleman's set of any radio protocol that claims to have minimum worthy protection of information and at the same time is designed to work on low-power devices in low-speed networks. Moreover, this is a very good example of implementing not just a secure protocol, but a protocol written for low-power devices and minimizing the consumption of both airtime and computing power wherever possible without significant damage to security.
And if you are designing your own protocol for IoT, then the well-specified LoRaWAN, combined with an understanding of the basic methods of conducting attacks, provides an excellent opportunity to learn how to properly organize this protection.