Pourquoi chiffrer la mémoire Flash de vos objets connectés IoT ?

0
(0)

Le chiffrement permet de rendre illisibles les informations pour toute personne ne disposant pas de la clé de chiffrement, garantissant ainsi leur confidentialité.

Le chiffrement des communications est bien connu grâce au fameux cadenas dans votre navigateur, qui signale l’usage du protocole sécurisé HTTPS. Un attaquant interceptant vos échanges sera alors incapable de lire le contenu transitant entre votre ordinateur et le serveur HTTP visité.

Mais au delà du chiffrement des communications, voyons pourquoi il est important de chiffrer la mémoire Flash d’un objet connecté.

Pourquoi chiffrer la mémoire Flash d’un objet connecté IoT ?

Le “cerveau” d’un objet connecté IoT (Internet of Things) est un micro-contrôleur, qui stocke ses données persistantes (programme, configuration Wi-Fi…) dans une mémoire Flash. Ce type de mémoire conserve en effet les données même sans alimentation.

Une personne ayant un accès physique à un objet connecté peut dès lors lire le contenu de cette mémoire et en extraire des secrets, informations cruciales pour la sécurité de votre réseau (certificats de sécurité, mot de passe de l’application, mots de passe Wi-Fi…). Il est donc indispensable de chiffrer cette mémoire afin de rendre ces secrets illisibles pour un attaquant. Il existe d’ailleurs maintenant des puces spécialisées pour le stockage des secrets (ex : TPM).

La plupart des objets connectés “grand public”, comme les capteurs de température ou les caméras de vidéo-surveillance, ne sont pas équipés de puce TPM et leur mémoire Flash est rarement chiffrée. Or ces objets sont généralement connectés à un réseaux Wi-Fi.

Les communications sur les réseaux Wi-Fi sont maintenant relativement sécurisés avec une clé de chiffrement WPA2-PSK. Mais un attaquant qui a un accès physique à un objet connecté (un capteur dans une usine, une caméra dans votre jardin), peut facilement extraire cette clé de la mémoire Flash non chiffrée de cet objet.

Voici un exemple minimaliste de code pour un objet connecté basé sur un microcontrôleur ESP32, qui se connecte au réseau Wi-Fi TP-Link_21B7 (SSID) avec le mot de passe R3seauS3cur1t3IoT! :

C++
// Example used to show how Wi-Fi password
// can be extracted from Flash memory
//
// https://tutoduino.fr/

#include <WiFi.h>

const char *ssid = "TP-Link_21B7";
const char *passphrase = "R3seauS3cur1t3IoT!";

void setup() {
  Serial.begin(115200);
  delay(100);

  WiFi.begin(ssid, passphrase);

  Serial.println();
  Serial.println();
  Serial.print("Waiting for WiFi... ");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  delay(1000);
}

Le nom du réseau Wi-Fi (ssid) et son mot de passe (passphrase) sont des constantes qui vont être stockées dans la mémoire Flash du microcontrôleur.

Après avoir connecté l’objet via son port USB à un ordinateur sous Linux, il est trivial d’extraire les identifiants Wi-Fi de sa mémoire Flash :

Exemple d’extraction de mot de passe Wi-Fi de la mémoire Flash d’un ESP32

Voici cet exemple illustré en vidéo :

Comment chiffrer la mémoire Flash sur un ESP32 ?

Le framework ESP-IDF permet de chiffrer la mémoire flash des ESP32 avec une procédure relativement simple.

Voici les principales étapes :

#1. Générer une clé de chiffrement (à conserver précieusement !)

Bash
espsecure.py generate_flash_encryption_key my_key.bin

Cette clé a une taille de 256 bits, qui permettra de chiffrer avec un bon niveau de sécurité vos firmwares. Attention cette clé sera nécessaire pour toute les futures modifications de firmware de votre objet connecté, elle doit être conservée précieusement.

#2. Brûlez-la clé de chiffrement dans un eFuse du micro-contrôleur (attention, ceci est irréversible)

Un eFuse (electronic fuse) est un fusible électronique gravé directement dans le silicium de l’ESP32. Contrairement à la mémoire flash réinscriptible, c’est une mémoire OTP (One-Time Programmable). C’est pourquoi cette action est irréversible.

Bash
espefuse.py --port /dev/ttyUSB0 burn_key flash_encryption my_key.bin

Voici le résultat de cette commande si tout se déroule bien :

Bash
steph@F15:~/esp/esp-idf-5.5.1$ espefuse.py --port /dev/ttyUSB0 burn_key flash_encryption my_key.bin
espefuse.py v4.11.dev2
Connecting.....
Detecting chip type... ESP32

=== Run "burn_key" command ===
Sensitive data will be hidden (see --show-sensitive-info)
Burn keys to blocks:
 - BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
	Reversing the byte order
	Disabling read to key block
	Disabling write to key block

Burn keys in efuse blocks.
The key block will be read and write protected (no further changes or readback) 


Check all blocks for burn...
idx, BLOCK_NAME,          Conclusion
[00] BLOCK0               is not empty
	(written ): 0x0000000400000000000014380000b00000a5840d8e19b63400000000
	(to write): 0x00000000000000000000000000000000000000000000000000010080
	(coding scheme = NONE)
[01] BLOCK1               is empty, will burn the new value
. 
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BURN BLOCK1  - OK (write block == read block)
BURN BLOCK0  - OK (all write block bits are set)
Reading updated efuses...
Successful

