Aller au contenu
Niveau de Sécurité : Matériellement Sécurisé

MQTTS Stockage Sécurisé

L'étape 3 implémente un Durcissement au Niveau Silicium en isolant l'identité cryptographique du dispositif dans un coprocesseur dédié. En utilisant le Secure Element ATECC608B, nous séparons physiquement la clé privée du firmware.

Le Concept du Secure Element

Transférer les secrets depuis l'intérieur du code, toujours falsifiable, vers un emplacement de stockage externe sécurisé.

Flux Sécurisé

Pipeline d'Authentification

Trajet de la confiance : du silicium au serveur.

Signataire

ATECC608B

La clé privée est hébergée dans le coffre-fort matériel (Slot 8) et n'est extraite qu'à la volée par le microcontrôleur pour l'authentification, garantissant un stockage sécurisé.

Transport

ESP32

Assure l'encapsulation TLS 1.2 du trafic MQTT. Le microcontrôleur récupère temporairement la clé du Secure Element en mémoire volatile pour établir le tunnel chiffré, sans stockage persistant sur la flash.

Vérificateur

Mosquitto

Valide l'identité du client via l'authentification mutuelle (mTLS). Le broker vérifie la signature cryptographique et la chaîne de certification X.509 avant d'autoriser la session MQTT.

Les limites du stockage Flash conventionnel

Sur un microcontrôleur standard, la mémoire flash ne dispose pas d'isolation matérielle contre les accès physiques directs.

  • Dumping de firmware
  • Clonage d'identité

L'Approche Coffre-Fort

L'ATECC608B est une chambre forte cryptographique. Il introduit une frontière physique que le logiciel ne peut franchir.

Non-Extractabilité
Anti-Tamper

Note Technique : Bien que ce lab charge la clé en RAM pour la démo TLS, en production, la clé ne quitte jamais le chip (offloading TLS).

Schéma de câblage

M5Stack

PORT A (Red)
HUB

ENV II Unit

0x44 (SHT30) 0x76 (BMP280)

ATECC608B Unit

0x35 (I2C)
GND (Noir)
VCC (Rouge - 5V)
SCL (Jaune - Pin 1)
SDA (Blanc - Pin 2)

Pourquoi les clés stockées matériellement améliorent la sécurité

Avantages fondamentaux par rapport au stockage logiciel.

Voir la Fiche Technique

Résistance aux Attaques Invasives

L'extraction de secrets exige des attaques physiques destructives (décapsulation chimique, micro-sondage FIB), nécessitant un équipement de laboratoire coûteux et une expertise avancée, rendant l'attaque économiquement non viable.

Immunité aux Canaux Auxiliaires (SCA)

Le composant intègre des contre-mesures actives pour lisser la consommation de courant et introduire du jitter d'horloge, neutralisant ainsi les attaques par analyse de puissance (SPA/DPA) et temporelles (Timing Attacks).

Injection et Formatage des Clés

