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

5
(1)

Le chiffrement consiste à rendre les données illisibles pour toute personne ne possédant pas la clé de déchiffrement, assurant ainsi leur confidentialité.

Ce principe vous est sans doute familier grâce au petit cadenas affiché dans la barre d’adresse de votre navigateur : il indique que la communication entre votre appareil et le site web utilise le protocole sécurisé HTTPS. Ainsi, même si un attaquant intercepte le trafic, il ne pourra pas en lire le contenu.

Toutefois, la protection des données ne se limite pas aux échanges réseau. Dans le cas des objets connectés, il est tout aussi crucial de chiffrer la mémoire Flash, afin d’empêcher l’accès ou la modification non autorisés des informations stockées localement.

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

Vous pouvez utiliser la clé de chiffrement matérielle intégrée à l’ESP32 (unique pour chaque puce) ou générer votre propre clé de chiffrement personnalisée. Chaque méthode présente ses avantages et ses inconvénients. Dans ce tutoriel, à des fins pédagogiques, j’ai choisi de générer ma propre clé de chiffrement.

Voici comment générer votre propre clé de chiffrement :

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

Votre clé de chiffrement doit être écrite dans l’ESP32. Afin de garantir la confidentialité absolue de la clé et d’empêcher toute lecture ou modification ultérieure, le dispositif utilise le mécanisme de programmation eFuse.

Un eFuse (fusible électronique) est un composant matériel intégré directement dans la puce de l’ESP32. Contrairement à la mémoire flash standard, c’est une mémoire OTP (One-Time Programmable) : une fois un bit activé, il ne peut plus être modifié ni effacé. Cette opération est donc permanente et irréversible.

Bash
espefuse --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 --port /dev/ttyUSB0 burn_key flash_encryption my_key.bin
espefuse 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.

Nous pouvons vérifier par la suite que nous n’avons aucun accès en lecture à la clé de chiffrement :

Bash
espefuse --port /dev/ttyUSB0 summary

Renvoie des points d’interrogation pour BLOCK1, la clé de chiffrement est correctement protégée en lecture.

Bash
BLOCK1 (BLOCK1)                                    Flash encryption key                              
   = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/- 

#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 --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CNT 1
espefuse --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CONFIG 0x0F

Vérifions les valeurs des fusibles électroniques à cette étape :

Bash
espefuse --port /dev/ttyUSB0 summary

FLASH_CRYPT_CNT est défini sur 1 et FLASH_CRYPT_CONFIG est défini sur 0xf, cela semble correct.

Bash
Flash fuses:
FLASH_CRYPT_CNT (BLOCK0)                           Flash encryption is enabled if this field has an o = 1 R/W (0b0000001)
                                                   dd number of bits set                             
FLASH_CRYPT_CONFIG (BLOCK0)                        Flash encryption config (key tweak bits)           = 15 R/W (0xf)

#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 encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0x1000 \
  --output bootloader_enc.bin \
  bootloader.bin  

$ espsecure encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0x8000 \
  --output partitions_enc.bin \
  partitions.bin  
  
$ espsecure encrypt_flash_data \
  --keyfile my_key.bin \
  --address 0xe000 \
  --output boot_app0_enc.bin \
  boot_app0.bin    
    
$ espsecure 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 --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 5 / 5. Vote count: 1

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?