Votre clé de chiffrement de 256 bits est stockée dans le BLOCK1 des fusibles, elle est protégée en lecture/écriture.

#3. Activer le chiffrement de la flash dans le micro-contrôleur (attention, ceci est irréversible)

Deux eFuse spécifiques doivent être brûlés pour activer le chiffrement de la flash :

  • FLASH_CRYPT_CNT : Compteur qui limite le nombre de tentatives pour activer le chiffrement, empêchant toute réinitialisation non autorisée du chiffrement. Sa valeur doit être impair pour activer le chiffrement.
  • FLASH_CRYPT_CONFIG : Définit les paramètres du chiffrement. La valeur 0x0F active le chiffrement AES-256 pour toutes les données stockées dans la mémoire Flash (y compris le bootloader, l’application et les données utilisateur).
Bash
espefuse.py --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CNT 1
espefuse.py --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CONFIG 0x0F

#4. Activer le chiffrement de la partition NVS

La partition NVS (Non-Volatile Storage) est une partition spéciale de la flash. Son rôle principal est de stocker des données de configuration persistantes qui doivent survivre à un redémarrage ou à une coupure d’alimentation. La partition NVS doit être chiffrée afin de protéger les données sensibles comme les mots de passe.

Le chiffrement de la partition NVS se fait de la manière suivante dans l’IDE Arduino :

  • Sélectionner le schéma de partition “Custom
  • Créer le fichier “partitions.csv” dans le répertoire où est stocké votre croquis sur votre ordinateur
  • Configurer le schéma de partition souhaité au format csv dans ce fichier
  • Ajouter le flag “encrypted” pour la partition NVS
  • Compiler le programme dans l’IDE Arduino (il peut être utile de supprimer auparavant le répertoire cache arduino)
Exemple de schéma de partition avec la partition NVS chiffrée pour un ESP32

#5. Chiffrer le firmware

Après avoir compilé le programme sous l’IDE Arduino, il faut exporter les fichiers binaires générés.

Cela positionne tous les fichiers nécessaires dans le sous-répertoire build du répertoire où est stocké votre croquis Arduino.

Le fichier flash_args contient le nom des fichiers qu’il va falloir chiffrer et à quel offset il va falloir ensuite les flasher dans la mémoire de l’ESP32 :

Chiffrer tous ces fichiers binaires avec votre clé de chiffrement en indiquant en paramètre leur adresse dans la mémoire Flash.

Bash
$ espsecure.py encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0x1000 \
  --output bootloader_enc.bin \
  bootloader.bin  

$ espsecure.py encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0x8000 \
  --output partitions_enc.bin \
  partitions.bin  
  
$ espsecure.py encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0xe000 \
  --output boot_app0_enc.bin \
  boot_app0.bin    
    
$ espsecure.py encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0x10000 \
  --output firmware_enc.bin \
  firmware.bin  

#6. Flasher le firmware chiffré dans la mémoire Flash de l’ESP32

Flasher tous les binaires chiffrés à l’étape précédente dans la mémoire flash de l’ESP32 :

Bash
esptool.py --chip esp32 --port /dev/ttyUSB0 \
  write_flash \
  0x1000  bootloader_enc.bin \
  0x8000  partitions_enc.bin \
  0xe000  boot_app0_enc.bin \
  0x10000 firmware_enc.bin

Le chiffrement assure la confidentialité des données !

En répétant la procédure du début de ce tutoriel, il devient impossible d’extraire les données en clair de la mémoire Flash.

La partition NVS est chiffrée et le SSID et le mot de passe de Wi-Fi ne sont plus lisibles en clair

Le firmware est également chiffré, il n’est plus possible de réaliser d’ingénierie inverse dessus :

Le firmware est également chiffré, rendant impossible tout reverse engineering

Conclusion

Le chiffrement de la mémoire Flash assure la confidentialité des données qu’elle stocke et apporte de nombreux bénéfices aux niveau de la cybersécurité de votre objet connecté IoT :

✅ Bootloader chiffré

  • Empêche l’exécution de code malveillant au démarrage.
  • Protège contre les attaques par modification du bootloader (ex. : injection de malware).
  • Garantit l’intégrité du processus de démarrage.

✅ Application protégée

  • Rend le code illisible sans la clé de chiffrement.
  • Empêche l’ingénierie inverse (reverse engineering) pour voler la propriété intellectuelle.
  • Sécurise les algorithmes sensibles (ex. : protocoles de communication, logiques métiers).

✅ Mot de passe Wi-Fi inextractible

  • Empêche la récupération du mot de passe même avec un accès physique à la mémoire.
  • Réduit les risques de piratage du réseau via l’extraction des identifiants.
  • Protège la confidentialité des données transmises sur le réseau.

✅ Clone du firmware impossible sans la clé de chiffrement

  • Empêche la duplication non autorisée du firmware (protection contre la contrefaçon).
  • Garantit l’authenticité du matériel (seuls les appareils légitimes peuvent fonctionner).
  • Protège les revenus et la réputation en évitant les copies illégales.

En résumé : Le chiffrement de la mémoire Flash renforce la sécurité, protège la propriété intellectuelle et limite les risques de piratage ou de contrefaçon. Un must pour les appareils connectés ! 🔒

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?