La LoRa Alliance prend au sérieux les vulnérabilités découvertes puisque les versions 1.1 (parue en 2017 mais incompatible avec 1.0.x) puis 1.0.4 en juin 2020 apportent des corrections aux points soulevés précédemment.
Attention cependant, modifier le protocole ne corrige pas les failles qui n’en découlent pas. Seule une sensibilisation et mise en place de bonnes pratiques peut aider les constructeurs sur la sécurité lors du déploiement de leurs produits et serveurs en production.

Remplacement des nombres aléatoires

D’après les spécifications 1.1 ligne 1507 et 1.0.4 ligne 1435, DevNonce et AppNonce sont maintenant des compteurs :
DevNonce is a counter starting at 0 when the end-device is initially powered up and incremented with every Join-Request. A DevNonce value SHALL never be reused for a given JoinEUI value.

Cela permet d’éviter les collisions produites par des générateurs d’aléas biaisés et ne permet de garder que la valeur actuelle des compteurs en mémoire plutôt que toutes les valeurs précédemment utilisées.

Persistence des compteurs entre redémarrages

Les compteurs des appareils ABP doivent maintenant être persistés, comme indiqué dans les spécifications 1.1 ligne 640 et 1.0.4 ligne 686 :
ABP devices have their Frame Counters initialized to 0 at fabrication. In ABP devices the frame counters MUST NEVER be reset during the device’s life time. If the end-device is susceptible of losing powerduring its life time (battery replacement for example), the frame counters SHALL persist during such event.

Ce qui à pour effet de contrer directement le rejeu de paquet après réinitialisation du FCnt via redémarrage. Concernant le débordement des FCnt sur 16 bits, la taille minimale passe maintenant à 32 bits (spécifications 1.1 ligne 653 et 1.0.4 ligne 703) :
Frame counters are 32 bits wide. The FCnt field SHALL correspond to the least-significant 16 bits of the 32-bit frame counter

La persistance des compteurs touche maintenant également le DevNonce et AppNonce (spécifications 1.1 ligne 1507 et 1.0.4 ligne 1435), là ou auparavant un “certain nombre” devait être gardé en mémoire :
If the end-device can be power-cycled, then DevNonce SHALL be persistent (e.g., stored in a non-volatile memory). Resetting DevNonce without changing JoinEUI will cause the Join Server to discard the Join-Requests of the end-device. For each end-device, the Join Server keeps track of the last DevNonce value used by the end-device and ignores Join-Requests if DevNonce is not incremented.

Liaison des paquets entre eux

Ajout d’un champ ConfFCnt dans le MIC d’un accusé de réception seulement dans la version 1.1. Ce champ contient les 16 bits inférieurs du FCnt du paquet confirmé (spécifications 1.1 lignes 775 et 791) :
 If ACK bit of the […] frame is set, meaning this frame is acknowledging a […] “confirmed” frame, then ConfFCnt is the frame counter value modulo 2^16 of the “confirmed” […] frame that is being acknowledged. In all other cases ConfFCnt = 0x0000.

Dans la version 1.1 uniquement (ligne 789), les uplink contiennent les infos de DR (TxDR) et canal (TxCh) dans leur MIC pour éviter le rejeu. Les canaux sont pseudo-aléatoires à chaque transmission et le DR négocié entre appareil et serveur réseau. Puisque l’appareil utilise les paramètres radio de l’uplink durant ses 2 fenêtres de réception qui suivent (RX1 et RX2), il n’est pas possible de rejouer un downlink précédent arbitraire car l’appareil écoute sur la même DR et canal que le message qui viens d’être envoyé.

Ajout du Join Server

Une modification majeure est l’ajout du Join Server en plus du Network Server (serveur réseau) et Application Server (serveur applicatif). Le Join Server est gérer par le constructeur des appareils et remplace le serveur réseau lors de la procédure d’appairage afin que seul l’appareil et son constructeur connaissent la clé maître AppKey.
Les JoinRequest lui sont transmise lors de l’appairage OTAA pour vérification et dérivation des clés. Il génère ensuite les JoinAccept correspondants. Enfin il est chargé de transmettre la clé de signature NwkSKey au serveur réseau, et la clé de chiffrement AppSKey au serveur applicatif.

Ce mécanisme permet de séparer les responsabilités des tiers : l’opérateur n’a plus à gérer l’établissement de sessions.
Les spécifications 1.1 ajoutent le roaming, le fait qu’un appareil puisse utiliser n’importe quelle passerelle et serveur réseau pour communiquer avec son serveur applicatif. Ce ne serait pas possible sans un tier pour authentifier l’appareil et dériver les clés de session car tout serveur réseau n’aurait pas en sa possession la clé racine de l’appareil en question.

Conclusion

Le LoRaWAN, tel Sigfox et d’autres protocoles LPWAN, est taillé sur mesure pour l’IoT. Il intéresse autant par sa couche physique LoRa que ses propriétés de faible consommation et complexité tout en apportant sécurité et qualité de service.

Même si les dernières versions en date du LoRaWAN permettent de corriger ses vulnérabilités, nombre d’appareils LoRaWAN n’évolueront pas vers ces versions ou ne sont plus supportés. Les appareils LoRaWAN sont faits pour être simplifiés au possible afin de réduire les coûts, n’embarquant pas de système de mise à jour à distance.
D’ailleurs, même depuis la version 1.1, peu d’appareils sont mis à niveau. Ils ne nécessitent pas les fonctionnalités ou la sécurité apportée face aux coûts de développement et intégration de cette version.
La version 1.0.4, dans la lignée des version 1.0.x, donc plus proche du besoin et demandant un effort d’intégration moindre, séduira peut-être plus les constructeurs même si elle ne permet pas de se protéger contre toutes les vulnérabilités.

À lire également