 Ja, dann herzlich willkommen aus der Übersetzer-Kabine. Ihr hört gleich Squeezing a Key through a Carry Bit. Also wir quetschen einen Schlüssel durch ein Übertrags-Bit. In der Kabine übersetzen für euch Flo, FL und Tribut. Und wir sehen gerade die Vorstellung auf der Bühne. Es geht um Philippo Valzorda, der uns erzählen wird über ein Bit, das auf Assemblalevel bei der P256 Kurve, die einem erlaubt, den privaten Schlüssel zu extrahieren. Also bitte ein herzliches Willkommen für Philippo Valzorda. Danke. Ich liebe den Term Kryptogopher. Ich möchte wiegen kann mit dem drauf. Mein Name ist Philippo, wie ihr gehört habt, arbeite ich an Infrastruktur, ich arbeite an Go, ich arbeite an Kryptografie. Und das hier ist eine Kooperation mit Sean Devlin. Ihr kennt ihn wahrscheinlich als ein der Autoren von Kryptopals, eine Serie von Krypto-Challenges. Vor einigen Monaten, in dieser Jahr, ein Cloudflare-Engineer hat Certific-Transparency-Logs angeschaut. Es sind Logs von SSL-Zertifikaten. Was er dort gemacht hat, ist, er hat die ECD-SA-Signaturen angeguckt und eigentlich diese Signaturen waren nicht wirklich schön definiert. Was eigentlich komisch ist, weil die Certific-Transparency-Logs die Einträge müssen eigentlich geprüft werden, bevor sie ins Log kommen. Das war also wahrscheinlich ein Fehler in der Software, die Cloudflare benutzt hat, in der Software, um die Certificate zu prüfen, wo sie eingetragen werden, in der Go Standard Library. Das weiß ich, es ist ein Fehler in der P265-Kurve von NIST, eine sehr schwierige zu implementieren, der Kurve für die ECD-Signaturen. Diese Kurve hat eine Assembler-Implementation in der Go Standard Library, um die volle Performance da rauszubekommen. Es ist besonders optimiert für X86-64-Richtigtoren. Das ist genau der, wo der Fehler lag. Es war ein Übertragungsfehler und wurde upstream gemeldet. Alle haben zugestimmt, dass es nicht offensichtlich ausnutzbar war. Aber es könnte ein cooles Paper werden. Wie kann man darauf verziesen? Sean und ich haben uns in Paris getroffen und während einer Woche ein bisschen Teilfood gegessen und diesen Assembler-Code angeguckt, eingestarrt. Und versuche herauszufinden, was tut das? Ein Monat später hatten wir ein CV und zwei neue Go-Releases. Wir haben es geschafft, diesen Back von einem einzeln Übertragungs-Bit zu einer vollen Schlüsselauslesefunktion zu bekommen. Im Diffy-Helmen-Ephemeral-Static. Wenn das noch nichts für euch, wenn euch das noch nicht sagt, dann macht das nix, da kommen wir nachher noch zu. Einer der Exploits ist in JWT, das hat 15 verschiedene Akronüme. Es ist auch implementiert in Go. Das heißt, es kann wirklich in Real-World-Implementation angewartet werden. Also fangen wir an, indem wir den Code mit diesem Bug angucken. Das hier ist die kurze Assembler-Funktion, die eine Subtraktion tut. In Mathematik mit elektrischen Kursen arbeitet man an einem Feld, eine elektrische Kursen mit einem Modulus in einer Primzahl. Also wenn man eine Subtraktion tut, man A-B, Modulo-P. Und das tut dieser Code, der setzt A zu A-B. Diese Zahlen sind in der Kriptographie natürlich viel so groß, um in ein einzelnes Register zu passen. Also wie? Wir rechnen wir, wenn wir das nicht in ein Register packen können. Wir machen das mit der multiprocesischen Math. Ihr wisst sicher alle, wie man das tut. Wenn ihr das in der Primarschule gelernt habt, und zwar schreibt man Zahlen in Spalten, und dann macht man Mathematik mit einer Registergröße von 10. Und für jede Zahl geht man aber zur nächsten Spaltung und überträgt sie in die nächste, wenn das nötig ist. Genau das, was dieser Code hier tut, er tut das einfach statt mit 10, mit 64 Zeichen pro Spalte. Und schauen wir uns mal die erste Spalte an. Die erste Spalte ist einfach nur abziehen, abziehen, abziehen oder übertragen. Und diese Übertragung ist dann gespeichert, diesen MUL-0-Archimulator. Was tun wir denn, wenn es negativ wird? Wir sagen, es muss ja dann MUL-0-P sein. Wir können das also nicht einfach über 0 rausgehen lassen. Es muss in die Registerbreite passen. Aber weil es eine arithmetische MUL-0-Zahl ist, können wir es einfach MUL-0 hinzurechnen und es muss dasselbe betun. Das heißt, wir können das aber dazurechnen und da geht es auch. Wir nehmen seinen Code P des Resultats und rechnen da einfach P dazu. Und das funktioniert sogar in konstanter Zeit. Und am Ende prüfen wir einfach ... Am Ende prüfen wir einfach welche von diesen beiden, also die subtrahierte Version oder die Originale wir benutzen und dann kriegen wir das Ergebnis. Und wenn man jetzt genauer hinschaut, dann sieht man den Back, der hier passiert. Gut, dafür muss man ... Assembler schon lesen können. Hier unten die Sachen, die sind konstante Zeit. Das heißt, es ist wichtig, dass das konstante Zeit ausgeführt wird, damit man nicht die Numere konstruieren kann. Und was man üblicherweise macht, ist, dass man 0 dazuzählt oder um sicherzustellen, dass diese Flex gesetzt sind. Aber das ist kein Hinzufügen, sondern das ist Hinzufügen mit Übertrag, also Add mit Carry. Das heißt, es addiert jetzt 0 auf Mulsiro und das Carry-Bit von der vorherigen Rechnung. Das hat aber nichts damit zu tun. Das heißt, dass da vorne das addiert P mit drauf, aber es ist völlig egal, ob das dann Überlauf gibt oder nicht. Denn das wird er sowieso nicht benutzt. Das heißt, es addiert hier ein zusätzliches Bit in die Operation, die das einfach hier nicht hingehört. Und dann werden aber auch unten die Bedingungen auch umgedreht. Das heißt, das sorgt dafür, dass das sich quasi wieder auffäht. Aber außer, dass Carry-Bit ist nicht gesetzt, also dieses Übertrags-Bit. Denn das ist dann genau der Fall, wenn hier dieses Carry-Bit eben nicht gesetzt wird. Das passiert nur alle zwei hoch 32-mal. Das heißt, das läuft eigentlich ganz gut. Es ist keinem aufgefallen, bis das dann in diesem einen CT-Lock, also diesen Certified Transparency-Lock aufgetaucht ist. Und da hatten sie quasi riesiges Glück, denn wer das dann nicht aufgepasst, wer das quasi nur vorübergehend mal aufgetreten, dann hätte man gedacht, da gut, vielleicht ist die Verbindung einfach kaputt gegangen. Und das ist ein Carry-Propagation-Buck, also ein Übertrags-Weiter-Verbreitungs-Buck. Und hier haben wir quasi nicht vergessen, den Übertrag mitzunehmen, sondern wir haben den Übertrag übertragen, den wir gar nicht hätten übertragen sollen. Und meistens funktioniert das gut und in wenigen Fällen geht es eben kaputt. Und wenn es kaputt geht, dann haben wir das falsche Ergebnis und halten die falsche Berechnung. Falsche Berechnung? Na ja, was soll das? Wie kann diese einzelne Eins jetzt noch irgendwie dazu führen, dass wir den kompletten Schlüssel wiederherstellen können? Das ist ja keiner von diesen klassischen Buckklassen wie ein Bufferoverflow, wo man weiß, was man machen soll. Wo man also durch eine ganze Menge von Möglichkeiten hat, um zum Beispiel Speicher zu überschreiben. Aber hier hat man praktisch gar keine Möglichkeiten. Und ich will das heute erklären, wie wir diesen sehr, sehr seltenen, fehlgeschlagenen Berechnung benutzen, um den kompletten Schlüssel wiederherzustellen. Und ich möchte mich aber zuerst entschuldigen, dass ich so einen ganz kurzen Crash Course über elliptische Kurven geben muss hier am CCC. Also wir haben das den allgebreichen Körper gesehen, also wir machen immer Operationen Modulo P, und dann gibt es Punkte, das sind XY-Werte, die zu einer Gleichung passen, die uns nicht interessieren. Das sind ganze Zahlen, das heißt, wir können mit denen arbeiten. Und wir können den benutzen, um eine Gruppe zu erzeugen. Eine Gruppe ist eine sehr elementare Struktur in moderner Kryptografie. Und um so eine Gruppe zu erzeugen, brauchen wir einen Nullpunkt, einen Erzeugerpunkt und eine Addition über die Punkte in der Gruppe. Also wir definieren eine Addition, und das interessiert uns gar nicht, wie die Addition funktioniert. Wir nehmen einfach zwei Punkte, wir addieren die, und wir kriegen ein Ergebnis. Und das hat alle Eigenschaften, die man aus der Grundschule kennt, komutativ, associativ. Und dann gibt es auch noch zusätzlich die Multiplikation. Wir definieren nicht wirklich, wie man einen Punkt multipliziert, aber wenn ich euch sage, wir haben hier eine zusätzliche Operation, und ich sage hier, ich hätte gerne fünfmal diesen Punkt. Na, was macht ihr? Ihr addiert den Punkt, und ihr addiert den Punkt, und so weiter, fünfmal. Und das nennt man Skalare-Multiplikation. Das funktioniert über wiederholte Additionen von einem Punkt. Und jetzt haben wir also quasi eine Gruppe, die erzeugt wird durch Multiplikation eines Erzeugerpunkts. Eine bestimmte Anzahl von Zeiten. Und wir haben eine Additionsoperation. Und wie machen wir darüber jetzt Kryptografie? Das ist ja noch alles sehr abstrakt. Und was wir machen ist, wir bauen elipte Curve-Diffie-Helmen, und ihr werdet jetzt, wenn ihr das normale Diffie-Helmen kennt, an einem bestimmten Punkt sehen, das passt alles wieder zusammen. Der private Schlüssel in eCDH ist einfach nur ein zufälliger, großer 256-Bit Wert. Und dann haben wir einen öffentlichen Schlüssel. Das ist genau dieselbe große Nummer. Multipliziert mit dieser Skalare-Multiplikation, die ich gerade gesagt habe, von so einem Generator-Punkt. Also, bei Diffie-Helmen entspricht das G hoch A. Und wenn nicht, dann ignoriert das einfach. Es geht nur, wir multiplizieren den privaten Schlüssel mit einem Punkt. Und wenn ich dann einen privaten Schlüssel und einen öffentlichen Schlüssel habe, und du schickst mir deinen öffentlichen Schlüssel, dann müssen wir ein gemeinsames Secret, ein öffentliches, ein geteiltes Geheimnis erzeugen. Und da nehme ich einfach deinen öffentlichen Schlüssel, und ich multipliziere es mit meinen privaten Schlüssel mit deinem Punkt. Und da kommt dasselbe raus, weil dein privater Key mal D ist dasselbe wie mein privater Key, weil D, das ist komotativ. Und das ist schon alles, was wir wissen müssen, um hier das zu verstehen. Aber es gibt noch eine Sache, die ich hier nicht weiter darauf eingegangen bin. Es ist leicht, mit fünf zu multiplizieren. Wir addieren einfach fünfmal. Aber wenn ich jetzt sage, multiplizieren wir mit einer 256-Bit-Nummer. Also, man kann das nicht zwei hoch 256-mal aufadieren. Also, was machen wir? Was wir versuchen, ist, wir wollen die Multiplikation, das privaten Schlüssel mal dem Punkt, dem öffentlichen Schlüssel. Also, wir nehmen den privaten Schlüssel und wir legen den hier bittweise hin. Und wir starten bei dem höchstwertigen Bit, das ist, also, Little India. Also, die Slide war am Anfang falsch, aber, also, seht ihr, ich behaupte einfach, ich habe es genau andersrum gemeint in Neustern. Das heißt, dieses Bit hier ist tatsächlich zwei hoch 256 Wert. Bzw. zu hoch 255, wenn wir das umändern, dann addieren wir 255. Zwei hoch 255. Und dann prüfen wir einfach dieses erste Bit, ist es gesetzt? Ja oder nein? Ja, also addieren wir diesen Punkt. Und cool ist dieser Punkt, den wir hier multiplizieren wollen. Und dann gehen wir einen Bit nach unten, indem wir es verdoppeln. Und wie verdoppeln wir? Wisst ihr, wie das geht? Wir haben ja nur Addition. Naja, wir addieren es auf sich selber drauf. Also, wir benutzen Addition, um den Punkt zu verdoppeln. Und ihr seht vielleicht schon, wo das hinführt. Wir multiplizieren es, also wir verdoppeln es jedes Mal, wenn wir einen Bit nach unten gehen. Und wie häufig haben wir dann also quasi am Ende verdoppelt, ja, 256 Mal. Das war ja quasi das Bit. Das war zwei Hoch 255 Wert. Und am Ende hat es dann also den Wert, den es haben soll. Und wir kommen zu dem Punkt und prüfen, ist der Punkt eins? Nein, wir machen gar nichts. Und wir verdoppeln, um runter zu gehen. Dann schauen wir wieder, ist das Bit eins? Wenn ja, dann, in dem Fall ist es eins. Also addieren wir den Punkt, verdoppeln, fügen den Punkt hinzu, verdoppeln und so weiter. Und so machen wir quasi weiter, bis wir, also wir haben hier noch ein paar Folien, bis wir beim niedrigstwertigsten Bit sind. Und am Ende müssen wir, haben wir das korrekte Ergebnis. Und das Resultat kommt von dieser Sequenz an Instruktionen, wo du höchstens zweimal 256 Instruktionen sind. Das können wir konkret tun. Wieso habe ich das jetzt so, diesen sehr spezifischen Algorithmus erklärt? Weil, um den Angriff zu verstehen, müsst ihr verstehen, dass jeder Schlüssel, also jede Kette von Bit in eine sehr spezifische Sequenz von Operationen umgewandelt werden kann. Wenn man ein Bit ändert, dann wird es genau eine zusätzliche Addition oder eine weniger Addition geben. Und jeder Schlüssel hat eine sehr spezifische Sequenz von Instruktionen, zum Beispiel hinzuwügen, verdoppeln, hinzuwügen, verdoppeln, hinzuwügen, verdoppeln und so weiter. Und zurück zum Back. Wenn ihr abgeschweift seid, weil ich ein bisschen viel Kriptografie erzählt habe, ich habe dich gesehen, dann komm zurück. Dann solltet ihr diese beiden Dingen mitnehmen. Es gibt einige große Nummer an den Privatschlüsseln. Wir wollen diese große Nummer diesen Privatschlüsseln mit einem Punkt multiplizieren. Wir wollen in einer Serie von Addition und Verdoppelung. Und diese Serie ist spezifiziert durch die Bits von dieser großen Nummer. Nur das müsst ihr wissen für den nächsten Teil. Gut, gehen wir zurück und schauen, wie wir das brauchen, um diesen sehr kleinen Übertragungsfehler in einem Dioconvirium zu wandeln. Wir spielen das hoch. Die Funktion, die kaputt geht, ist die P256.8 Subinternal. Diese Funktion wird benutzt von der Funktion P256.8. Das ist die Funktion, die Punkte addiert. Und um Punkte hinzuzufügen, das brauchen wir, wenn wir diese Scalar-Multiplikation machen, wenn wir multiplizieren, dieses D mal Q. Und wie wird Scalar-Mult benutzt? Und wir haben genau diese Stufe, auf der wir arbeiten können, wenn wir multiplizieren. Diese Operation sieht man in Elliptic Curve-Diffier-Helmen. Es gibt einen Scalar, das ist der geheime Schlüssel. Es gibt einen Punkt, der öffentliche Schlüssel, der anderen Person, also zum Beispiel das andere Eifer. Also Scalar-Mult, in diesem Fall, mit den Terminologien zu sprechen, hat ein definierten Scalar und ein Attacker-Supply ein Punkt vom Angreifer. Und das Secret ist der Session-Key. Zum Beispiel in TLS. Wenn du eine Verbindung erfuhr, mit ECDH, dann tun wir diesen Hanz, um einen Session-Key zu erzielen. Wenn der Session-Key korrekt ist, dann wird die Verbindung sich öffnen und wir können HDB-Request absetzen. Wenn der Back passiert ist und das Resultat falsch ist und das Resultat ein falsches Share-Secret erzeugt, dann ist der Session-Key falsch. Und wenn der Session-Key falsch ist, dann fällt das auf, weil die Verbindung unterbrochen wird. Das ist, was wir in Protografie ein Oracle nennen. Und dieses Oracle kann man anfragen und einen Punkt senden, weil das unser öffentlicher Schlüssel ist, also Angreifer. Wir senden diesen Punkt, und das Oracle wird multipliziert mit dem privaten Schlüssel des Oracles und es gibt ein Bitt an Informationen raus, und zwar wurde der Back ausgelöst oder nicht. Der größte Teil der Zeit wird es nicht ausgelöst werden, weil ihr erinnert euch, es ist ein extrem seltener Back. Wir haben ein Oracle, das uns sagt, der Back ist passiert oder nicht entsprechend zum Punkt, der gesendet wurde. Und sagen wir mal, der Key bleibt derselbe. Wenn die euch vorstellen, wie wir das benutzen, um Dinge über den Schlüssel zu lernen, sagen wir, wir können magisch ein Punkt heraufbeschwören der in dieser Sequenz von Operationen an einer sehr beziehbischen Stelle passiert. Und wenn wir einen anderen Punkt finden, bei dem der Punkt an einem anderen, aber auch interessanten, Bubble passiert, wenn wir gewisse Bits von dem Schlüssel schon kennen, was können wir dann tun mit diesen beiden Punkten? Wir senden sie beide. Eines davon wird die Verbindung unterbrechen. Das andere Punkt wird funktionieren. Das heißt, der Punkt, der funktioniert, hat den Back nicht ausgelöst, der den Unterbrich hat den Back ausgelöst. Und wir wissen, welche dieser Punkte mit welchen dieser Backs zusammenpasst. Weil wir genau entsprechende Punkte gebaut haben, die an der richtigen Stelle des Keys nur dann auslösen, wenn dort eine 1 oder 0 steht. Und in Cryptography ist das Prinzip, wenn du ein Bit des Schlüssel hast, die das wahrscheinlich ein Weg um an alle anderen Bits zu kommen. Und fangen wir an, haben wir die vier Bits auf der rechten Seite und wollen die beiden auf der Linken. Wir konstruieren zwei Punkte. Die Verbindung unterbricht, wenn die Multiplikation genau beim linken Bit passiert. Und ein, der nur dann auslöst, wenn dort keine Multiplikation ausgelöst wird. Dann senden wir beide und nur eine dieser Punkte unterbricht die Verbindung. Und dann wissen wir das erste Bit. Und dann gehen wir zurück. Wir gehen zurück zum magischen Punktegenerator und machen zwei neue Punkte. Diesmal schauen wir nicht für das erste Bit auf der linken Seite und kennen die anderen vier auf der rechten, sondern wir kennen die fünf auf der rechten. Wir gucken für das erste auf der neuen. Und wieder machen wir zwei Punkte. Eine unterbricht die Verbindung, der andere nicht. Und wir wissen ein Bit mehr. Und wir gehen wieder zurück zu unserem Generator, machen zwei Punkte, eine unterbricht die Verbindung, der andere nicht und so weiter. So machen wir weiter. Und wenn wir zurückgehen, passen wir uns an, verwenden die Bits auf der rechten Seite. Deshalb nennen wir das einen adaptiven Tag. Hier ist mal adaptieren wir uns um das, was wir wissen. Wir lernen und nutzen das Gewerbentrum. Das Schöne an diesen adaptiven Tags ist, sie sehen genau aus, wie wir in Hollywood filmen. Es ist wunderschön, weil die, die sieht, wie sie durch die Values durchgehen und ein Bit nach dem anderen wird Sichtfahren. Das habt ihr all gedacht, das sei falsch, ist es nicht. In diesen Attacken ist es wirklich so. Sonst ist das falsch. Dieser Angriff, wir dachten, als wir den erfunden haben, das ist etwas Extremes Neues. Und wir haben die Literatur angeguckt. Und jeder, der im Publikum und Akademiker ist, der weiß, was passiert ist. Wir haben Paper gefunden, das ist genau das Tat. Aber es war ein bisschen anders. Es war auf dieselbe Kurve, P256. Es war immer noch EC26. ECDH. Es ist wirklich ähnlich, aber es ist ein Angriff, der sehr, sehr on auf den Implementationsdetails bricht. Man kann nicht einfach deren Coach weiterverwenden. Die Idee ist dieser sehr adaktiver Angriff, der versucht zwei verschiedene Punkte. Das wurde schon in einem entsprechenden Paper dokumentiert und in diesem Fall gegen Open SSL. Und nicht gegen die Go Standard Library. Gut. Für den weiteren Verlauf sprechen wir deshalb jetzt darüber, wie genau wir das gegen Go implementiert haben. Weil unser Bug sehr, sehr spezifisch auf die Webseite ist. Die generelle Idee des Angriffs habe ich jetzt beschrieben. Wir definieren Punkte, senden beide zur selben Zeit und anhand jeden Punkt finden wir ein Bit. Aber ich habe euch ein bisschen angelogen und ich habe euch in verschiedenen Punkten ein bisschen angelogen. Weil das erste, was ich eingelogen habe, ist Go macht kein Double Add ein Bit at a time, sondern tut das mit fünf Bits in einmal. Statt ein Punkt oder 0 Punkte zu addieren und dann zu verdoppeln, addiert ist zwischen minus 16 und plus 16 und verdoppelt dann fünf Mal. Tut das einfach, in der Blöcke von fünf Bits. Also es nimmt diesen Schlüssel und da bricht ihn in die Blöcke von fünf Bits und verwendet dann Werte von einer vorberechneten Tabelle mit allen möglichen Werten von einem Punkt bis 16 Mal. In dieser Schleife verdoppelt es fünf Mal, weil es fünf Mal durchgeht und entscheidet sich erst dann, welchen dieser Punkte von 1 bis 16 aus dieser Multiplication Tabelle das es verwenden wird und fügt das zum laufenden Resultat dazu. Es gibt auch ein bisschen Konstanzzeit, weil das andere, was ich euch eingelogen habe, ist, es gibt kein 0 Punkt. Es ist ein eingebildeter Punkt, den wir verwendet haben, um die Mathematik zu offen zu bekommen. Aber wenn man diesen Punkt erreichen versucht, dann ist es ungefähr wie durch 0 zu dividieren. Das geht nicht. Was funktioniert, ist, 0 hinzuzubügen. Man tut einfach nichts. Wenn es also 0 ist, dann wird nichts hinzugefügt und wenn es nicht 0 ist, wird der entsprechende Wert in der Multiplication hinzugefügt. Das dritte, was wir tun, muss um die Lösung hinzukriegen, ist, dass jeder dieser fünf Bit-Blocke als ein einzelne Element eingeguckt haben, weil es viel einfacher ist, als mit jedem einzelnen Bit zu arbeiten. Das heißt, für diesen Talk schauen wir uns einfach jede Krone von fünf Bits als Glieder an, als Werte von 0 bis 15. Wenn ich einen Glieder wähle, dann ist es einfach ein fünf Bit Wert aus diesem Schlüssel, aus diesem riesigen D. Wie ändert sich dadurch der Angriff? Nicht wirklich großartig. Statt einen Bit anzugreifen, zwei Punkte, eins das kaputt geht, eins das nicht kaputt geht, müssen wir einen Glied aufs Mal angreifen. Eins das für 1, die Verbindung unterbricht, eins das für 2, die Verbindung unterbricht, eins für 3 und so weiter. Jeden dieser Werte. Um fünf Bits des Schlüssels hinzubekommen, haben wir den Angriff ausgelöst. Wir schauen immer noch, wir versuchen einen Bug zu finden, der genau am richtigen Punkt der Verdoppelung ausschlägt. Bei der richtigen Verdoppelung. Wir schauen immer noch, wie der Angriff ausgelöst wird. Wir schauen immer noch, wie der Angriff ausgelöst wird. Bei der richtigen Verdoppelung. Und wenn nie dann. Das ist auf einem hohen Level so, wie wir es machen, aber jetzt will ich euch erzählen, wie wir diesen Magic Point erzeugen, genau zur richtigen Zeit. Es gibt keine Spezielle Direktur, wie wir es machen. Es gibt keine Spezielle Direktur, wie wir es machen. Wir haben das Stabilisiering für den Bugs. Dann haben wir eine Rüggabe-Werte ausgelöst. Dann haben wir die einzelnen Glieder ausgerupt. Wir wollen immer wissen, was der Rückgabe-Wert für das nächste Glied sein wird. Wir wollen wissen, was der Rückgabe-Wert für das nächste Glied sein wird. Wir wollen wissen, was der Rückgabe-Wert für das nächste Glied sein wird. Die nächsten Glieds. und dann probieren wir alle möglichen Verteile für die eine, die wir nicht wissen. Wenn einer und nur einer den Bac getrickert hat, war das für uns eine nutzliche Information, weil wir genau wussten, mit welcher von uns bestimmten Wert der Bac getrickert wird. Okay, so... Es geht sogar mehr auf einen hohen Level. Jetzt wird es noch ein bisschen tiefer. Wir mussten natürlich eine große Menge von möglichen Kandidaten von denen wir dachten, dass wir den Privatkey nicht wissen. Aber wir wussten nicht, wie das ganze Protokoll funktioniert. Wir wussten nicht, wie das ganze Protokoll funktioniert. Wir haben deswegen von Multiplying einen neuen random Privatkey. Deswegen haben wir den Privatkey jedes Mal wieder ausprobiert. Wir haben vieler G, sondern eine Optimisation. Wir haben die various Assemblies der Standard-Librärie ausprobiert. Wir haben die Assemblerimplementierung der Standard-Libräre angeschaut. Ich werde es nie auf den Code-Review prüfen, aber ich liebe es. Wenn ich das im Code-Review sehen würde, würde ich das natürlich überhaupt nicht durchlassen. Aber ich finde es trotzdem cool, wie das programmiert ist. Hier drin seht ihr den Bac. Es gibt zwar false positives, aber hier ist der Bac drin. Gibt das Ergebnis Träger das Ergebnis im Bac? Nein, okay, false positives. Die einzige Sache, die wir noch nicht haben, ist, dass wir beim ersten Tug durch den Angriff Kommandos verstehen. Das erste ist das signaturese. Wir beginnen noch mit dem signifizierten Bit. Wenn man mit diesem Bit auch keine Ahnung von dem Key ist, ist das aber das Problem. Wir nehmen jetzt ein Beispiel, dass das Kern der Limb ist. Wir finden, dort hier ist ein Bac. Wir machen jetzt Fussing und wir finden einen Wert, der beim fünften Versuch den Backtrigger heisst das jetzt, dass das erste Glied 3 ist? Nein, falsch. Würde das auch heißen, dass das Glied 3 oder 12 wäre? Das Problem ist, 3 wird ausgesucht, das wird in der Commutation herbeverdockelt, dann kommt 6 raus. Noch mal 2, dann kommt 12 raus. Was ist der Fall? Wie lautet jetzt das, dass wir jetzt 4 mal artiert haben? 6 mal 5, das ist der Fall. Wir wissen immer noch nicht, was der Wert ist. Das sagt uns jetzt also gar nichts, dann das könnte 3, 6 oder 12 sein, dann 12 ist ja einfach nur 3, 2 mal verdoppelt. Und wenn wir es also nochmal verdoppeln, dann ist es immer noch kaputt. Wir wissen ja also nur, es geht kaputt, nicht an welcher Stelle. Das heißt, was wir also machen ist, wir finden jetzt 3 Punkte. Einer, der kaputt geht, wenn 3, 2 mal verdoppelt wird und einmal wenn er 4 mal und einmal 7 mal verdoppelt wird. Und wir schauen uns die alle an und gucken, welche kaputt geben. Also wenn nur der erste kaputt geht, dann ist es eine 3. Der zweite, aber nicht der dritte, ist es eine 6. Alle 3, dann ist es offensichtlich eine 12. Und das hat ewig gedauert, bis ich das in meinem Kopf irgendwie einsortieren konnte. Also ich kann jetzt schon spüren, dass ihr langsam müde werdet. Das ist sehr intensiv, da ist viel Mathematik mit drin. Also schauen wir uns mal was anderes an und reden wir über Kangaroos. Ich werde euch was über Kangaroos erzählen, was ich aus einem kryptografischen Paper gelernt habe. Ich schwöre, dass ich das da gelernt habe. Und es geht darum, wie Kangaroos springen. Und das hängt wohl davon ab, wie der Boden beschaffen ist, auf dem die Kangaroos springen. Je nachdem, wenn man zwei Kangaroos auf die exakt selbe Stelle stellt, dann werden sie dieselbe Entfernung und etwa die selbe Richtung weit springen. Ich weiß nicht, ob das richtig ist, aber Pollard hat das in einem Paper behauptet und mit dem diskutiere ich wirklich. Ja, und warum bringt uns das jetzt was Praktisches? Die Idee ist, wir haben einen sehr coolen Weg jetzt, um Kangaroos zu fangen. Nein, also es geht hier darum, Kangaroos zu fangen. Also wir nehmen einen Kangaroos, das man rumliegen hat, ihr habt ja alle ins Rumliegen, ihr macht ein GPS Checker ran und dann lasst ihr es frei. Und dieses Kangaro hüpft und läuft durch die Gegend und genießt seine Freiheit. Und zu einem bestimmten Punkt sammelt man es wieder ein, denn ihr wisst ja wo es ist und ihr macht da quasi eine Markierung hin, genau da wo ihr es gefunden habt. Was passiert denn mit einem Kangaro, was da nur vorbei läuft? Wenn es zu irgendeinem Zeitpunkt einen dieser Marker, wo das andere Kangaroo gehüpft ist, danach wird es denselben Fahrt folgen, denn jeder Sprung hängt ja nur davon ab, wie der Boden beschaffen ist. Und auf die Art und Weise, wenn das wilde Kangaroo auf einem der anderen Fußabdrücke landet, dann werdet ihr es auf jeden Fall finden, denn es wird auf jeden Fall in derselben Falle landen. Okay, das hatte jetzt mit dem Talk gar nichts zu tun, ich wollte das noch mal erzählen. Nein, natürlich nicht. Also hier, so hängt das jetzt mit Kryptografie zusammen. Wir können Punkte auf einer elliptischen Kurve so springen lassen wie Kangaroos. Also wir können die deterministisch ausschließlich auf den Input, also auf den Startpunkt. Also wir können zum Beispiel einen Hash nehmen, egal welchen, ihr könnt den selber designen. Das ist scheinbar in kryptografischen Währungen, ist es sehr populär, seine eigene Hashfunktion zu erzeugen. Okay, und man hascht einen Punkt auf einen anderen Punkt, und wenn man jetzt einen Sprung machen will, dann nimmt man einen Punkt und man addiert ihn auf seinen eigenen Hash hinzu. Also Qn plus 1 hängt jetzt nur von Qn ab. Und das ist genauso wie bei dem Kangaroo jetzt. Wie kann man das jetzt dafür benutzen, was wir hier machen wollen? Wir wollen P rekonstruieren, also wir wollen die Multiplikation der diskrete Logarithmus, sagt man häufig, des öffentlichen Schlüssel. Also wir nehmen jetzt ein gezähmtes Kangaroo, also einen Punkt, wo wir das P kennen und lassen das hüpfen und das hüpft vor sich hin. Und wir merken uns, was der Wert ganz am Ende ist. Und wir nehmen diesen Wert und speichern ihn. Wir müssen gar nicht alle Punkte zwischendrin aufheben, das reicht den letzten Punkt zu speichern, wir müssen da nicht viel im Speicher halten. Und dann nehmen wir den Punkt, wo wir das P eben nicht kennen und wir springen eine ganze Weile. Was passiert ist, dass es sehr viel höhere Wahrscheinlichkeit hat, dass es eine der Fußabdrücke des vorherigen Punktes zu treffen und wenn das tut, dann wird es am Ende in unserer Falle landen. Also es wird denselben Wert haben wie der Wert, den wir vorher ausgerechnet haben. Und wenn das passiert, dann wissen wir, wie weit der wilde Punkt gelaufen ist. Denn wir waren ja diejenigen, die die Springer ausgelöst haben. Das heißt, wir können jetzt zurücklaufen zum Startpunkt. Und das stellt sich raus, das ist eine sehr effiziente Variante, um den D-Wert zu finden. Also wenn wir in einem kleinen Bereich starten, dann wissen wir, wenn zu viel Zeit verlaufen ist, dann wissen wir, okay, dann ist es wahrscheinlich, keine von unseren Fallen erreicht und dann spulen wir einfach die Zeit zurück. In Krypto können wir das machen und starten wir woanders. Und diese Attacke, nennt man Pollard-Kenguru-Attacke, die ist in einem ursprünglichen Paper aus den 80ern beschrieben. Da ging es um Diffy-Helmen, aber es funktioniert bei allen Gruppen. Also funktioniert es auch auf elliptischen Kurven. Und es gab weitere Verbesserungen später in späteren Papers und einen Kapitel, wo es in dem elliptischen und hyperelliptischen Handbuch, wo das beschrieben ist. Also wir wissen jetzt, wie wir starten müssen, wir wissen, wie wir durchlaufen und wir wissen, wie es aufhört. Also lass uns das mal konkret betrachten. Also gucken wir, suchen wir uns mal einen Ziel. Also wie ich schon gesagt habe, dass diese Attacke funktioniert gegen JVT. Und JVT hat sehr viele fragwürdige Entscheidungen getroffen. Und eine davon ist, dass einer der Algorithmen für den öffentlichen Public Key Algorithmus ist, Diffy-Helmen, also nicht der, den wir sonst benutzen, wo wir quasi bei jedem, bei jeder Variante einen neuen Schlüssel aushandeln. Das macht diesen Attacke natürlich unmöglich, denn das ist ja ein adaptiver Angriff. Also ein Angriff, wo wir immer wieder und wieder den Angriff fahren müssen. Stattdessen machen die einen statischen Diffy-Helmen. Das heißt, eine von den beiden Seiten ist immer dieselbe. Das macht man als Optimierung, macht das auf gar keinen Fall. Auf dem SSL hat das ursprünglich gemacht, aber hat das mittlerweile aufgegeben, weil das dazu führen ein paar Attacke anfällig war. Und bei GOT TLS funktioniert das nicht, denn GOT TLS macht das richtig, aber JVT macht das, denn wenn der private Schlüssel fest ist, dann ist natürlich auch der öffentliche Schlüssel fest, dann ist natürlich auch der private Schlüssel fest. Das heißt, wir gucken uns hier den EC-DHA-Algorithmus an und wir können ihn benutzen, zum Beispiel gegen GOT JOSY. Das ist jetzt nicht die Schuld von GOT JOSY, aber es ist eine populäre Implementierung. Und GOT 181, die letzte Version, die noch verwundbar war. Und wir können einfach nur, ob der Dienst unsere Daten entschlüsseln kann. Das kann zum Beispiel daran liegen, dass es einen HTTP-Error ausgibt, wenn es das nicht kann, oder aufgrund von Timings, aufgrund von Inhalte von der Festplatte und so weiter. Alles, was wir brauchen, ist ein Orakel. Also, Abfragen zu können, hat der Bug ausgelöst, oder nicht? Also, haben wir recht bei der Vorhersage des Glieds, oder nicht? Und dann müssen wir natürlich eine ganze Menge Arbeit machen. Wenn ihr nicht die Ressourcen von einer großen Firma habt, dann könnt ihr auch einfach EC2-Spotinstances benutzen. Wie wir das eingerichtet haben, ist, es gab eine kleine Code, der nichts Intensives macht. Das kann man auf einem Laptop oder mit einem anderen Gerät laufen lassen. Das HTTP-Anfragen annimmt von den Arbeitern. Und das Schöne an dieser Infrastruktur ist, man kann das horizontal skalieren. Die kann also beliebig viele Worker starten auf non heterogenes, nicht heterogenen Plattformen. Denn das Einzige, was die machen müssen, ist, also die müssen keine Ports offen haben. Die müssen, man muss sich nicht über einen Natt sorgen machen. Man kann es im Prinzip auch auf dem Bordnet ausführen. Das Einzige, was die machen müssen, ist zurückverbinden und nach Arbeit fragen. Und nach 30 Sekunden oder wann auch immer sie einen Punkt gefunden haben, noch mal eine Verbindung aufbauen. Wenn ich habe was gefunden oder ich habe nichts gefunden, gibt mir mehr Arbeit. Und das ist auch deswegen praktisch, weil wenn man diesen Workercode falsch macht oder das irgendwas ändern will, dann kann man einfach die Worker nochmal neu starten oder woanders neu starten, ohne dass man den Zustand des Verteilers hier in dem Fall beeinflussen muss. Das bleibt erhalten. Das ist im Wesentlichen nur ein kleiner Skript, was EC2-Instanzen startet, weil wir da kein eigenes Image dafürstellt haben. Also ein paar Zahlen. Jeder Schlüssel hat 52 Glieder, das wird ein bisschen weniger brauchen am Ende, denn wir haben ja Kängurus, aber sagen wir ungefähr 52. Und jedes von diesen Gliedern enthält 16 Punkte im Mittelwert. Manche sind schneller, es sind eigentlich 17, aber manche sind schneller, zu machen, deswegen ungefähr 16. Für jeden Punkt brauchen wir ungefähr 26 Kandidatenpunkte. Das heißt, wir müssen 2 hoch 26 Punkte ausprobieren, bevor wir einen finden, der den Bug auslöst. Auf diesen richtigen Punkt. Nachdem wir also 16 solche Punkte brauchen und jeder braucht 2 hoch 26 Versuche, bedeutet das etwa 85 CPU Stunden, das heißt, eine Stunde, ein Einkehren für eine Stunde ist eine CPU Power. Und 85 CPU Stunden kostet ungefähr 1,4 Dollar, was also die Gesamtsumme, die uns diese Attacke kostet, etwa 60 Dollar. Und am Anfang hatte ich die Mathematik, also habe ich das falsch gerechnet, und hatte Angst, das könnte 1.000 Dollar kosten, aber ich hatte mich nur verrechnet. Ich bin nicht mutig genug, diese Attacke live auszuführen, das ist ja eine nette Infrastruktur, aber nein, das steht so sehr vertraue ich dem nicht. Aber es dauert auch eine Weile, und wenn man eine große Anzahl von EC2-Maschinen hochfahren will, dann braucht das eine Weile, also ich denke etwa 12 Stunden. Also ihr habt doch bestimmt noch eine 3.500 Zeit, oder? Dann werden wir also mal ein Video von der Mathematik anschauen. Das ist das UI von des EC2-Maschinen. Das ist das UI von des EC2-Maschinen. Das ist das UI von des EC2-Maschinen. Das soll jetzt nicht ganz so verwirrend sein. Und wenn jemand von euch das Lizenzieren will, dann können wir das im Talk gerne mal drüber reden. Was ihr hier an den Values rumseht, das sind die Werte, die die Workers gefunden haben und des EC2-Maschinen zu gemeldet haben. Und die grünen Werte sind die, also sie sind auf der rechten Seite. Sie erinnern uns, dass hier der Target ist, eine JWT-Receiving-Applikation. Und dann könnt ihr sehen, dass die Werte, die die Applikation von unten flippen. Und ihr seht, dass die Sonne nach grün, teilweise in Status auf grün wechseln. Und das ist ja genau wie immer noch. Und ihr seht unten, wenn sie gefunden werden, um die 30 Kandidaten zu arbeiten für jedes Limp, das wir finden. Für jedes Limp, das wir hier finden, das hat natürlich auch ein bisschen Glück, dann zu tun. Sobald wir das finden, meldet der Workers zurück. Das Ding, das läuft jetzt noch ein bisschen. Das Video, das läuft jetzt noch ein bisschen. Das Video, das läuft jetzt noch ein bisschen. Das war die Attacke. Ich habe das nicht geteut, das alles komplett anzunehmen. Den Code, leave the Limps, you lost, they belong to us now. Und für den Fall, dass ihr ein paar Glieder verloren habt, die gehören jetzt alle uns. Irgendwelche Fragen. Was ist auch noch, thank you very much for this lovely talk and the kangaroos. Herzlichen Dank für diesen großartigen Talk und es gibt eine Frage von den Signal Angels. Actually, the internet wants to know, did you compare this bug to implementation in other libraries? Ja, Antia, die Internet hat gefragt, hast du das mit anderen Implementierungen verglichen? We did not, also because each implementation is a bit different. Hanno works on a lot of fuzzing of begin implementations and he asked me, like on Twitter, if I tried fuzzing the go implementation for example. And sadly, this is constant time code that is specific to p256. So, the answer is, there's a lot of them and the bug can be small and anywhere. It's not like you will be looking for another bug in p256 subtraction. It can be anywhere in the underlying math and we can turn that into the same attack. So, no, we didn't look for this specific one. Aber nein, wir haben konkret nicht danach geschaut. Four CVEs in 2017 on OpenSSL have descriptions that are very similar, but they are about finite field if you have normal VH. If you look for something that says about it's barely doable because all the computation can be applied, that's this kind of attacks on OpenSSL. Next. Any other questions from the single angel? So please line up at the microphone, microphone one please. So, why can't you determine the points algebraically? Die Frage ist, warum kann man den Punkt nicht direkt rausfinden? It's entirely assembly and there's a lot of points where values then thrown out or like it might get corrected by how it's... Essentially, we didn't see a clear path to this and it's $65 on Institute. So, it doesn't really change the feasibility to just pass them. So, we just went for the fastest path to the entrance. Are there any other questions? No one is asking about kangaroos, people. Es gibt keine. Ich frage hier keine danach kangaroos. Hast du schon mal in Australien? Er sagt, er war nicht in Australien. Danke. Damit ist der Talk dann zu Ende. Wir verabschieden uns auch aus der Übersetzerkabine.