Au cœur de la faille Coldcard : ce qui a mal tourné et pourquoi un seed faible ne peut pas être corrigé

AnalysesBlock · 960 75810 min de lecture

Cette traduction a été réalisée avec l'aide de l'IA.

Ceci est une analyse. Elle interprète les événements et leur contexte et ne constitue pas un conseil financier.

La couverture du vol depuis Coldcard, traitée dans notre article d'actualité associé, répond à ce qui s'est passé. Cet article répond à la question plus difficile, le pourquoi, et à ce que cette réponse change dans la façon dont chacun devrait lire la promesse de sécurité d'un hardware wallet.

La version courte est gênante justement par son caractère ordinaire. Rien dans Bitcoin ne s'est cassé. Aucune courbe elliptique n'a été résolue, aucun secure element n'a été forcé, aucun attaquant n'a touché un appareil physique. Un unique réglage de compilation a discrètement envoyé l'une des opérations les plus sensibles qu'un portefeuille effectue vers le mauvais morceau de code, et il y est resté des années.

Commençons par ce qu'est vraiment un seed

Quand un portefeuille Bitcoin est créé, il tire un très grand nombre aléatoire. Chaque clé privée, adresse et signature que le portefeuille produira un jour descend de ce seul nombre, appelé le seed. La sécurité de tout le portefeuille repose sur une seule propriété de ce nombre : que personne d'autre n'aurait pu le deviner.

La mesure de la difficulté à deviner un nombre s'appelle l'entropie, comptée en bits. Un seed de douze mots est censé porter 128 bits d'entropie. Ce nombre n'est pas du marketing. Il décrit un espace de seeds possibles si vaste que le parcourir n'est pas seulement coûteux, c'est physiquement hors de portée, plus proche du comptage des atomes que de l'exécution d'un programme.

C'est toute la raison d'être d'un hardware wallet. Sa tâche centrale, au-dessus de l'écran, de l'air-gap et de la puce sécurisée, est de choisir ce nombre dans l'espace entier et non parcourable. S'il le choisit dans un espace plus petit, tout ce qui est bâti au-dessus hérite de la faiblesse, et aucune des autres fonctions ne peut compenser.

Le bug : un réglage, la mauvaise branche

Coinkite a conçu la Coldcard pour utiliser un générateur de nombres aléatoires matériel, une source physique de bruit sur la puce. En 2021, l'entreprise a déplacé sa cryptographie Bitcoin vers la bibliothèque libsecp256k1 de Bitcoin Core, un choix solide utilisé par Bitcoin Core lui-même. Cette migration a introduit une bibliothèque d'appoint, libngu, et a réacheminé la génération du seed de l'ancien chemin matériel vers un nouvel appel, ngu.random.bytes().

C'est là que le câblage a dérapé. Pour décider quelle source aléatoire compiler, le code vérifiait un réglage nommé MICROPY_HW_ENABLE_RNG. Coinkite avait mis cette valeur à zéro, avec l'intention de désactiver le générateur intégré de MicroPython et d'utiliser le sien. La vérification employait une forme qui teste seulement si le réglage existe, pas s'il est activé. Comme le réglage existait, même mis à zéro, la compilation a silencieusement lié la génération du seed au repli logiciel de MicroPython au lieu de la source matérielle.

Ce repli est un générateur pseudo-aléatoire, une formule qui produit une sortie d'apparence aléatoire à partir d'une valeur initiale. Sur les Mk2 et Mk3, cette valeur initiale provenait surtout de l'identifiant unique de la puce et de ses registres de minuterie. Ces entrées ont l'air aléatoires mais sont fixes ou étroitement bornées, ce qui explique pourquoi Coinkite estime désormais l'espace de recherche effectif à environ 40 bits plutôt que 128.

Pour un attaquant, 40 bits ne sont pas un mur, c'est une liste de tâches. L'espace est assez petit pour être parcouru avec une puissance de calcul ordinaire, en dérivant des seeds candidats, en comparant chacun à des adresses connues et en gardant ceux qui contiennent des fonds. Une adresse publique ou une clé publique étendue indique à l'attaquant, à l'instant même, si une tentative était correcte, ce qui explique précisément pourquoi une entropie faible dans un portefeuille est bien plus dangereuse qu'une entropie faible dans la plupart des autres logiciels.

