Dans un objet connecté, l'élément sécurisé (ou secure element / HSM) est le coffre-fort. C'est lui qui détient les clés cryptographiques, prouve l'identité de l'appareil et protège les communications. Quand cet élément est une puce propriétaire, fermée, sans documentation publique, l'utilisateur — et le régulateur — est contraint de faire confiance sur parole au constructeur. C'est exactement la situation de la puce MJA1 de Xiaomi, présente dans ses caméras récentes.
C'est cette boîte noire que Mengsi Wu, chercheuse chez Quarkslab, a entrepris d'ouvrir. Sa publication du 18 juin 2026, relayée par l'analyste Denis Laskov (@it4sec), constitue les premiers détails techniques publics sur le composant. C'est un cas d'école de recherche en boîte noire : chaque bribe de connaissance sur l'appareil doit être acquise au cours même de la recherche. Aucune documentation, aucun SDK, aucun schéma, aucune carte de développement — rien, hormis quelques brochures commerciales.
La démarche est remarquable parce qu'elle inverse la logique habituelle de l'audit : ici, il faut d'abord reconstruire le manuel de l'appareil avant de pouvoir évaluer sa sécurité. Cette première étape — la collecte de connaissances — est précisément ce que documente la recherche.
| Chercheuse | Mengsi Wu (Quarkslab) |
| Relayé par | Denis Laskov (@it4sec) — Substack, 18 juin 2026 |
| Publication | Blog Quarkslab — 18 juin 2026 |
| Cible | Puce sécurisée Xiaomi MJA1 (modèle MJA1 C06CW) — élément sécurisé / HSM propriétaire |
| Fonction | Protection des données et communications des caméras et objets connectés Xiaomi |
| Boîtier | DFN 2×3-8 (Dual Flat No-lead, 2 × 3 mm, 8 broches) |
| Interface | I2C — adresse esclave 0x2A (broches SCL + SDA) |
| Appareils étudiés | Xiaomi Outdoor Camera BW300, Camera Base Station, Smart Camera C301 (accès root) |
| Méthodologie | Black-box : identification matérielle, sniffing I2C, dump flash, RE firmware, brute-force de commandes |
| Outils clés | PCBite + analyseur logique, programmeur TNM5000, Raspberry Pi 3 B+ (SPI), binwalk / unblob / SquashFS |
| Résultats | 9 commandes documentées + 2 cachées (0x06 Update, 0x13 inconnue) · format de trame & CRC-16/X-25 reconstitués · frontière de confiance validée |
| Verdict (à ce stade) | Aucune faille protocolaire évidente côté hôte — les clés privées ne quittent jamais la puce |
| CVE assigné | Aucun — première étape de recherche (collecte de connaissances) |
Pourquoi la recherche black-box ?
Auditer un produit dont on possède la documentation, le code source et les schémas est déjà un travail exigeant. Le faire sans rien relève d'un autre registre. La puce MJA1 affiche des promesses fortes — protection matérielle, résistance au rejeu, au MITM et à la force brute, clé privée et certificat uniques par exemplaire — mais ces affirmations ne sont, en l'état, vérifiables par personne d'autre que Xiaomi. Avant cette recherche, le seul élément public était une photographie issue d'un autre projet de rétro-ingénierie.
L'objectif de Mengsi Wu était donc double : comprendre comment fonctionne réellement la puce, puis évaluer si ses propriétés de sécurité tiennent leurs promesses. La méthode suit une progression rigoureuse : du silicium vers le protocole, du matériel vers le logiciel.
Identification de la cible
Le choix de l'appareil obéit à trois critères : intégrer la puce MJA1, rester abordable (moins de 50 à 100 €), et permettre — en dernier recours — d'intercepter les mises à jour de firmware via l'application mobile si le dump matériel échouait.
Deux appareils ont finalement été acquis pour le prix d'un seul : la Xiaomi Outdoor Camera BW300 (60 €) et la Xiaomi Camera Base Station (30 €). Tous deux embarquent la MJA1 et interagissent ensemble, ce qui permet de comparer deux cibles, d'identifier la plus accessible et de croiser les observations. Une troisième caméra, la C301 (sur laquelle un accès root était disponible), servira plus tard à la phase de test actif.
Analyse matérielle
Localiser et identifier la puce
Après ouverture des appareils et inspection des circuits imprimés, la puce a été repérée sur chaque carte : le même modèle MJA1 C06CW dans les deux cas. Elle se présente dans un boîtier DFN 2×3-8 : sans broches saillantes, deux millimètres sur trois, huit contacts seulement. Minuscule — et donc délicate à sonder.
Écouter la conversation : sniffing I2C
Pour observer le dialogue entre le processeur principal et la MJA1, la chercheuse a utilisé un montage PCBite couplé à un analyseur logique, dont les pointes se posent sur le pas de 0,5 mm des broches. Sur les huit broches, la plupart restent figées (alimentation ou masse) : seules deux montrent un échange de données actif.
Deux broches actives seulement, échangées de façon bidirectionnelle et synchrone : la signature est sans ambiguïté. Ce n'est ni de l'UART (deux broches mais asynchrones), ni du SPI (au moins quatre broches), mais de l'I2C — une ligne d'horloge (SCL) et une ligne de données (SDA). Le décodeur I2C intégré révèle l'adresse de la puce sur le bus : 0x2A.
Détail savoureux : la séquence d'octets capturée passivement (0x05 0x00 0x03 0x00 0x02 0x00 0x08 0x58 0xEF) s'avérera être une commande READ — la même qui sera décodée en détail plus loin. Le sniffing donne le transport (I2C, adresse 0x2A), mais pas encore la structure des commandes. Pour cela, il faut extraire le firmware de l'hôte.
Extraire la mémoire flash
Les deux appareils embarquent des mémoires flash différentes. La Base Station utilise une MD25Q128, prise en charge par le programmeur universel TNM5000 : dump immédiat. La BW300, elle, embarque une NAND SPI Winbond 25N01KVZEIR (1 Gbit, boîtier WSON 8×6) non supportée par le programmeur — il a donc fallu improviser.
La solution : un Raspberry Pi 3 B+ câblé directement aux broches de la flash via une breadboard. Le Pi parle SPI au composant, lit son identifiant JEDEC pour confirmer le modèle, puis dumpe l'intégralité de la NAND page par page.
Analyse du firmware
Retrouver le code qui parle à la puce
Avec binwalk, unblob et les outils SquashFS, les systèmes de fichiers ont été extraits des deux firmwares. Sans surprise, aucun code propre à la puce n'y figure : l'élément sécurisé exécute son propre firmware, jamais exposé à l'hôte. En revanche, le code côté hôte qui dialogue avec la puce devait s'y trouver.
Une recherche de chaînes de caractères fait apparaître un préfixe récurrent — mjac (pour MJA Chip) — dans le binaire miio_client. MIIO désigne l'ensemble de protocoles et le SDK propriétaires développés par Xiaomi pour son écosystème IoT. C'est ce binaire qui orchestre la communication I2C avec la MJA1.
miio_client est un exécutable MIPS 32 bits lié dynamiquement à uClibc — typique d'un Linux embarqué. Il a été dépouillé de ses en-têtes de sections (ce qui complique la rétro-ingénierie), mais, heureusement, les noms de fonctions ont été conservés dans la table des symboles. On y identifie notamment : mjac_init (initialise l'I2C), la famille mjac_cmd_build_<cmd> (construit les commandes), mjac_resp_parse_data (analyse les réponses) et mjac_crc16_ccitt (calcul d'intégrité).
Neuf commandes reconstituées
En analysant la famille mjac_cmd_build_*, chaque identifiant de commande a pu être associé à sa fonction :
| ID | Commande | Catégorie |
|---|---|---|
| 0x00 | Echo | Utilitaire |
| 0x02 | Generate random | Utilitaire |
| 0x05 | Read | Accès aux données |
| 0x0D | Hibernate | Utilitaire |
| 0x11 | Generate key | Cryptographie |
| 0x14 | Query | Accès aux données |
| 0x16 | Generate signature | Cryptographie |
| 0x17 | Verify signature | Cryptographie |
| 0x18 | Establish key | Cryptographie |
Trois familles se dégagent : des commandes utilitaires (test de communication, génération d'aléa cryptographique, mise en veille), des commandes d'accès aux données (lecture de zones, interrogation d'informations comme le numéro de série) et des opérations cryptographiques (génération de paire de clés ECC éphémère pour ECDH, dérivation de secret partagé, signature et vérification).
Décoder le format d'une trame
Reconstituer ce tableau a été moins direct qu'il n'y paraît. Même avec les noms de fonctions, chaque mjac_cmd_build_<cmd> empile ses arguments dans une structure aux décalages magiques, calcule un CRC sur une plage précise et renvoie une longueur variable. La commande Establish key (0x18) illustre bien la grammaire :
- octet 0 : identifiant de commande (
0x18) ; - octet 1 : constante
0xFFau sens incertain ; 0x45octets suivants : la charge utile ;- CRC16 calculé sur les
0x47premiers octets, ajouté en deux octets little-endian ; - longueur totale :
0x49octets (1 + 1 + 0x45 + 2).
Reconstituer le CRC
Aucune trame valide ne peut être envoyée sans une implémentation exacte du mjac_crc16_ccitt. Le nom suggère un CRC-16/CCITT « standard », mais il en existe quantité de variantes (polynôme, valeur initiale, réflexion des bits, XOR final). La lecture du code décompilé a permis d'identifier les quatre paramètres : table inversée, polynôme 0x8408 (forme bit-reversed du 0x1021 canonique), initialisation à 0xFFFF, résultat final inversé. Soit la variante CRC-16/X-25 (alias CRC-16/IBM-SDLC) — précisément pas celle vers laquelle on se tourne spontanément quand on entend « CRC-16/CCITT », d'où la nécessité de la dériver du code plutôt que de la deviner.
Validation croisée
Ce n'est qu'après tout ce travail qu'un dépôt GitHub public a été découvert — iomonad/handshow-firmware — appartenant à un appareil tiers qui embarque le SDK Mijia BLE de Xiaomi et contient le code source d'un wrapper MJA1. Le trouver plus tôt aurait épargné beaucoup d'efforts, mais il a surtout permis de confirmer la liste de commandes et de combler les derniers détails sur les arguments et les codes de réponse.
Lecture, zones et frontière de confiance
La commande Read (0x05) sélectionne une zone, un offset et une longueur, avec validation par CRC16. Les zones accessibles révèlent la logique de confiance de la puce :
- index 0 : certificat de l'appareil ;
- index 1 : certificat du fabricant ;
- index 2 : certificat racine ;
- index 3 : données produit ;
- index 4 : données utilisateur.
Chaque réponse comporte un statut (0x00 OK, 0x01 CRC invalide, 0x02 arguments invalides, 0x04 commande non supportée, 0x06 longueur trop grande…), une longueur, les données et un CRC.
Tests actifs
Jusque-là, tout était passif. Pour aller plus loin, il fallait émettre ses propres commandes. La caméra C301 rootée a servi de banc d'essai. Un petit programme C dialogue directement via l'interface I2C de Linux : ouverture de /dev/i2c-0, sélection de l'adresse esclave, puis envois et lectures de trames.
Autour de ce noyau, une table de dispatch associe chaque commande à un constructeur dédié, offrant une petite interface en ligne de commande pour les tests interactifs (lecture d'une zone, interrogation de la puce, envoi de trame arbitraire pour le fuzzing).
miio_client), la cause profonde n'a jamais été trouvée. Les commandes ont donc dû être envoyées une par une.
Brute-force des identifiants de commande
L'étape suivante : chercher des commandes cachées que miio_client ne référence pas. En parcourant tous les identifiants possibles (0x00 à 0xFF) avec un CRC valide, et en observant le code de réponse, on distingue les commandes absentes (réponse « commande non supportée ») des autres. Pour contourner le blocage après chaque commande, un contrôleur Python automatise le cycle complet : connexion SSH à la caméra, exécution du test, capture de la réponse, redémarrage si la puce est figée, attente du retour en ligne, puis commande suivante.
Deux commandes absentes de la liste extraite de miio_client ont ainsi été découvertes :
0x06→ Update : écrit des données dans une zone ;0x13→ inconnue : renvoie systématiquement un code d'erreur non documenté0x0F.
La 0x13 est la plus intrigante : elle ne répond pas « non supportée » mais par une erreur personnalisée, signe qu'elle existe et est partiellement gérée, mais qu'une condition manquante l'empêche de s'exécuter. Une cible de choix pour du fuzzing ciblé.
Malgré son nom, la commande Update n'a rien à voir avec une mise à jour de firmware : elle écrit dans une zone, avec validation CRC16. Surtout, les tests confirment que seule la zone de données utilisateur (index 4) est modifiable. Les certificats (appareil, fabricant, racine) et les données produit sont en lecture seule, immuables depuis l'hôte. La puce applique donc une protection en écriture stricte là où elle compte.
Ce que la recherche établit — et ce qui reste à faire
Partant d'une puce sans aucune documentation, la recherche a identifié son interface, dumpé et rétro-conçu le firmware hôte, reconstitué le format complet des trames (y compris la variante exacte du CRC) et exploré tout l'espace des identifiants pour débusquer deux commandes cachées. Vu du bus, la puce se comporte correctement : certificats et données produit en lecture seule, clés privées jamais exposées, écritures cantonnées à la zone utilisateur, arguments malformés rejetés. Aucune faille évidente au niveau protocolaire.
Mais, comme le souligne la recherche, le protocole n'est que la porte d'entrée. Ceci n'est que la première étape de la recherche black-box — rassembler la connaissance ; la suivante consiste à tester réellement la sécurité du composant. Plusieurs pistes sont ouvertes :
- Dessoudage et test isolé de la puce sur une carte dédiée pilotée par microcontrôleur, pour lever la limitation du redémarrage et permettre un fuzzing complet — notamment de la mystérieuse
0x13. - Injection de fautes (glitch de tension, impulsion EM, glitch d'horloge) : que se passe-t-il si une faute est injectée précisément au moment où la puce vérifie l'index de zone d'une commande
Read? Le contrôle pourrait-il être contourné pour lire hors des zones autorisées — jusqu'à la mémoire interne ou les clés privées ? - Analyse par canaux auxiliaires (consommation, émissions EM) : les opérations ECC (génération et établissement de clé, signature) sont des cibles classiques pour récupérer du matériel de clé privée.
C'est là que commence le travail le plus intéressant — et le plus difficile.
Un enjeu de gouvernance : la confiance ne se décrète pas
Le cas MJA1 cristallise une tension structurelle de la sécurité des objets connectés. Un élément sécurisé est la racine de confiance de tout l'appareil : s'il tombe, toute la sécurité s'effondre. Or ici, cette racine est une boîte noire propriétaire. Le constructeur affirme qu'elle résiste au rejeu, au MITM et à la force brute — mais, jusqu'à cette recherche, personne d'extérieur ne pouvait le vérifier.
La sécurité par l'obscurité (pas de documentation, pas de SDK) n'est pas, en soi, une faiblesse : un secure element bien conçu n'a pas besoin de divulguer ses entrailles. Le problème est ailleurs : en l'absence de toute transparence, la seule contre-expertise possible vient de chercheurs indépendants qui acceptent d'acheter des appareils, de les ouvrir et d'en reconstituer le manuel. C'est précisément ce que démontre Mengsi Wu — et c'est aussi ce que vise la trajectoire réglementaire récente.
Le Cyber Resilience Act impose aux produits comportant des éléments numériques une sécurité dès la conception, une gestion documentée des vulnérabilités et une traçabilité des composants. Pour les éléments sécurisés, la voie de référence est la certification (Common Criteria / schéma européen EUCC), qui soumet la puce à une évaluation indépendante par un laboratoire agréé (un CESTI, en France). La question légitime que pose ce travail : la MJA1 a-t-elle fait l'objet d'une telle évaluation publique ? À défaut, l'affirmation de sécurité repose sur la seule parole du fabricant.
Les caméras connectées, sonnettes vidéo, stations de base domotiques et autres équipements de maison intelligente se diffusent rapidement sur le continent — pour la sécurité résidentielle, la surveillance de commerces, le suivi logistique. La quasi-totalité de ces appareils est importée, embarque des composants propriétaires fermés comme la MJA1, et arrive sans aucune évaluation locale.
Le risque tient en une asymétrie : ces appareils captent des flux extrêmement sensibles — images de l'intérieur des domiciles, des commerces, des sites — et leur sécurité repose sur des racines de confiance que ni l'utilisateur, ni l'importateur, ni le régulateur national ne peuvent auditer. Si l'élément sécurisé est défaillant ou contournable par injection de fautes, c'est tout le flux vidéo et toute l'identité de l'appareil qui sont en jeu.
Pour les autorités d'homologation et de régulation — ARCEP, ANRT, ARTP, NCA et leurs homologues — qui intègrent progressivement des volets cybersécurité dans le contrôle des équipements, ce type de recherche est un argument concret : la conformité radio (Wi-Fi, fréquences) ne dit rien de la robustesse de l'élément sécurisé. Reconnaître les certifications d'éléments sécurisés (EUCC, Common Criteria), ou exiger une preuve d'évaluation indépendante pour les équipements traitant des données sensibles, devrait figurer dans les grilles d'homologation.
C'est aussi un enjeu de souveraineté numérique : tant qu'il n'existe pas, sur le continent, de capacité d'évaluation matérielle indépendante — un laboratoire capable de sniffer un bus, de dumper une flash, de mener une injection de fautes — l'Afrique reste contrainte de faire confiance sur parole à des composants qu'elle ne peut pas ouvrir. Bâtir cette capacité d'expertise est précisément l'un des chantiers stratégiques de la cybersécurité des équipements connectés et radio.
Ce qu'il faut retenir
La recherche de Mengsi Wu pose des questions pratiques immédiates :
- Les équipements connectés sensibles (caméras, contrôle d'accès) déployés par l'organisation s'appuient-ils sur des éléments sécurisés certifiés (EUCC / Common Criteria), ou seulement annoncés comme sécurisés ?
- Le fournisseur peut-il produire une preuve d'évaluation indépendante de sa racine de confiance ?
- L'analyse de sécurité va-t-elle au-delà du protocole, jusqu'à la résistance physique de la puce (injection de fautes, canaux auxiliaires) ?
- Les procédures d'homologation nationales reconnaissent-elles les schémas de certification d'éléments sécurisés ?
- Existe-t-il une capacité locale, même embryonnaire, d'évaluation matérielle indépendante des équipements importés ?
Conclusion
La force de cette recherche n'est pas d'avoir trouvé une faille spectaculaire — elle n'en revendique aucune au niveau protocolaire. Elle est d'avoir démontré, méthodiquement, qu'une boîte noire n'est noire que tant que personne n'a la patience de l'ouvrir. À partir de rien — pas de documentation, pas de SDK, pas de schéma — Mengsi Wu a reconstruit le manuel d'un composant que son fabricant gardait fermé, et a posé les fondations d'une évaluation de sécurité sérieuse.
Pour la sécurité des objets connectés, la leçon est double. D'une part, un élément sécurisé bien conçu peut tenir ses promesses côté protocole : la MJA1 ne laisse pas fuiter ses clés privées, et c'est à porter à son crédit. D'autre part, la confiance ne devrait jamais reposer sur la seule affirmation du constructeur : elle se vérifie, par la certification indépendante ou par la recherche. Tant qu'un composant critique reste une boîte noire opaque, la bonne question n'est pas « est-il sûr ? », mais « qui l'a vérifié, et avec quels moyens ? ».
Sources & références
- Mengsi Wu (Quarkslab) — « Black Box Probing: a Security Analysis of Xiaomi's MJA1 Secure Chip » Blog Quarkslab · 18 juin 2026 — recherche originale : identification matérielle, sniffing I2C, dump flash, rétro-ingénierie du firmware, brute-force des commandes, propriétés de sécurité. Toutes les illustrations de cet article en sont issues.
- Denis Laskov (@it4sec) — veille relayant la recherche MJA1 Substack · 18 juin 2026 — mise en contexte de la recherche black-box et de ses prochaines étapes.
- iomonad/handshow-firmware — code source d'un wrapper MJA1 (SDK Mijia BLE) GitHub — dépôt tiers ayant permis la validation croisée de la liste de commandes et des arguments.
- Winbond — datasheet de la NAND SPI W25N01KV Winbond — brochage et spécifications de la mémoire flash dumpée sur la caméra BW300.
- Catalogue CRC — CRC-16/X-25 (IBM-SDLC) reveng — référence des variantes de CRC-16, dont la variante exacte reconstituée à partir du firmware.
- Quarkslab — page de contact / audits de sécurité Quarkslab — laboratoire de sécurité à l'origine de la recherche.