 Trust zone ist nicht genug in der Übersetzung von Michael und Florian. How you can hijack debug components for embedded security in ARM processors. Pascal is not only a banded software security engineer but also a researcher in his spare time. So please give a very very warm welcoming good morning applause to Pascal. Okay, thanks for the introduction. So as it was said, I am an engineer by day. Danke für die Einführung. Wie schon anfangs genannt arbeite ich eine französische Firma. Aber in diesem Talk geht es vor allem um die Aktivität als Wissenschaftler. In diesem Talk habe ich mit einem Wissenschaftler mitgearbeitet. Der heißt Muhammad Abdul Wahab. In diesem Talk wird es hauptsächlich darum gehen um die Sicherheit für Embedded Systeme und vor allem in der Sicherheit in ARM Prozessoren. Auf der Slides unten seht ihr ein Link, da könnt ihr Zugriff auf alle Dokumente haben und auch auf dieses Slides nach meinem Talk. Vor dem Kongress wusste ich nicht, welcher Hintergrund vorhanden ist hier für diesen Talk, welchen Hintergrund ihr habt. Deswegen habe ich da ein paar Referenzen hier auf dieser Slide gezeigt, dass ihr das Vokabular auch verstehen könnt. Und im Bereich der Sicherheit und Computerarchitektur wird es darum gehen. Zum Beispiel hat hier Kegan einen Talk gehabt zu Angriffe auf Mikroarchitekturen und Sicherheits-Execution-Environments. Ich werde im Bereich von FPGR Sachen. Gibt es die Open-FPGR-Assembly, die ihr hier besuchen könnt. Und wenn ihr keine Ahnung habt von FPGRs, dann hoffe ich, dass ihr Zeit habt, um eben zu dieser Assembly zu gehen, weil diese Leute an der Assembly einen guten Arbeit machen, um FPGR Open Source zu machen. Wenn ihr diese Slide seht, dann ist die erste Frage, wieso habe ich den Titel gewählt, Trustzone ist nicht genug. Nur eine kurze Erinnerung, was ist Trustzone? Trustzone ist das Prinzip, dass man ein System teilt in eine sichere Komponente und eine unsichere Komponente oder eine vertrauenswürdige Komponente kann man auch sagen. Wir haben viele Hardware-Komponenten und viele Software-Komponenten in den Trustzone, die uns erlaubt, ein separat, ein sicheres Betriebssystem laufen zu lassen in unserer Trustzone. In unserem Fall ist, was wir tun wollen, wir wollen die Komponenten verwenden auf der linken Seite hier von dem Bild und uns angucken, ob wir das noch sicherer machen können. Das Weiteren, wollten wir uns Trustzone genau angucken, wenn ihr euch nämlich den Talk-to-Sicherheit angesehen habt, dann habt ihr vielleicht schon gesehen, dass man Trustzone verletzen kann unter bestimmten Bedingungen. Dieser Vortrag ergänzt das andere, da wir etwas auf ein niedrigeren Niveau machen, auf ein niedrigeren Level machen, der Prozessorarchitektur. Ich werde im weiteren Teil des Vortrags darüber reden, was wir zwischen der Trustzone und dem Approach in Visrock machen können. In Visrock wird es eine kurze Einführung, eine Ansätze, Debackkomponenten für Sicherheit zu benutzen. Dann rede ich über ARM-Hacks, das ist der Name des Systems, das wir entwickelt haben, um die Debackkomponenten zu benutzen, in dem Kontext unseres Projektes. Arbeiten wir mit einem System on a Trip. System on a Trip sind diese Art von Gerät, wo wir in dem grünen Teil den Prozessor haben. Es kann ein Einzelkern sein oder Dualcore oder sogar ein Quadcore Prozessor. Und ein anderer interessanter Teil, der ist in gelb hier, ist die programmierbare Logic, ein FPGA in diesem Kapfall. In dieser Art von System on a Trip hat man ein VR Prozessor und einige Links zwischen den beiden Einheiten. In dem kleinen roten Rechteck könnt ihr also die Trustzone sehen. Das ist ein Bild davon von einem System on a Trip, der von der Sync heißt, von Psylinks, einem FPGA Hersteller. In dieser Art von Chips hat man typischerweise zwei Cortex-Prozessoren und die FPGA-Reihe, um damit zu arbeiten. Was wir machen wollen mit den Debackkomponenten, ist dynamisch ein Informationsfluss zu verfolgen. Was ist Informationsfluss? Informationsfluss ist das Transfer von Informationen von einem Container C1, sondern Container C2 in einem Prozess P. In anderen Worten, wenn wir diese einfache Codebeispiel übernehmen, wir haben vier Variablen A, B, W und X. Die Idee ist, wenn man einige Metadaten in A hat, dann werden die Metadaten nach W verschoben. Also, welche Art von Informationen wir haben, übertragen, die im Wesentlichen die Informationen, die wir in dem ersten Block haben, ist okay. Diese Daten sind privat, diese Daten sind öffentlich und wir sollten keine öffentlichen und privaten Daten vermischen. Im Wesentlichen können wir sagen, dass die Information, die nähere Information sein kann, die öffentlich oder privat ist. Aber wir haben verschiedene Niveaus von Informationen im Drübischen. In Zukunft, in den weiteren Teilen wird diese Information taint, also verunreinigt oder getacked, gedannt. Und wir werden sagen, mein Tag ist rot oder grün, um zu sagen, ob es private oder öffentliche Daten sind. Wie ich gesagt habe, wenn das Target A rot ist, dann muss die Daten in W auch rot sein. Das Gleiche für B und X. Wenn wir auf ein Buffer Overflow angucken, als Beispiel. In dem oberen Teil der Folie habt ihr den Assembler Code und in dem unteren Teil die grüne Farbe ist die Farbe der Tax. Unter rechten Seite der Spalte hat man den Status der verschiedenen Register. Dieser Code ist im Wesentlichen okay, wenn mein Input am Anfang rot ist. Also wir würzen einen verunrechnigten einen in der X-Variable. Dann wird der Register 2, dass den X enthält, wird auch rot. Dann, wenn wir den Buffer IDX zugreifen wollen, was die zweite Zeile in dem C Code ist, dann wird auch die Information dort rot sein. Und das Resultat der Operation, was X ist, wird natürlich auch rot sein. Das heißt, wenn wir am Anfang einen verunrechnigten Input haben, dann müssen wir in der Lage sein, diese Information bis zur Rückgabeadresse dieses Codes übermitteln können. Wenn dieser verunrechnete Input tainted ist, dann muss auch der Ausgabekode tainted sein, also verunreinigt. Was können wir damit machen? Es gibt eine einfache Code, der sagt, wenn du ein normaler Bin-Würzer bist, dann musst du bloß das Welcome-File aufnehmen. Wenn du ein Rout-User bist, dann musst du das Passwort-Datei öffnen. Das sagt im Wesentlichen okay, wenn wir das Welcome-File öffnen wollen, das ist eine öffentliche Information, damit kannst du alles machen. Wenn das ein Rout-Benutzer ist, dann wird Passwort zum Beispiel einen kryptographischen Schlüssel enthalten und wir dürfen nicht zu der Print-F-Funktion gehen. So im Wesentlichen, die Idee ist zu testen, dass die FS-Variable, die die Daten enthält, das ist datals privat oder öffentlich ist. Im Wesentlichen haben wir drei Schritte dafür. Zuerst die Kompilation gibt uns den Assembler-Code, dann müssen wir die Systemaufrufe verändern, sodass sie das Tag mitsenden, also die Daten öffentlich oder privat sind über meine FS-Variable. Ich werde darüber später etwas mehr reden. Und in der Zukunft ist die Idee, dass wir ein Berichtssystem zu kompilieren, dass diese mit integrierten Unterstützung vor DIFT. So, es hat dafür einige Sachen Arbeit gegeben über dynamische Informations-Tracking. Im Wesentlichen sollten wir das Informationsverfolgung in zwei Arten machen. Zum Ersten auf den Applikationslevel, also wir arbeiten im Java, im Android-Level. Einige Arbeiten schlagen auch Lösungen auf den Betriebssystem-Level vor, zum Beispiel Lamar. Was wir machen wollen, wir wollen auf einem niedrigeren Niveau arbeiten, nicht auf den Applikations- oder Betriebssystem-Level, sondern auf dem Niveau der Prozessorarchitektur. Also, wenn ihr ein bisschen Informationen darüber haben wollt über diese US-Level-Information von Informationsflussverfolgung, dann könnt ihr auf bler.ids.org gehen. Da gibt es einige Informationen für einem Android und ein Apport für ein Inclusion-Detection-System. Im Rest des Talks werde ich im Wesentlich durch diese Arbeiten durchgehen und gucken, was wir darüber machen können. Wenn wir reden über den dynamischen Informationsflussverfolgung auf der tiefsten Ebene, gucken wir vor allem drei Sachen an. Das Erste ist das, was man auf der linken Seite sieht, von der Slight hier. Die Idee ist hier, dass auf der oberen Seite von dieser Figur hier sieht man die normale Pipeline. Zum Beispiel, dass es dekodiert wird. Dann hat man ein Registrier-Datei. Und dann geht es in die ALU-Rein, in die algorithmische Verarbeitungsunit. Das ganze gibt Security. Dann wird das verarbeitet mit Text und Tains. Also, es ist einfach gesagt, wird das hier normal verarbeitet. Nur, um Daten zu verarbeiten. Das impliziert zwei Sachen. Erstens, brauchen wir den Source Code von dem Prozessor selbst, um das zu duplicieren. Und um den DIFT, die Informationsflussverarbeitungs-Tracking, zu verarbeiten. Das ist also sehr unpraktisch, weil wir den Source Code brauchen, was nicht immer einfach ist. Und über alles gesprochen, können wir alle Kabel rausziehen von dem Prozessor. Und dann ans Angucken, was wir bekommen. Der zweite Ansatz ist, hier auf der rechten Seite zu sehen, das ist ein bisschen anders. Anstelle von einem einfachen Prozess, das alles machen will. Zusätzlich zum Informationsflusskontrolle, wollen wir stattdessen den normalen Informationsfluss behalten. Das ist hier das zweite Bild. Und dieser Weg ist ebenfalls nicht so gut, weil wir einen Kern haben, der die Applikation betreut und einen anderen Core haben, einen anderen Prozessor-Kern haben, der nur die Analyse macht. Das heißt, es ist ein bisschen schade, einen ganzen Prozessor-Kern zu benutzen, nur für die DIFT. Was wir also gut machen sollen, ist, wir können einen dedizierten Core-Prozessor für DIFT erstellen. Wir haben also einen Hauptprozessor, der die Applikation betreut und mit dem Core-Prozessor interattigiert. Und da gibt es dann ein paar Kommunikationen zwischen diesen beiden Prozessoren. Wenn wir also mal einen kurzen Überblick haben wollen und einen Vergleich zwischen den einzelnen Einsätzen. Wenn man DIFT in reinen Software laufen lassen möchte, das ist sehr, sehr kostendig. Es kostet viel und es tut weh, weil es viel overhead und Zeit braucht. Hinsichtlich von den anderen Approaches, die alle mit Hardware geholfen werden. Das heißt, auf dieser Slide, die man jetzt wieder sieht, ist dieser Core-Prozessor nicht so wichtig. Wir sehen das in meinem Talk, wir werden sehen, dass der dedikated DIFT-Core-Prozessor, die letzte Zeile hier, dass dieser nicht so, und lass mich sagen, der ist nicht so einfach für verschiedene Sicherheitspolicies. In der ersten Zeile von dieser Tabelle, die man jetzt sieht, ist die Idee, dass man Instrumentation benutzt. Wenn man zum Beispiel am Tag 2 ist, dann ist Instrumentation die reine Verwandlung von einem Programm in sein eigenes Messwerkzeug. Ich habe also einen Teil von meinem Code nur zur eigenen Messung. Wenn ich also messen möchte, welchen Einfluss die Instrumentation hat auf meine Applikation, dann kann man in diesem Diagramm sehen, dass die Normale Applikation normalerweise ein Level von 1 hat, und wenn man aber Instrumentation mit benutzen möchte, dann ist der minimale Overhead oder Override. Overhead, das ist ungefähr 75%, so ungefähr die Zeit, die man braucht für Instrumentation, wird grob gesagt doppelt so lang brauchen wie wenn man normal einfach nur das Programm laufen lässt. Und das ist natürlich nicht akzeptabel, weil das wird dein Programm zerstören. Also mein Ansatz, hier der ARMHEX-Ansatz, der reduziert diesen Overhead von einem Softwareansatz. Wir werden jetzt nicht die Sicherheit von dem DRFT-Co-Prozessor beachten. Das ist der erste Ansatz von einem DRFT in einer hardware-basierten Crip. Ich habe den Talk zur Sicherheit von Nintendo Switches beobachtet, und der Sprecher hat gesagt, dass Blackbox-Testing Spaß macht, außer dass es eben keinen Spaß macht. Was wir machen wollen, wir wollen das oder suchen ohne den Prozessor die Kappen zu müssen. Das ist was wir machen wollen. Auf der lichten Seite haben wir den ARM-Prozessor. Im Wesentlichen, das hier ist eine vereinfachte Version mit nur einem Kern. Auf der rechten Seite habt ihr die Struktur des Co-Prozessors, den wir implementiert haben in FPGA. Im Wesentlichen könnt ihr ja sehen, zum Beispiel für Entschuldigungen im Moment zwei Dinge. Das erste, es gibt einige Verbindungen zwischen dem FPGA und der CPU. Diese Links existieren schon in dem Chip. Und die andere Sache, die man sehen kann, bezüglich des Speichers, es gibt separaten Speicher für den Prozessor und für den FPGA. Und wir sehen später sehen, dass wir Trustzone benutzen können, nur um ein Layer der Sicherheit hinzuzufügen, so dass wir den Speicher zwischen beiden mischen können. Im Wesentlichen, wenn wir mit einem ARM-Prozessor arbeiten wollen, müssen wir die ARM Datenblätter sehen. Zuerst mal habt keine Angst vor der Länge der ARM Data Chips. In meinem Fall habe ich mit dem ARM V7 Technical Manual gearbeitet. Es sind schon 2.000 Seiten. Das ARM V8 Manual ist über 6.000 Seiten. Aber natürlich, was auch schwierig ist, die Information ist zwischen verschiedenen Dokumenten verteilt. Aber egal, wenn wir die Backkomponenten benutzen wollen, in dem Fall von ARM, dann haben wir nur dieses Register hier, das heißt DBG, irgendwas. Und ihr könnt sehen, in diesem Register kann man sagen, okay, den Schlüssel und Wert 038, irgendwas in dieses Register zu schreiben. Und wenn man irgendein anderen Wert dahinschreiben, dann entsperrt es den Register. Also das ist der erste Schritt, um die Backkomponenten anzuschalten. Einfach ein zufälligen Wert in dieses Register zu schreiben, um die Backkomponenten freizuschalten. Hier ist noch mal die Schematik des System on the Chip. Hier könnt ihr sehen, es gibt diesen Core Prozessor. Und auch ganz oben habt ihr, was die Core-Site-Komponenten heißen. Das sind die berühmten Backkomponenten, über die ich im zweiten Teil meines Talks reden möchte. Hier ist ein vereinfachter Ansicht von den Backkomponenten, die wir in dem Sync haben. Auf der linken Seite haben wir die CPU1 und die CPU2, die beiden Prozessoren. Und all die Core-Site-Komponenten und PCM, also die Dinge, die in dem Rote Dreieck sind und die ITM und die Instrumentation und die Trace-Buffer, also Spur-Mikrozelle. Im Wesentlichen wollen wir Daten aus diesen Core-Site-Komponenten extrahieren, die der wesentliche Fahrt wird okay. Wir benutzen den PTM und wir folgen dieser roten Linealgenie, gehen durch den Trichter und an der Stelle haben wir zwei Möglichkeiten, die Informationen zu speichern, die wir von den Deeper-Komponenten haben. Das erste ist der eingebüttete Trace-Buffer, eine kleine Speichereinheit in dem Prozessor. Aber glücklicherweise ist das eine sehr, sehr kleine Speicher, ungefähr vier Kilobytes. Und die andere Möglichkeiten, die Daten auf den Trace-Packet-Output zu exportieren, das ist das, was wir einfach um Daten zu benutzen, um die Daten an den Core-Prozessor im FPGA zu übertragen. So was PTM machen kann, das erste ist, zu nachverfolgen, welche Speicherstelle, man kann alle Aufrufe verfolgen, aber man kann auch zum Beispiel nachverfolgen eine spezifische Region des Codes. Das heißt, man kann sagen, ich will nur den Code in S.1 oder S.2 oder S.n nachverfolgen. Dann kann das PTM auch ein paar Verzweigungstests machen. Das ist etwas, das nicht in dem Linux-Kernel vorhanden war. Wir haben ein Broadcasting ins PTM, ein Patch dafür, eingereicht, der abgenommen wurde. Man kann auch Time-Stamping machen, um die Informationen ins Trace zu speichern. Das ist im Wesentlichen, wie eine Trace aussieht. Hier ist der einfachste Code, den wir haben können, einfach eine Vorschleife, die nichts macht. Hier das ist der Assembler-Code. Und die Trace wird ungefähr so aussehen. In den ersten fünf Bytes haben wir ein Stop-Paket, das Async-Paket, das ist einfach der Anspruch des Traces. In dem grünen Teil haben wir die Adresse, die zu dem Anfang der Schleife entspricht. Der orangene Teil sind die Branch-Adress-Packets. Wir haben zehn Iterationen dieses Pakets. Wir haben auch zehn Iterationen in der Vorschleife. Das zahlt einfach nur, wie die generelle Struktur dieses Spur aussieht. Wenn wir eine andere Schleife daran haben, dann macht das einfach die Spur etwas länger, um die Informationen über die zweite Schleife hinzuzufügen. Wenn wir all diese Spuren haben, ist der nächste Schritt okay, ich habe meine Texte, aber was mache ich jetzt damit? Wie definiere ich die Regeln? Nur um eine Texte zu übertragen. Dafür benutzen wir statische Analyse. In diesem Beispiel haben wir die Instruktion okay. Okay, brechne einfach Register 1 plus Register 2 und tut das in Register 0. Dann benutzen wir statische Analyse, die uns zu sagen, okay, okay, der Tag, der mit Register 0, der Tag für Register 0 ist der Tag für Register 1 oder Register 2. Und die statische Analyse führen wir durch, bevor wir den Code durchführen. Und wir sagen, okay, wir haben all die Regeln für unsere Grenzfälle. Und jetzt haben wir die Traces. Wir wissen, wie wir die Text übertragen müssen. Und der letzte Schritt ist es, die statische Analyse in dem LWM-Backend zu machen. Und der letzte Schritt ist die Instrumentierung. Wie ich vorhin gesagt habe, wir können alle Speicheradressen, die wir brauchen, für die Instrumentierung bekommen. Aber in der zweiten Möglichkeit können wir auch nur die Register-Member-Speicheradressen für die Instrumentierung. Im ersten Fall, in diesem einfachen Fall, können wir im Wesentlichen sagen, okay, wir instrumentieren allen Code, aber der wesentliche Nachteil daran ist, okay, wir werden sehr die Zeit der Ausführung beeinflussen. Was wir sagen können, okay, mit dieser Funktion können wir nehmen die Daten auf der Spur. Also wir nehmen die Programmkontrolladresse der Spur. Und für den Stack-Pointer benutzen wir statische Analyse, um die Information über den Stack-Pointer zu kommen. Und wir instrumentieren nur noch die Instruktion am Ende. Also wenn wir jetzt zu diesem System zurückkehren. Für die Kommunikation, wir fangen rot. Also diese rote Kommunikation ist der wesentliche Nachteil. Wir haben den Prozessor und den FPGA, die in verschiedenen Teilen arbeiten, laufen. Das wesentliche Problem wird sein, wie können wir diese Daten in echt Zeit übertragen zwischen dem Prozessor und dem FPGA? Also das PTM, das ist der Zeit-Overhead, wenn wir Trace enabled. Also im Blau haben wir die Zeit, die Basiszeit, wenn die Spuren abgeschaltet sind. Und wenn wir Spuren anschalten, ist der Zeit-Overhead fast vernachlässigbar. Hinsichtlich der Zeit-Instrumentation können wir sehen, dass wir mit Strategie 2, dass die Core-Site-Komponenten die Instrumentation und die statische Kontrolle benutzen. Und wir konnten den Overhead von 53% auf runterbrechen, auf herunterfahren, auf nur 5%. Also es gibt immer noch ein Klein-Overhead, aber der ist sehr, sehr klein verglichen zu mit vorherigen oder vergleichbaren Ansätzen. Hier hat man einen Überblick, der zeigt, in der Grau sieht man die Vergleicharbeit oder die vorherige Arbeit und man kann sehen, dass in unserem Ansatz, in unserer Strategie 1 ist das kleiner und in Strategie 2 ist es noch mal kleiner. Es ist also sehr, sehr, sehr viel kleiner. Der Prozentsatz von dem Instruction instrumentet. Das ist nochmal ein Überblick über das System. Wir können sagen, okay, wir können Trace-Zone benutzen, nur um zu trennen die CPU von den FPGA-Core-Prozessor. Wenn wir also einen Vergleich ziehen zu vorherigen Ansätzen, können wir sehen, dass verglichen zu den vorherigen Ansätzen, dass wir jetzt nun hardcore portibel sind, was der Ansatz von HEO auch konnte, aber eben nicht kann und denkt. Und natürlich ist der Flächenverbrauch sehr viel kleiner als vorherige Ansätze. Kommen wir nun zur Zusammenfassung. Was ihr mitnehmen sollt, ist, dass die PTM-Information zusammenzieht. Das ist ein Tracing, was nicht eingreift und wir haben einen vernachlässigbaren Overhead an Performance. Wir verringern die Kommunikation-Zeit und verbessern die Sicherheit der Software. Was wir zukünftig noch machen möchten, ist für Multicore-Prozessoren, vielleicht den gleichen Ansatzverwinden für andere Prozessorarchitekturen wie Intel. Da kann man unsere Ansatz vielleicht auch übertragen. Und das war mein Talk. Danke, dass ihr zugehört habt. Vielen Dank für das Talk. Wir haben keine Zeit für Q&A. Damit verabschieden sich aus der Übersetzerkabine Michael und Florian. Sie hörten den Talk, Trustzone ist nicht genug. Bitte wende dich mit Feedback auf Twitter an ad C3lingo oder mit dem Hashtag C3T. Tschüss.