Dentro la falla di Coldcard: cosa è andato storto e perché un seed debole non si può correggere

AnalisiBlock · 960.75810 min di lettura

Questa traduzione è stata realizzata con l'assistenza dell'IA.

Questa è un'analisi. Interpreta gli eventi e il loro contesto e non costituisce una consulenza finanziaria.

Il resoconto del furto da Coldcard, trattato nella nostra notizia di accompagnamento, risponde a cosa è successo. Questo articolo risponde alla domanda più difficile, il perché, e a cosa cambia quella risposta nel modo in cui chiunque dovrebbe leggere la promessa di sicurezza di un hardware wallet.

La versione breve è scomoda proprio per quanto è ordinaria. Nulla in Bitcoin si è rotto. Nessuna curva ellittica è stata risolta, nessun secure element è stato violato, nessun aggressore ha toccato un dispositivo fisico. Una singola impostazione di compilazione ha silenziosamente inviato una delle operazioni più sensibili che un wallet compie attraverso il pezzo di codice sbagliato, e lì è rimasta per anni.

Partiamo da cosa è davvero un seed

Quando si crea un wallet Bitcoin, questo estrae un numero casuale molto grande. Ogni chiave privata, indirizzo e firma che il wallet produrrà discende da quell'unico numero, chiamato seed. La sicurezza dell'intero wallet poggia su una sola proprietà di quel numero: che nessun altro avrebbe potuto indovinarlo.

La misura di quanto è difficile indovinare un numero si chiama entropia e si conta in bit. Un seed di dodici parole dovrebbe portare 128 bit di entropia. Quel numero non è marketing. Descrive uno spazio di seed possibili così grande che percorrerlo non è soltanto costoso, è fisicamente fuori portata, più vicino al contare atomi che all'eseguire un programma.

È l'intera ragione per cui esiste un hardware wallet. Il suo compito centrale, prima dello schermo, dell'air-gap e del chip sicuro, è scegliere quel numero dall'intero spazio non percorribile. Se lo sceglie da uno spazio più piccolo, tutto ciò che vi è costruito sopra eredita la debolezza, e nessuna delle altre funzioni può compensare.

Il bug: un'impostazione, il ramo sbagliato

Coinkite ha progettato la Coldcard per usare un generatore di numeri casuali hardware, una sorgente fisica di rumore sul chip. Nel 2021 l'azienda ha spostato la propria crittografia Bitcoin sulla libreria libsecp256k1 di Bitcoin Core, una scelta solida usata dallo stesso Bitcoin Core. Quella migrazione ha introdotto una libreria di supporto, libngu, e ha reindirizzato la generazione del seed dal vecchio percorso hardware a una nuova chiamata, ngu.random.bytes().

È qui che il cablaggio è andato storto. Per decidere quale sorgente casuale compilare, il codice controllava un'impostazione chiamata MICROPY_HW_ENABLE_RNG. Coinkite aveva impostato quel valore a zero, con l'intenzione di disattivare il generatore integrato di MicroPython e usare il proprio. Il controllo usava una forma che verifica solo se l'impostazione esiste, non se è attivata. Poiché l'impostazione esisteva, anche impostata a zero, la compilazione ha silenziosamente legato la generazione del seed al fallback software di MicroPython invece che alla sorgente hardware.

Quel fallback è un generatore pseudocasuale, una formula che produce output dall'aspetto casuale a partire da un valore iniziale. Su Mk2 e Mk3 quel valore iniziale proveniva per lo più dall'identificativo univoco del chip e dai suoi registri di temporizzazione. Quegli input sembrano casuali ma sono fissi o strettamente delimitati, ed è per questo che Coinkite stima ora lo spazio di ricerca effettivo a circa 40 bit anziché 128.