Pourquoi les modèles plus récents ont aussi été touchés, mais moins

Pendant le développement de la Mk4, Coinkite a mélangé de l'aléa supplémentaire provenant de deux secure elements dans l'état du générateur, comme une réserve de réserve. C'est pourquoi les Mk4, Mk5 et Q sont moins exposées que la Mk3. C'est aussi pourquoi elles ne sont pas sûres.

D'après l'analyse de Block, le reseed ne remplaçait qu'un mot de 32 bits de l'état interne du générateur, de sorte que, pour un état de repli et un historique d'appels fixes, l'appareil produisait au plus environ quatre milliards de flux de sortie distinguables. Coinkite situe l'espace de recherche qui en résulte autour de 72 bits. Mieux que 40, toujours très en dessous de l'objectif de 128 bits, et toujours à la portée d'un attaquant motivé. L'entropie supplémentaire a relevé le mur sans jamais combler la brèche.

Pourquoi des années de revue ne l'ont pas vu

Le détail qui devrait rester à quiconque construit ces appareils ou leur fait confiance, c'est à quel point la défaillance a été silencieuse. Le générateur matériel correct et le repli logiciel erroné avaient la même signature de fonction, si bien que la compilation s'est terminée sans se plaindre. Les relecteurs pouvaient confirmer que le code matériel prévu était présent dans le binaire du firmware, et avoir raison, sans remarquer que le chemin du seed ne l'atteignait jamais vraiment.

La faille n'était pas une ligne de cryptographie fautive qu'un lecteur attentif aurait pu repérer. C'était une question de savoir laquelle de deux fonctions d'apparence identique l'éditeur de liens reliait, deux couches plus bas dans un sous-module. C'est une chose vraiment difficile à saisir en lisant le code, et c'est une mise en garde contre le fait de traiter un audit comme un simple tampon de réussite ou d'échec.

L'intrigue secondaire de la licence, et le poids qu'elle peut porter

Il y a une seconde histoire autour de ce bug, et elle mérite d'être racontée avec prudence plutôt que comme un verdict. Le PDG de Foundation Devices, Zach Herbert, a exposé une chronologie. En juillet 2020, Foundation a annoncé son portefeuille Passport, bâti sur le firmware Coldcard qui était alors sous la licence de logiciel libre GPLv3. Le fondateur de Coinkite s'y est publiquement opposé. Coinkite est ensuite passée à une licence plus restrictive de type source available et, en mars 2021, a livré un gros commit qui supprimait le dernier code GPL.

Ce même commit d'environ 120 fichiers est l'endroit où la génération du seed a changé et où le chemin aléatoire défectueux est entré. Herbert présente le bug comme un possible dommage collatéral de cette réécriture.

Lue comme une interprétation de l'auteur, la coïncidence de calendrier est difficile à ignorer : le différend sur la licence a été le déclencheur visible de la réécriture, et la réécriture est là où la faille est née. La lecture inverse et honnête compte tout autant. Coinkite a déclaré que la même migration poursuivait de vrais objectifs techniques, avant tout l'adoption de libsecp256k1 de Bitcoin Core, et rien ne prouve que le changement de licence à lui seul ait causé le bug. Une réécriture de cette taille peut introduire un défaut subtil pour des raisons sans rapport avec celle qui l'a lancée. Cette lecture s'affaiblirait nettement s'il s'avérait que la vérification défectueuse précise était antérieure au commit de mars 2021, ou apparaissait dans un changement sans lien avec le travail sur la licence.

Ce que la faille coûte réellement à l'utilisateur

La conséquence la plus importante est aussi la moins intuitive. Un seed généré par un firmware concerné ne peut pas être réparé.

Mettre à jour le firmware n'aide pas, car la mise à jour ne change que la façon dont les seeds futurs sont créés. Réimporter le même seed dans une nouvelle Coldcard, une BitBox ou un Trezor n'aide pas non plus, car la faiblesse est à l'intérieur du seed lui-même et le suit. Réinitialiser l'appareil et restaurer les mêmes mots ne fait rien. La seule voie décrite par Coinkite est de générer un seed réellement nouveau sur un firmware corrigé et de déplacer les fonds vers de nouvelles adresses qui en dérivent.

