 zwischen Details von embedded microprocessors. Er hat seit 30 Jahren schon akademische Paper publiziert, veröffentlicht und ja bitte herzlich willkommen für Alistar Raid. Vielen Dank für die Einführung und ich spreche über den ARM Prozessor und die sind unglaublich weitverbreitet in Telefonen, Tablets, in anderen Geräten, in Festplatten, sind überall und wenn man darüber nachdenkt ist von allen, man vertraut ihn seine privaten Daten an und es ist ganz ganz wichtig, dass sie genau das tun, was sie tun sollten und nichts anderes und wir müssen wirklich sicher sein, dass wir es genau verstehen, wie sie funktionieren und ob Melware und Verwundbarkeiten vorhanden sind und so weiter. Und ich rede über Arbeit, die ich vor sechs Jahren begonnen habe und es gibt um eine sehr genaue Spezifikation von ARM Prozessoren zu erstellen und ich werde auch darüber reden, was im April, im April hat er am die Spezifikation veröffentlicht in Maschinenlesbaraform und ich sollte vielleicht sagen, ich habe mit der Universität zusammengearbeitet, um das fertig zu stellen und in diesem Vortrag rede ich vor allem über diese ausführbare Prozessospezifikation, das wird der größte Teil sein, aber am Ende auch noch über formal verifizierte Software, also auf diesem Kongress ist es vielleicht besser über Sachen zu sprechen, die wir wirklich machen können. Die Spezifikation, die ARM veröffentlicht hat und da sind ganz viele Beschreibungen von Instruktionen und ganz viele sehr interessante Security-Sachen, Speicherschutz, Exceptions, Privilege-Kontrollen und so weiter und es gibt viele interessante Sachen und wie man die Geräte sicher macht und auch dann sicher ist, dass alles sicher ist und zeige ich ganz viele Links, ihr könnt die Spezifikation runterladen direkt auf dem ersten Link, aber bitte erst nach dem Vortrag und es gibt auch die in HTML die Spezifikation von den Herstellern und viele nützliche Informationen, Blocks und Papers und fangen wir einfach an mit der eigentlichen Spezifikation. Das erste ist, alle wirklich wichtigen Security-Features in dem Prozessor werden kontrolliert von den System Control Vectors und mit den Registers und ein sehr wichtiges SC-TLA und es spricht sich ganz einfach, SC-TLA sind, da gibt es ganz viele verschiedene Control-Bits, die entweder Optimierung betreffen oder auch Security-Features und hier ist zum Beispiel eine, um das mal zu zeigen, worüber wir hier reden. Hier sind einige Dokumente über WXN-Bad und der stellt sicher, dass der Stack kein Code enthalten kann und man kann keine Instruktionen auf den Stack werfen, weil wenn man diesen Prozessor setzt, dann wird der Prozessor sie nicht ausführen und in anderen Worten ist das ein Bit was ein Requirement für und was kann man damit machen, wenn man zum Beispiel Code Reverse engineered und disassembliert und man sieht sowas wie dieses hier und zum Beispiel und man guckt sich das an, was macht das? Es ist völlig kryptisch und die Informationen, die in der XML Version ist, kann man ganz einfach herausfinden, was das macht, wie man das dekodiert, einige der kryptischeren Sachen und aha, in Wirklichkeit ist das hier das SC-TLA Register und das ist nun kryptischer Name für das Register und man kann auch noch mehr machen, man kann die einzelnen Bits im Register sehen und ich habe eben gesagt WXN und man kann das benutzen zum Beispiel, um das so darzustellen, um das etwas benutzbarer zu machen und man kann auch die Dokumentation nehmen, das ist was das WXN Bit macht und man kann zum Beispiel hier drauf klicken und ein Mausover Text angucken und das macht es viel einfacher, diesen kryptischen Code zu lesen und das ist ganz oberflöchige Sachen, die man da rausziehen kann, aber wenn man tiefer einsteigt in die Beschreibung der Instruktion, dann gibt es zum Beispiel Sachen wie die Assemblersprache und die Spezifikation der Assemblersyntax und etwas, was ich vor einigen Jahren gemacht habe und ein Blogartikel darüber geschrieben am Wochenende und es ist zum Beispiel möglich, diese Spezifikation zu nehmen und in ein Disassembler zu tun und zum Beispiel den Code disassemblieren und man nimmt zum Beispiel die binäre Beschreibung des Befehls und das ist oben, was in dem Schreibmaschinen-Zeichensatz ist und dann macht man daraus Zeichenketten und das ist dann der Code unten, der beschreibt, wie man es macht, das heißt man kann es als ein Disassembler benutzen und es ist möglich, das umgekehrt anzuwenden, wenn das als ein Assembler zu benutzen und man kann es einfach von unten nach oben machen und kann aus den Strings dann Binärcode machen und wir werden mehr davon sehen Sachen rückwärts ablaufen zu lassen und das Wichtige bei den Befehlsatz ist, dass er was macht und die Spezifikation enthält eine Beschreibung davon, was genau dieser Befehl macht und diese Beschreibung ist als Code, was mich als Programmierend natürlich glücklich macht und ich verstehe die englischen Wörter nicht, aber ich verstehe den Code und was man machen kann ist man mit Code, man kann ihn ausführen und wir gehen einfach durch und wir nehmen einen Befehl und vergleichen ihn mit dem Diagramm und vielleicht bekommen wir dann Werte für einige der Variablen und dann gehe ich da einzeln durch Schritt für Schritt und werden diesen Code aus und irgendwann sehen wir das in Register 5 ein Wert gesetzt wird und das ist irgendwas relativ einfaches, was man mit der Spezifikation gemacht hat und das ist eine relativ einfache Sache und sobald man es hat, kann man darauf aufbauen und sehr viel mehr machen. Eine Sache, die erstaunlich einfach zu implementieren ist, ist eine symbolische Repräsentation von diesem Befehl zu machen und ich zeige ganz kurz, wie das geht. Wir nehmen diese konkreten Werte und wir haben noch vier andere Variablen und die benutze ich als symbolische Variablen nur und so, wenn ich hier durchgehe durch den Code, dann breche ich nicht nur konkrete Werte, zwei oder vier oder so, sondern ich werde auch einen Graph aufbauen, der genau zeigt, wie ich zu diesen Werten gekommen bin und wenn ich den Code ausführe, kann ich diesen Graph bauen und der repräsentiert genau das, was der Code macht und was ich jetzt machen kann, ist wir gehen durch diesen Code und durch den Graph und sehen, was er macht und jetzt haben wir eine symbolische Darstellung davon, von einem Lauf durch diesen Befehl und ich kann das in einen Constraintsolver geben, wenn einer C3 oder SMT Solver malgehört hat, darüber spreche ich hier und ein Constraintsolver ist ein sehr nützliches Tool, weil man einfach Code da vorwärts durchlaufen lassen kann, man kann Eingabewerte geben und sehen, was der Output ist, was die Ausgabe ist von dieser Funktion, von diesem Befehl, man kann ihn aber auch rückwärts laufen lassen und wenn man einige Ausgabewerte hat, ein Endergebnis, kann man fragen, bei welchen Eingabewerten wird das passieren und das ist ganz wichtig, wenn man versucht, wenn man versucht rauszufinden, was die einzelnen Befehle machen oder wie man einen bestimmten Effekt erzeugen kann, wie man zum Beispiel rausfinden kann, wie ein bestimmtes Register benutzt werden kann und welche Inputs braucht man damit genau das passiert und man kann auch den Constraintsolver benutzen, um zwischenwerte rauszufinden, die in der Mitte der Berechnung sind, wenn man einen Wert haben will in der Mitte, dann kann man fragen, welche Eingabewerte werden das verursachen und wenn einige von euch solche Tools kennen wie Clay, zum Beispiel ein symbolisches Ausführungstool und dann die benutzen etwas ganz Ähnliches wie dies und ich habe jetzt gezeigt euch einen einfachen Graf gezeigt, wie man den aufbaut und dies ist der tatsächliche Graf für diesen Befehl und er hat viel mehr Knoten und einige der Funktionen, die aufgerufen werden und da kann man wie berechnet wird, ob eine Abzweigung verfolgt wird oder nicht, das sind 80 oder 90 Knoten und ich habe damit experimentiert, um das in zwei Arten zu erweitern, dies ist nur ein Pfad durch die Ausführung von diesem Befehl und eine Möglichkeit das zu erweitern ist, ein Graf der alle möglichen Pfade durch diesen Befehl darstellt und das ist viel nützlicher, denn wenn man irgendwas haben will, dann kann man fragen, wie kann ich das machen, dass das passiert und welche Eingabewerte brauchen wir für diesen speziellen Pfad und ich habe auch experimentiert mit der gesamten Spezifikation und wie Exceptions behandelt werden, wie Befehle geholt werden, ausgeführt werden und für alle Befehle und ich habe damit experimentiert einen Graf zu bauen, der die gesamte Spezifikation auf einmal darstellt und das ist noch nützlicher, denn praktisch jede mögliche Frage über die Spezifikation, dann kann man den Constraints Hall weiterauf ansetzen und der wird dir eine Antwort liefern und dieser Graf ist für die komplette Spezifikation groß, eine halbe Million Knoten und das ist die Spezifikation, die Arm benutzt, etwa eine halbe Million Knoten und das Tolle ist, dass moderne Constraints Hall war, können diese halbe Million Knoten und immer noch in ein bis zehn Sekunden eine Antwort ausrechnen und für die meisten Fragen und das ist unglaublich nützlich, wenn man so ein Tool hat, wenn man genau verstehen will, was die Spezifikation macht und wie genau Programme sich verhalten werden und rausfinden, welches Programm man schreiben will, um ein bestimmtes Verhalten zu erzielen und viele uns interessieren Befehle, aber vor allem benutzen die meisten von uns Programme, das heißt man kann die Spezifikation benutzen, um ganze Programme auszuführen, man hat sozusagen einen Simulator des Arm Prozessors und wie man wie der Prozessor Befehle holt und ausführt und Exemptions behandelt und das habe ich gemacht, ich habe diese Schleife zu dieser Spezifikation hinzugefügt und teste jetzt die Spezifikation und die gute Nachricht für mich ist, ich arbeite für Armen, deswegen habe ich interne Tests und kann die benutzen und Sachen, die die Arm benutzt und große Test-Streets, große, viele Tests, mehrere Zehntausend Testprogramme, die Arm hat in den letzten 25, 30 Jahren aufgebaut hat und ich habe mich dran gesetzt und die Spezifikation getestet, diese Test-Street von Arm selbst zu benutzen und wenn man Software testet, dann weiß man der Graf sieht irgendwie so aus, am Anfang geht alles gut und nach und nach geht es mehr oder weniger gut, aber dann gibt es immer mehr Wachs, die immer schwerer zu finden sind und vor allem was ich rausgefunden habe, als ich die Spezifikation getestet habe, war, das, ihr solltet eigentlich schockiert sein, darüber was, davon was ich gesagt habe, dass selbst die offizielle Arm Spezifikation hat nicht alle Tests von Arm erfüllen können und das ist eigentlich schockierend. Ich sage euch das, ich erzähle euch das um das zu betonen nicht, weil ich glaube, dass Arm Spezifikation besonders schlecht ist, ich glaube, dass es einfach nur üblicherweise schlecht ist. Ich denke, dass man das mit jeder Spezifikation für jedes echtes System in der Welt benutzen kann und dann versuchen wir das zu testen gegen den Test-Street und dann finden wir irgendwie Fehler und man wird sehen, dass es genauso schlecht abschlägt wie bei Arm. Es hat mich Wochen gedauert überhaupt auf einen Reset zu kommen bei dem Prozess, nur um den Start bei dem Prozess neu zu kriegen. Ich denke, wenn man andere Spezifikationen anguckt, dann wird man ähnliche Sachen feststellen. Okay, lasst uns weitergehen. Ein nutzliche Sachen, die man mit der Spezifikation machen kann. Etwas, was ich letzten Sommer versucht habe ist, ich habe es für Fast-Testing benutzt. Das besteht aus, ich nehme ein Programm und schmeiß zufällige Eingaben rein und gucke mal an, was kaputt geht und ziemlich alles geht kaputt. Mehr als F-Tests oder weiter, also gibt es noch AFLs, die monitoren ein bisschen, wie das Programm abläuft und das gibt mir ein bisschen Leidfahrten, was ich als nächstes angucken kann. Ich kann sozusagen aufpassen, was das Programm macht, ob es einen bestimmten Fahrt nimmt oder nicht und ich kann mehr versuchen, wenn ich sehe, da funktioniert was gerade effizient, wenn ich neue Fahrte finde, dann versuche ich das weiter und wenn nicht, dann veränder ich etwas. Das ist das normale Fussing, was man eigentlich versucht ist, man versucht die Branch-Coverage zu maximieren, also dass alle Zweige mal abgelaufen werden. Was wir getan haben mit der Spezifikation war, wir wollten nicht nur im analysierten Binary angucken, sondern in der Spezifikation die Branche angucken, die Zweige. Und was wir dabei gefunden haben ist, wenn man das Binary analysiert, dann ist es einfach nur gerade zu Coat, da gibt es keine Verzweigung. Man sieht nämlich anders der Coat im Zweifel schnell woanders hinspringt. Aber vielleicht ist der Coat, vielleicht sieht er eine Abzweigung nicht, für die man den ... Ja und das Chax-Opti ist ein Geräteregister ist oder RAM oder ROM und es gibt ganz viele verschiedene Abzweigungen und das macht das Fussing sehr interessant, um damit rumzuspielen. Und wenn es um den Micro-Kernel geht, wir haben analysiert, was das Call-Interface ist und eins, wo mit der Fusser uns überrascht hat, ist, wenn man einen Stack-Point an dem zum Beispiel und zeigt irgendwo mitten in Device-Adressraum und macht dann eine Exception, was passiert dann und die Antwort ist, es gibt einen Fehler im Micro-Kernel und was gemacht hat war, dass das erste ist, es hat vom Stack gelesen und wir haben von einem der Geräte tatsächlich gelesen und das ist nicht wirklich, was hätte passieren sollen, das Security-Modell ist einfach damit kaputt. Und das heißt, wir wollen nicht nur Coverage über die Branches und das Binary, sondern ich hoffe, einige von euch werden damit weiter experimentieren. Und der Grund, warum ich all das gemacht habe, ist, ich wollte die Möglichkeit haben, einen ARM-Prozessor formal zu verifizieren. Und das heißt, ich musste erst mal eine Spezifikation haben, bevor ich damit anfangen konnte. Und dieses übereinfache Modell, stark vereinfachte Modell von einem Prozessor, das ist irgendwie 20 oder 30 Jahre alt, aber es ist für das Beispiel gut genug, wenn man einen Prozessor überprüfen will, ob der korrekt ist. Was man machen kann, ist, man baut zusätzliche Logik außen drum, die die Werte überwacht am Anfang der Instruktion und dann am Ende der Instruktion. Und wenn man den da die Spezifikation reintut, dann sieht man, was die Antwort sein sollte und kann das vergleichen damit, was der Prozessor tatsächlich gemacht hat. Und man kann das machen und ein Test-Based-Ansatz und guckt, ob die Ausgabe wirklich passt. Und man kann es aber auch eine formale Verifikation mit einem Bounded Model Checker machen. Und eine der Grenzen von diesen Constraintsolver ist, dass man das damit machen kann. Und der macht nicht nur einen Schritt, sondern versucht alle möglichen Kombinationen von Inputs von 1, 2, 3 und noch mehr Instruktionen machen und immer längere Instruktionssequenzen und guckt nach, was schiefgehen kann. Okay, und das stellt sich als eine sehr, sehr effektive Art heraus. Das werden wir ganz viel benutzen, wenn wir unser neuen Feature evaluieren wollen. Wir haben darüber ein Paper geschrieben und ich empfehle euch das Video von Cliffortoots von vor ein paar Stunden anzugucken, die machen das sehr ähnlichem Prozess. Okay, ich lade euch dazu ein, die Spezifikation zu nehmen und was Fantastisches zu finden, was man damit machen kann. Ich habe ein paar Ideen vorgeschlagen und da gibt es noch ein paar mehr, die konnte ich zeitlich nicht beschreiben in dieser Zeit hier. Aber lasst uns zum Titel des Vortrags kommen, wie kann man eine formalisierte Software trauen, vom einfach gefützten Software trauen. Also wir nehmen ein Programm und wir verifizieren das gegen eine Spezifikation. Aber die laufen ja gar nicht irgendwie im Vakuum, die laufen auf einem bestimmten Betriebssystem, die benutzen bestimmte Bibliotheken. Da gibt es auch noch Programmiersprachen, in denen sie geschrieben sind und wenn man also jetzt ein Programm gegen die Spezifikation verifiziert, dann verifiziert man das auch gegen die Spezifikationen von Linux und Bibliotheken, Chilipsi, IOC und die haben alle irgendwie, die haben kaum oder sehr, sehr schlechte Spezifikationen und also was machen denn jetzt eigentlich Compiler und so in Wirklichkeit in der Praxis? Wenn man also sein Programm verifiziert gegen Spezifikationen, dann wird man viele Fehler finden und man wird zwar seine Software sehr viel verlässlicher machen, aber wenn die Spezifikationen nicht gut sind, so wie zum Beispiel die Armspezifikationen nicht gut waren bevor wir die getestet haben, traue ich jetzt vom mal verifizierter Software? Nein, nicht wirklich, es ist sehr viel besser, wenn es vom mal verifiziert ist, aber das ist nicht alles, wir können zwar mit Technik schon viel machen, fast deswegen zum Beispiel, aber da gibt es noch mehr. Okay, das ist meine letzte Folie, ich lade euch dazu ein, rauszugehen und was mit den Spezifikationen zu machen, eine Verifikation. Und zu Gott nicht mich anzusprechen, wenn ihr Fragen oder Probleme habt, wenn es hier weitere Hackers gibt im Publikum, dann bitte, bitte kommt zu mir und geht es mit mir oder Milch Merritt ist hier in der ersten Reihe, wenn du interessiert bist, bei Arm zu arbeiten. Ich möchte ganz vielen Leuten danken, auch Leuten von Arm und überall sonst mir zu helfen bei dieser Arbeit. Vielen Dank für eure Aufmerksamkeit für die letzte halbe Stunde. Okay, vielen lieben Dank, Alex. Wir haben noch Zeit für Fragen. Wenn es Fragen gibt, stellt euch an die Mikrofone. Jetzt ist eure Gelegenheit. Bitte sorgt dafür, dass eure Fragen mit dem Thema zusammenhängen. Gibt es Fragen von online? Noch gibt es keine Fragen online. Okay, dann an Mikrofon 1. Also wir benutzen Verifikation Conditions aus der Spezifikation, wir leitest du dir daraus ab. Und die Idee ist, die Spezifikation zu nehmen, die einfach beschreibt ein Stück Hardware. Und was ich versuche ist, was ein Hardware-Engineur machen würde, wenn die wirklich die Maschine bauen und implementieren würde. Das heißt, in wirklich haben wir einen riesen Graf. Und wenn der Control Flow ist und sich zusammenkommt, dann gibt es einen Unterschied zwischen den berechnet Variablen von links und recht. Okay, ich sehe mich vor allem für welche Logik sie benutzen, um den Server einzugucken und so. Okay, Mikrofon Nummer 6, bitte. Ich habe mich gefragt, ob Sie kurz ein bisschen über die Sprache reden können, mit der Sie Ihre Spezifikation schreiben. Diese ist eine Sprache, die ich geerbt habe eigentlich von der armen Dokumentation. Alle Prozessoren sind im Pseudocode beschrieben. Und der Pseudocode, den Armen geschrieben hatte, war eigentlich wirklich nah an einer echten Sprache. Und ich habe diese Sprache reverse engineered und habe daraus dafür Tools gebaut. Ich habe dann daraus versucht, daraus zu finden, was diese Sprache eigentlich wirklich ist. Und die Sprache selbst ist eine ganz einfache, imperative Sprache. Es ist eigentlich etwas wie BBC Basic. Ich weiß nicht, ob jemand sich an BBC Basic erinnert. Und ein bisschen wie Pascal ist keine komplizierte Sprache. Sondern sie ist design, sodass möglichst viele Leute das lesen können und wirklich zweifelsfrei wissen, was es bedeutet, ohne die Sprache lernen zu müssen. Okay, gibt es vom Signal Engine was? Ja, jetzt gibt es eine Frage. Hat Arm seine eigene Form von der Intel Management Engine? Nein, die kurze Antwort. Nein, ich glaube, wir haben nichts in der Art. Ja, ich sage einfach nein. Mikro Nummer 1, hallo. Auf die Frage, die wir vorher hatten zur Spezifikationssprache, habt ihr darüber nachgedacht, die 3-Son-Sprache zu benutzen? 3-Son-Sprache ist so eine Art, besteht aus S-Expressions. Und wenn man das, wenn man List mag, ist das ganz toll. Aber wer kein List mag, da ist es wirklich ein großes Problem und eine große Barriere für das Verständnis. Und wir wollten eigentlich was, wo man hinguckt und sieht, aha, ich verstehe, was hier passiert und die Barrieren möglichst niedrig zu halten. Ist klar. Okay, letzte Versuch, Signal Engine. Wie lange dauert der komplette Test für die Armspezifikation? Ungefähr 2 Jahre. Ja, also ein moderner Prozessor und 80 Prozent des Teams sind Verifikation-Ingenieure und im Wesentlichen schreiben sie neue Tests und führen alte Tests durch und diagnostizieren die Tests. Und das ist irgendwie, vielleicht ungefähr 3 Jahre, aber nach dem ersten Jahr hat man ungefähr ein Prozess, von dem man weiß, dass er funktioniert und danach kann man ihn debaggen und dann ist Fein-Tuning an der Performance durchführen. Aber es dauert wirklich lange und die Tests selbst durchzuführen, ich weiß es eigentlich gar nicht. Und einer meiner Mitarbeiter ist hier im Publikum und die führen eigentlich die Tests durch, aber ich weiß es eigentlich gar nicht. Aber wir benutzen sehr viele Prozessoren parallel und aber ich weiß es gar nicht. Vielen lieben Dank, alles da. Lasst uns hier nochmal mit deiner warmen Runde von Applaus verabschieden.