Per un aggressore, 40 bit non sono un muro, sono una lista di cose da fare. Lo spazio è abbastanza piccolo da poter essere percorso con una normale potenza di calcolo, derivando seed candidati, confrontando ciascuno con indirizzi noti e tenendo quelli che contengono fondi. Un indirizzo pubblico o una chiave pubblica estesa dice all'aggressore all'istante se un tentativo era corretto, ed è esattamente perché un'entropia debole in un wallet è molto più pericolosa di un'entropia debole nella maggior parte degli altri software.

Perché anche i modelli più recenti sono stati colpiti, solo meno

Durante lo sviluppo della Mk4, Coinkite ha mescolato ulteriore casualità da due secure element nello stato del generatore, come riserva di una riserva. È per questo che Mk4, Mk5 e Q sono meno esposte della Mk3. Ed è anche il motivo per cui non sono sicure.

Secondo l'analisi di Block, il reseed sostituiva solo una parola da 32 bit dello stato interno del generatore, quindi per uno stato di fallback e una cronologia di chiamate fissi il dispositivo produceva al massimo circa quattro miliardi di flussi di output distinguibili. Coinkite colloca lo spazio di ricerca risultante intorno ai 72 bit. Meglio di 40, ancora molto al di sotto dell'obiettivo di 128 bit, e ancora alla portata di un aggressore motivato. L'entropia aggiuntiva ha alzato il muro senza mai chiudere il varco.

Perché anni di revisioni non l'hanno notato

Il dettaglio che dovrebbe restare a chiunque costruisca questi dispositivi o si fidi di essi è quanto silenzioso sia stato il guasto. Sia il generatore hardware corretto sia il fallback software sbagliato avevano la stessa firma di funzione, così la compilazione si è conclusa senza proteste. I revisori potevano confermare che il codice hardware previsto era presente nel binario del firmware, e avere ragione, senza accorgersi che il percorso del seed non lo raggiungeva mai davvero.

La falla non era una riga di crittografia sbagliata che un lettore attento potesse individuare. Era una questione di quale di due funzioni dall'aspetto identico il linker collegasse, due livelli più in basso in un sottomodulo. È una cosa davvero difficile da cogliere leggendo il codice, ed è un monito contro il trattare un audit come un singolo timbro di promozione o bocciatura.

La sottotrama della licenza, e quanto peso può reggere

C'è una seconda storia attorno a questo bug, e merita di essere raccontata con cautela anziché come un verdetto. L'amministratore delegato di Foundation Devices, Zach Herbert, ha ricostruito una cronologia. Nel luglio 2020 Foundation ha annunciato il suo wallet Passport, costruito sul firmware Coldcard allora rilasciato sotto la licenza di software libero GPLv3. Il fondatore di Coinkite ha obiettato pubblicamente. Coinkite è poi passata a una licenza più restrittiva di tipo source available e, nel marzo 2021, ha rilasciato un grande commit che rimuoveva l'ultimo codice GPL.

Quello stesso commit di circa 120 file è il punto in cui la generazione del seed è cambiata ed è entrato il percorso casuale difettoso. Herbert inquadra il bug come possibile danno collaterale di quella riscrittura.

Letta come interpretazione dell'autore, la coincidenza temporale è difficile da ignorare: la disputa sulla licenza è stata l'innesco visibile della riscrittura, e la riscrittura è dove è nata la falla. La lettura contraria e onesta conta altrettanto. Coinkite ha dichiarato che la stessa migrazione perseguiva obiettivi tecnici reali, in primo luogo l'adozione di libsecp256k1 di Bitcoin Core, e non ci sono prove che il cambio di licenza da solo abbia causato il bug. Una riscrittura di quelle dimensioni può introdurre un difetto sottile per ragioni che non hanno nulla a che vedere con il motivo per cui è stata avviata. Questa lettura si indebolirebbe parecchio se emergesse che lo specifico controllo difettoso precedeva il commit del marzo 2021, o compariva in una modifica senza alcun legame con il lavoro sulla licenza.

Cosa costa davvero la falla all'utente

La conseguenza più importante è anche la meno intuitiva. Un seed generato da firmware interessato non può essere riparato.