La clé privée est générée hors-puce (OpenSSL), sérialisée au format binaire strict (PKCS#8 DER avec préfixe de longueur), puis provisionnée directement dans le slot sécurisé n°8 pour établir l'identité du dispositif.

Intégrité via Verrouillage OTP

Les zones de mémoire (Data Slots) utilisent la technologie One-Time Programmable (OTP). Une fois la zone verrouillée (Locked), la configuration devient irréversible, garantissant l'intégrité permanente des données provisionnées.

Architecture et Flux de données

La clé privée est confinée au sein du Secure Element. L'authentification s'établit directement entre le Broker et la racine de confiance matérielle (Hardware Root of Trust).

Publisher M5Go

Processeur Principal
ESP32
Bus I2C
SÉCURISÉ
ATECC608
Clé Privée (Slot 8)
mTLS
PUBLISH
m5go/env
:8883

Mosquitto

Terminal

Configuration
  • require_cert true
  • use_identity_as_username true
mTLS
SUBSCRIBE
m5go/env
:8883
RECEIVE
m5go/env
:8883

Subscriber M5Stack

Processeur Principal
ESP32
Bus I2C
SÉCURISÉ
ATECC608
Clé Privée (Slot 8)

Vidéo de Démo

Utilisez cet enregistrement comme un contrôle rapide (il complète, mais ne remplace pas, les commandes reproductibles et les captures).

Carte des Slots ATECC608B

Explorez l'agencement mémoire du Secure Element ATECC608B Trust&GO. Cliquez sur une zone pour inspecter sa configuration, ses politiques d'accès et son contenu.

Agencement Silicium (Logique)

Note : Configuration ATECC608B-TNGTLSU Trust&GO

Logique d'Implémentation

La séquence d'initialisation établit la sécurité complète en cinq étapes distinctes, de la vérification matérielle au handshake TLS final.

step_01_check.cpp
// 1. Scan I2C pour trouver l'ATECC608B (adresse par défaut 0x35)
Wire.beginTransmission(0x35);
if (Wire.endTransmission() == 0) {
  Serial.println("ATECC608 détecté à l'adresse 0x35.");

  // Initialisation de la librairie SparkFun
  if (atecc.begin(0x35, Wire, Serial)) {
    // Lecture des registres de configuration
    atecc.readConfigZone(false);

    // Vérification des verrous (Locks)
    if (atecc.configLockStatus && atecc.dataOTPLockStatus) {
      Serial.println("Puce verrouillée et prête à l'emploi.");
    } else {
      Serial.println("Attention : Puce non verrouillée.");
    }
  }
} else {
  Serial.println("Erreur : Secure Element introuvable.");
}
// Tableau contenant la longueur (2 octets) + la clé DER brute
// Exemple raccourci : [LEN_HI, LEN_LO, DER_BYTE_1, DER_BYTE_2...]
const uint8_t key_blob[] = { 0x00, 0x8A, 0x30, 0x81... };

size_t offset = 0;
uint8_t block = 0; // Index du bloc (0 à 12 pour le Slot 8)

// Boucle d'écriture tant qu'il reste des données et qu'on ne dépasse pas le Slot 8 (13 blocs)
while (offset < sizeof(key_blob) && block < 13) {
  uint8_t chunk32[32]; // Buffer de 32 octets
  memset(chunk32, 0, 32); // Initialisation à 0 (padding)

  // Copie par paquet de 32 octets max
  size_t toCopy = min((size_t)32, sizeof(key_blob) - offset);
  memcpy(chunk32, &key_blob[offset], toCopy);

  // Calcul de l'adresse : (Slot 8 << 3) | (Bloc << 8)
  uint16_t addr = (8 << 3) | (block << 8);

  // Écriture physique dans la zone DATA
  atecc.write(ZONE_DATA, addr, chunk32, 32);

  offset += toCopy;
  block++;
}
uint8_t slotData[416]; // Buffer pour stocker l'intégralité du Slot 8 (13 * 32 octets)

// Lecture séquentielle des 13 blocs du Slot 8
for (uint8_t b = 0; b < 13; b++) {
  
  // Calcul de l'adresse du bloc dans le Slot 8
  uint16_t addr = (8 << 3) | (b << 8);

  // Lecture via la librairie SparkFun (zone DATA, adresse, 32 octets)
  if (atecc.read(ZONE_DATA, addr, 32, false)) {
    
    // La librairie stocke la réponse dans inputBuffer[1..32]
    // Copie ces données dans le buffer global
    memcpy(&slotData[b * 32], &atecc.inputBuffer[1], 32);
  }
}
// slotData contient maintenant : [Longueur (2 octets)] + [Clé DER] + [Padding zéros]
// Récupération de la longueur de la clé (Big Endian sur les 2 premiers octets)
uint16_t derLen = (slotData[0] << 8) | slotData[1];

// Pointeur vers le début des données DER (juste après les 2 octets de longueur)
const uint8_t *derPtr = &slotData[2];

// Encodage du flux binaire DER en Base64 (fonction utilitaire)
String b64Key = base64Encode(derPtr, derLen);

// Construction de la chaîne PEM finale
String pemKey = "-----BEGIN PRIVATE KEY-----\n";

// Ajout du corps en Base64 (idéalement découpé tous les 64 caractères)
pemKey += b64Key;
pemKey += "\n-----END PRIVATE KEY-----\n";
WiFiClientSecure tlsClient;

// Injection des certificats publics (CA et Client) stockés en Flash
tlsClient.setCACert(ca_cert);
tlsClient.setCertificate(client_cert);

// Injection de la clé privée PEM récupérée dynamiquement depuis le Secure Element
// Note : La clé n'est jamais écrite "en dur" dans le code source
tlsClient.setPrivateKey(pemKey.c_str());

// Connexion MQTT sécurisée (Port 8883)
PubSubClient mqtt(tlsClient);
mqtt.setServer(MQTT_HOST, 8883);

if (mqtt.connect("m5stack-client-id")) {
  // Connexion TLS établie avec authentification utuelle (mTLS) réussie
}

Approfondissement Technique

Logique d'ingénierie derrière la gestion crypto du firmware.

DER vs PEM

Matériel DER

Binaire (0s & 1s). Optimisé pour l'efficacité de stockage sur silicium.

Logiciel PEM

Texte Base64. Requis par les en-têtes de la bibliothèque TLS ESP32.

Pourquoi une Longueur de 2 Octets ?

Les clés privées ECC varient légèrement en taille (~118-121 octets). Les slots de la puce sont des conteneurs à taille fixe.

Format Big Endian
[LEN_HI][LEN_LO][KEY_DATA.......][0000]

Nous préfixons la longueur pour que le firmware sache exactement où finissent les données et où commence le remplissage.

Pourquoi 13 Blocs ?

Contrainte matérielle : L'ATECC608B lit/écrit strictement par blocs de 32 octets.

Taille Slot 8 416 Bytes
13 Opérations 13 x 32B = 416B

Nous ne pouvons pas lire 'juste 5 octets'. Nous devons lire les blocs complets et les analyser en RAM.

Vérification en Direct

Nous avons validé le système contre les modes de défaillance physiques et cryptographiques courants. Voici la preuve de résilience :

1. Test de Falsification Physique

Scénario : Secure Element Déconnecté

Terminal output showing 'Error: Secure Element not found' when ATECC608B is disconnected.

Résultat : Arrêt immédiat. Le firmware sonde le bus I2C à l'adresse 0x35. Si l'ATECC608B ne répond pas, le dispositif refuse de poursuivre, empêchant toute connectivité réseau.

2. Test de Clonabilité

Scénario : Secure Element contenant un mauvais certificat.

Log proving connection rejection with 'Bad Signature' error when using unwed/cloned secure element.

Résultat : Connexion Rejetée. Le mauvais Secure Element branché génère une signature qui ne correspond pas à la clé publique enregistrée. Le broker renvoie bad signature et ferme le socket.

3. Vérification d'Identité

Scénario : Matériel Valide Présent

Terminal log showing successful mTLS handshake and MQTT connection with verified hardware.

Résultat : Authentifié. Le handshake TLS Mutuel réussit. Le broker vérifie le certificat et le SUBSCRIBE au topic m5go/env est acquitté.

4. Opération Système

Scénario : Publisher et Subscriber

Publisher and Subscriber showing successful end-to-end encrypted messaging via MQTT.

Résultat : Synchronisation Parfaite. Le Publisher (bas) pousse les données environnementales de manière sécurisée. Le Subscriber (haut) les reçoit instantanément via le canal chiffré.

Analyse des Menaces (STRIDE)

Avec l'implémentation du Secure Element, nous obtenons une Couverture Complète.

Usurpation (Spoofing)

Sécurisé
Défense

Clé stockée dans le Secure Element (bien qu'exportée en RAM dans ce labo).

Résultat

Nous pouvons prouver une liaison d'identité distincte à la puce (bien que l'extraction RAM soit un risque théorique).

Falsification (Tampering)

Sécurisé
Défense

Vérifications d'Intégrité TLS.

Résultat

Les attaques Man-in-the-Middle modifient les paquets, brisant la signature. Le broker coupe la connexion instantanément.

Répudiation (Repudiation)

Sécurisé
Défense

Clé stockée dans le matériel (Exportée en RAM ici).

Résultat

Preuve d'origine irréfutable. La signature cryptographique garantit que le message a été généré exclusivement par ce composant matériel unique.

Divulgation d'Info (Information Disclosure)

Sécurisé
Défense

Session chiffrée TLS.

Résultat

Les charges utiles sont opaques pour les sniffers réseau. La confidentialité est totalement préservée.

Déni de Service (Denial of Service)

Sécurisé
Défense

L'authentification mutuelle (mTLS) agit comme un filtre strict au niveau transport.

Résultat

Rejet précoce. Les connexions non autorisées sont coupées avant même d'atteindre et de saturer la logique applicative.

Élévation (Elevation of Privilege)

Sécurisé
Défense

Cloisonnement matériel des secrets.

Résultat

Même si un firmware est exploité (Buffer Overflow), l'attaquant ne peut pas extraire la clé permanente pour attaquer d'autres systèmes.

Limitations et considérations de sécurité

Passer de l'implémentation éducative au durcissement en production implique des choix architecturaux critiques. Comprenez ce que nous avons construit, et la suite.

Logique TLS Hybride

Dans ce labo, la clé privée est extraite en tant que chaîne et transmise à la pile logicielle. Cela démontre le Stockage Sécurisé mais manque l'étape finale d' Exécution Sécurisée.

Objectif Production

Utilisez PKCS#11 ou des callbacks ECDSA (HAL) pour que la clé privée ne quitte jamais le silicium. La signature de handshake se fait entièrement dans le Secure Element.

Exposition RAM Éphémère

Bien que la clé soit effacée du Flash, elle existe brièvement dans la RAM de l'ESP32 durant la séquence de démarrage avant d'être passée au moteur mTLS.

Atténuation

Remettre à zéro les buffers après usage et activer le Secure Boot ESP32 pour empêcher l'extraction de RAM.

Potentiel Sniffing I2C

Le bus I2C entre le MCU et le SE n'est pas chiffré. Un attaquant dédié pourrait théoriquement intercepter la clé durant la transmission I2C.

Durcissement Matériel

Contre l'écoute physique, préférez les pistes enterrées ou le chiffrement de bus. L'idéal reste le M5Stack Core2 AWS : son Secure Element interne supprime tout câblage vulnérable et confine la clé.

L'Architecture de Référence

En combinant un TLS Mutuel avec un Secure Element, nous atteignons un niveau de sécurité IoT très élevé.

Identité Inoubliable

La clé privée est générée en externe, stockée dans la puce, et relue pour utilisation. Le clonage nécessiterait d'extraire la clé depuis le bus I2C ou la RAM durant la séquence d'initialisation.

Isolation Matérielle

Même si le firmware est compromis (Buffer Overflow), l'attaquant ne peut pas toucher aux clés stockées dans l'élément cryptographique séparé.

Résistance à la Falsification

L'intégration de maillages actifs (Active Shields) et l'obfuscation du layout confèrent à l'ATECC608B une immunité contre l'ingénierie inverse et les attaques invasives.

Prêt pour la Production

Cette architecture répond aux exigences de notre cahier des charges. C'est une référence de l'industrie pour les dispositifs connectés sécurisés.

Conclusion

Prêt à reproduire ?

Vous avez exploré la théorie et l'architecture. Maintenant, suivez la procédure étape par étape pour construire ce système vous-même.