Deux mesures d'atténuation adoucissent le tableau sans le corriger. Coinkite indique qu'un seed créé avec au moins cinquante lancers de dés indépendants et privés n'est pas à risque du seul fait de ce problème, car l'utilisateur a fourni une entropie que le firmware ne pouvait pas saper. Et une passphrase forte et unique, le secret optionnel qui se combine aux mots du seed pour produire un portefeuille distinct, oblige l'attaquant à deviner ce secret en plus du seed faible. Les deux achètent de la sécurité ou du temps. Aucune ne restaure l'aléa manquant, et c'est pourquoi le seed sous-jacent doit tout de même être remplacé.

Le récit qui a subi les vrais dégâts

Pendant des années, la Coldcard a été vendue en partie sur son caractère air-gapped, c'est-à-dire qu'elle ne se connecte jamais à un ordinateur par USB et déplace les données via une carte MicroSD ou des codes QR. Dans certaines parties de la communauté Bitcoin, cela s'est durci en une affirmation plus simple, à savoir que les portefeuilles air-gapped sont le choix sûr et, en pratique, impossibles à pirater.

Ce cas est une démonstration nette de pourquoi ce raccourci a toujours été trop fort. L'air-gap a fait son travail. Aucune donnée n'a fui par un câble, et l'attaquant n'a jamais eu besoin de l'appareil, car la faiblesse a été gravée dans le seed au moment de sa création. Un vide dans le câblage ne vaut rien quand le nombre en dessous était prévisible dès le départ.

Un portefeuille doit bien faire beaucoup de choses à la fois : générer un seed vraiment aléatoire, stocker les clés en sécurité, afficher honnêtement les détails de la transaction, vérifier ses propres mises à jour, implémenter la cryptographie proprement, résister aux attaques physiques et protéger sa chaîne d'approvisionnement. « Pas d'USB » ou « secure element » décrit une propriété de cette liste, pas la liste entière. Il y a même une petite ironie ici, notée par Coinkite elle-même : l'air-gap est en partie la raison pour laquelle l'appareil ne pouvait pas tirer d'entropie supplémentaire d'un hôte connecté, une source sur laquelle d'autres conceptions s'appuient.

C'est ici qu'un point structurel gagne sa place, offert comme raisonnement et non comme instruction. Les conceptions qui mêlent plusieurs sources d'entropie indépendantes, afin qu'un seul composant défectueux ne puisse pas décider à lui seul du résultat, sont plus robustes précisément face à cette catégorie de défaillance à point unique. C'est un argument sur l'architecture, pas sur le produit que quiconque devrait acheter, et il ne vaut que ce que vaut, en pratique, la propreté de la combinaison de ces sources.

La partie qui ne disparaîtra pas

Deux fils font de tout ceci plus qu'un bug corrigé. Coinkite a déclaré supposer qu'un attaquant a utilisé un modèle d'IA pour examiner son firmware ouvert et faire remonter la faille, et que sa propre revue assistée par IA quelques semaines plus tôt l'avait manquée. Les mêmes outils sont désormais assis des deux côtés de la table. Et l'usage par l'opérateur d'un compte payant chez un fournisseur de données blockchain, que Block a retracé grâce aux propres journaux du fournisseur, est le genre de trace opérationnelle ordinaire qu'un attaquant prudent aurait évitée, et la piste la plus solide pour l'instant pour les enquêteurs.

La leçon qui demeure n'est pas qu'une entreprise a échoué à un test. C'est que la sécurité de l'auto-conservation est une chaîne qui va du tout premier nombre aléatoire jusqu'à la dernière ligne sur l'écran, et qu'un portefeuille mérite d'être jugé sur la chaîne entière, pas sur le seul mot imprimé en plus gros sur la boîte.

Sources

  1. 1.Block Engineering: Predictable RNG Fallback and 32-Bit Reseed in Coldcard Firmware
  2. 2.Coinkite: Technical Deep Dive into the Entropy Issue
  3. 3.Zach Herbert (Foundation Devices) on the firmware and licensing timeline
  4. 4.CryptoSlate: A flaw in Coldcard seed generation lets attackers recreate private keys
  5. 5.Bitcoin Magazine: Coinkite releases fixed firmware after Coldcard bug; AI likely involved
  6. 6.CoinDesk: How bitcoin cold wallets lost $70 million in an attack that never touched the devices