Aggiornare il firmware non serve, perché l'aggiornamento cambia solo il modo in cui vengono creati i seed futuri. Reimportare lo stesso seed in una nuova Coldcard, in una BitBox o in un Trezor non serve, perché la debolezza è dentro il seed stesso e viaggia con esso. Resettare il dispositivo e ripristinare le stesse parole non fa nulla. L'unica strada descritta da Coinkite è generare un seed davvero nuovo su firmware corretto e spostare i fondi su nuovi indirizzi da esso derivati.

Due mitigazioni ammorbidiscono il quadro senza risolverlo. Coinkite afferma che un seed creato con almeno cinquanta lanci di dadi indipendenti e privati non è a rischio per questo problema da solo, perché l'utente ha fornito entropia che il firmware non poteva compromettere. E una passphrase forte e unica, il segreto opzionale che si combina con le parole del seed per produrre un wallet separato, obbliga l'aggressore a indovinare quel segreto oltre al seed debole. Entrambe comprano sicurezza o tempo. Nessuna delle due ripristina la casualità mancante, ed è per questo che il seed sottostante va comunque sostituito.

La narrazione che ha subito il vero danno

Per anni la Coldcard è stata venduta in parte per il suo essere air-gapped, cioè non si collega mai a un computer via USB e sposta i dati tramite una scheda MicroSD o codici QR. In parti della comunità Bitcoin questo si è indurito in un'affermazione più semplice, e cioè che i wallet air-gapped sono la scelta sicura e di fatto non violabili.

Questo caso è una chiara dimostrazione del perché quella scorciatoia sia sempre stata troppo forte. L'air-gap ha fatto il suo lavoro. Nessun dato è trapelato via cavo, e l'aggressore non ha mai avuto bisogno del dispositivo, perché la debolezza era impressa nel seed nel momento della creazione. Un vuoto nel cablaggio non vale nulla quando il numero sottostante era prevedibile fin dall'inizio.

Un wallet deve fare bene molte cose contemporaneamente: generare un seed davvero casuale, conservare le chiavi in modo sicuro, mostrare i dettagli della transazione con onestà, verificare i propri aggiornamenti, implementare la crittografia in modo pulito, resistere agli attacchi fisici e proteggere la propria catena di fornitura. "Niente USB" o "secure element" descrive una proprietà di quella lista, non l'intera lista. C'è persino una piccola ironia qui, notata dalla stessa Coinkite: l'air-gap è parte del motivo per cui il dispositivo non poteva attingere entropia aggiuntiva da un host collegato, una sorgente su cui altri progetti si appoggiano.

È qui che un punto strutturale trova il suo posto, offerto come ragionamento e non come istruzione. I progetti che mescolano più sorgenti di entropia indipendenti, così che un singolo componente difettoso non possa decidere da solo l'esito, sono più robusti proprio contro questa classe di guasti a punto singolo. È un argomento sull'architettura, non su quale prodotto si dovrebbe comprare, ed è valido solo quanto è pulita, nella pratica, la combinazione di quelle sorgenti.

La parte che non se ne andrà

Due fili rendono tutto questo più di un bug corretto. Coinkite ha dichiarato di presumere che un aggressore abbia usato un modello di IA per esaminare il proprio firmware aperto e far emergere la falla, e che la sua stessa revisione assistita da IA di poche settimane prima l'avesse mancata. Gli stessi strumenti ora siedono su entrambi i lati del tavolo. E l'uso da parte dell'operatore di un account a pagamento presso un fornitore di dati blockchain, che Block ha tracciato attraverso i log del fornitore stesso, è il tipo di traccia operativa ordinaria che un aggressore attento avrebbe evitato, ed è la pista più forte al momento per gli investigatori.

La lezione che resta non è che un'azienda abbia fallito un esame. È che la sicurezza dell'autocustodia è una catena che va dal primissimo numero casuale fino all'ultima riga sullo schermo, e che un wallet merita di essere giudicato sull'intera catena, non sull'unica parola stampata più grande sulla scatola.

Fonti

  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