Stölden tog 41 minuter
Den 30 juli gick någon igenom 1 196 bitcoinadresser och tömde dem på 1 082,65 bitcoin till ett värde av omkring 70,2 miljoner dollar, i ett fönster på 41 minuter. Ingen dyrkade upp ett lås. Ingen enhet vidrördes, ingen användare lurades, ingen server forcerades. Angriparen behövde inget av det, eftersom de privata nycklar som skyddade adresserna gick att räkna fram från grunden. De första rapporterna satte förlusten nära 38 miljoner dollar; när forskarna räknat färdigt landade siffran på nästan det dubbla.
Enheterna som berördes var Coldcard-maskinvaruplånböcker tillverkade av Coinkite, alltså just den produktkategori man köper för att hålla nycklar borta från nätverk. Det är detta som gör händelsen värd en timmes uppmärksamhet från vilken ägare som helst, oavsett vad denne anser om bitcoin. Haveriet inträffade inte vid den yttre gräns som alla budgeterar för. Det inträffade i det ögonblick hemligheten skapades, år innan någon försökte stjäla den.
Ett makro satt till noll slog på reserven
Coinkites egen tekniska redogörelse är ovanligt uppriktig om mekanismen. I mars 2021 leddes fröskapandet, under en migrering till Bitcoin Cores libsecp256k1, bort från den rutin som anropade enhetens maskinvarugenerator för slumptal och över till en allmän funktion. Den nya vägen landade i MicroPythons programvarureserv i stället för i Coldcards maskinvaruimplementering. Reservkoden hade funnits sedan maj 2018 och hade aldrig rört fröskapandet förrän vid just den migreringen.
Skälet till att den alls kompilerades in hör hemma på er egen kontrollista. Vakten kring reserven prövade om ett konfigurationsmakro var definierat, inte om det var satt till ett. Utvecklarna hade satt det till noll i betydelsen att maskinvarugeneratorn inte behövdes där, och ett makro satt till noll är fortfarande ett definierat makro. Vakten läste värdets närvaro i stället för värdet självt, och slog på reserven. Ingen skrev svag kryptografi. Maskinvarugeneratorn fanns och fungerade. Den var bara inte längre det som fröet drogs ur.
Fem år gick och varje test förblev grönt
På Mk2- och Mk3-enheter med programvara 4.0.1 till 4.1.9 bar de framställda fröna omkring 40 bitars entropi i stället för de 128 som en tolvordsfras ska ha. På Mk4, Mk5 och Q var bilden bättre men inte säker: ingenjörer hade blandat in värden från säkerhetselementen i generatorns tillstånd som, med Coinkites uttryck, en reserv för reserven, vilket lyfte de fröna till ungefär 72 bitar. Båda talen är katastrofala på samma sätt. Slump går inte att se. En nyckel med 40 bitar bakom sig signerar transaktioner, verifierar adresser och återställs från säkerhetskopia precis som en med 128, så varje funktionstest som företaget och dess kunder körde under fem år godkändes, med rätta, medan produkten var trasig.
Coinkite lämnar dessutom en detalj som de flesta leverantörer hade begravt. För några veckor sedan, skriver bolaget, använde det en av de bästa tillgängliga AI-modellerna för att granska sin egen kod efter säkerhetsproblem, och den hittade inte detta fel. Det är värt att dröja vid innan nästa leverantör berättar att deras kod har granskats av en modell. Defekten var i efterhand varken subtil eller dold, men den bodde i skarven mellan en byggkonfiguration och ett kryptografiskt antagande, alltså exakt den söm som en granskare inriktad på kodkvalitet minst sannolikt behandlar som en säkerhetsgräns.
Rättningen skyddar nästa nyckel, inte den förra
Coinkite släppte den 31 juli rättad programvara för varje berörd modell och gren: 4.2.0 för Mk2 och Mk3, 5.6.0 för Mk4 och Mk5, 1.5.0Q för Q samt motsvarande edge-byggen. Därefter publicerade bolaget den mening som väger tyngre än rättningen. En uppdatering av den fasta programvaran ändrar eller lagar inte ett befintligt frö. Anvisningen är att installera den rättade programvaran, skapa ett nytt frö på den uppdaterade enheten, skriva ner och kontrollera dess säkerhetskopia innan något sätts in, bekräfta en ny mottagaradress på enhetens skärm, skicka en liten testtransaktion och först därefter flytta återstående medel.
Detta är en migrering och inte en uppdatering, och i den skillnaden ligger hela lärdomen. Två saker kunde rädda en plånbok skapad under det berörda fönstret: femtio oberoende, privata tärningskast inmatade via enhetens egen tärningsfunktion, eftersom Coldcard räknade in dem i fröet, eller en stark och unik lösenfras som står som en egen barriär framför det svaga fröet. Coinkite uppmanar ändå även frasskyddade användare att migrera så snart det är praktiskt möjligt. TAPSIGNER, OPENDIME och SATSCARD vilar på andra kodbaser och är inte berörda.
Inventera det ni framställde, inte bara det ni kör
Nästan varje lappningsprocess en ägare har godkänt behandlar programvaruversionen som riskenhet. Man får veta att en version är sårbar, uppdaterar den, och exponeringen upphör. Entropidefekter bryter den modellen helt, eftersom skadan inte sitter i den körande koden utan i föremål som koden gav ifrån sig och räckte över: nycklar, tokens, sessionsidentifierare, återställningskoder, API-hemligheter, certifikat. Dessa föremål överlever den version som skapade dem, vandrar in i säkerhetskopior och tredjepartssystem och bär svagheten med sig för gott. Att uppdatera generatorn stoppar tillverkningen av dåliga hemligheter. Det gör ingenting åt lagret.
Frågan till varje leverantör vars produkt skapar hemligheter för er räkning är alltså inte bara vilka versioner som är berörda. Den är vilka hemligheter som framställdes på en berörd version, hur man räknar upp dem och hur bytesvägen ser ut. Det gäller långt utanför maskinvaruplånböcker: HSM:en i betalningskedjan, certifikatutfärdaren, linjen för enhetsutrullning, identitetsleverantören som ger ut långlivade tokens. Överallt där en maskin präglar något ni sedan förlitar er på är det defekta fönstret det som ska inventeras, och nästan ingen för bok över det.
Läs vidare: Tre firmor avgör om din telefon förblir billig | Siemens och Schneider kom med den 22 juli



