Schwerpunkte

Sicherheit für Cortex-M-Prozessoren

Viele vertrauenswürdige Zonen

19. März 2020, 13:38 Uhr   |  Von Dr. Cesare Garlati und Prof. Dr. Sandro Pinto

Viele vertrauenswürdige Zonen
© Bild:Shutterstock

Was tun, wenn Hardware-Isolationsmechanismen wie TrustZone bei Arm-Prozessoren der Cortex-M-Reihe fehlen oder wenn mehr als ein gesicherter Bereich benötigt wird? Zwei Sicherheitsexperten schlagen eine Alternative vor, die schnell und trotzdem sicher anzuwenden ist.

Die Entwicklung von SoCs und Embedded-Systemen wird immer anspruchsvoller. Komplexe Funktionen werden zunehmend durch Komponenten von Drittanbietern erfüllt, die hinzugefügt werden und oftmals nicht vertrauenswürdig sind. Die daraus resultierende monolithische Firmware bietet dann eine wesentlich größere Code-Basis, eine größere Angriffsfläche und eine erhöhte Systemanfälligkeit. Darüber hinaus führen Kostenbeschränkungen und Energiesparanforderungen zu ressourcenbeschränkten Mikrocontroller-Architekturen. Diesen fehlen grundlegende Hardware-Sicherheitsmechanismen und die Fähigkeit, mehrere vertrauenswürdige Anwendungen von weniger kritischen Komponenten zu trennen.

Ein neues Zero-Trust-Modell ist erforderlich, um der inhärenten Sicherheitsbedrohung zu begegnen, die von der daraus resultierenden monolithischen Multi-Source-Firmware ausgeht. Ein neuartiger Ansatz für eingebettete Sicherheit basiert auf einer Hardware-verstärkten, Software-definierten Trennung mehrerer, gleichermaßen sicherer Funktionsbereiche.

Herausforderung: Sicherung eingebetteter Systeme

Die Angriffsfläche in eingebetteten, verbundenen Geräten wächst exponentiell, da anspruchsvolle Kommunikationsanforderungen zunehmend durch die Integration einer Vielzahl von Softwarebibliotheken von Drittanbietern, Open-Source-Echtzeitbetriebssystemen und proprietären Black-Box-Binärdateien – d.h. Peripheriegerätetreibern – erfüllt werden. Das Problem wird durch das Fehlen einfacher und zuverlässiger Mechanismen verschärft, mit denen Komponenten mit gemischter Kritikalität aus mehreren Quellen voneinander getrennt werden können.

Dies führt unweigerlich zu unsicheren Systemen, die alle Softwarekomponenten auf der gleichen Privilegienebene ausführen und sich den gleichen Speicherplatz und die gleichen Peripheriegeräte teilen. Aufgrund des monolithischen Charakters der in diese Systeme eingebetteten Firmware reicht es in der Regel aus, wenn eine Schwachstelle in einer Komponente mit geringer Kritikalität ausgenutzt wird, um eine Privilegiensteigerung herbeizuführen, einen seitlichen Wechsel zu Modulen mit höherer Kritikalität zu vollziehen und das vollständige System zu kompromittieren.

Teurere – und leistungshungrige – Prozessoren bieten einige Funktionen zur Kontrolle des Zugriffs auf Speicherressourcen, wie z.B. virtueller Speicher und Memory Management Unit (MMU). Diese Mechanismen sind jedoch bei weitem nicht optimal, da sie erhebliche Nachteile im Hinblick auf die Implementierung von virtueller Speicherverwaltung und MMU aufweisen.

  • Erstens erfordern sie komplexere Hardware, z.B. Silizium-Gatter und TLBs (Translation Lookaside Buffer), sowie Software, z.B. zweistufige Übersetzungstabellen, die sowohl die Kosten als auch die Leistungsaufnahme erhöhen.
  • Zweitens erhöhen die zusätzlichen komplexen Softwareschichten, die zur Steuerung der MMU erforderlich sind, die gesamte Codebasis (TCB, Total Code Base) des Systems erheblich, was zu einer größeren Angriffsfläche und letztlich zu weniger sicheren Systemen führt.

Wie alle Produkte des menschlichen Intellekts ist auch Software von Natur aus fehlerhaft und zeigt statistisch wahrscheinlich unerwartetes Verhalten – allgemein als »Bugs« bezeichnet. Die daraus resultierende Erhöhung der TCB führt daher unweigerlich zu einer höheren Anzahl potentieller Schwachstellen und letztlich zu einem weniger widerstandsfähigen System.

Ressourcenbeschränkte Mikrocontroller, die in IoT-Anwendungen eingesetzt werden, verfügen in der Regel über vereinfachte Versionen der MMU, d.h. über eine Memory Protection Unit (MPU), die ebenso der Komplexität der für ihren Betrieb erforderlichen zusätzlichen Software ausgesetzt ist. Die mit der korrekten Implementierung dieser Techniken verbundene Komplexität führt oft dazu, dass Entwickler sie überhaupt nicht nutzen.

Wenn es um eingebettete Sicherheit geht, ist weniger mehr. Einfachere Hardware bedeutet einfachere Software, weniger Code-Zeilen, statistisch weniger Fehler und am Ende robustere Systeme. Traditionelle vertrauenswürdige Ausführungsumgebungen (TEE, Trusted Execution Environments), die einen sicheren Bereich aus den verschiedenen Hardwarekomponenten »herausschneiden« – allgemein als »sichere Welt« bezeichnet – sind seit 2004 auf dem Markt erhältlich, haben aber aufgrund zweier wesentlicher Einschränkungen nie eine breite Akzeptanz außerhalb der Mobiltelefonie erreicht.

  • Erstens sind sie auf proprietäre Hardwareerweiterungen angewiesen, die in der Regel nicht für alle Anbieter und Plattformen verfügbar sind
  • Zweitens sind sie zugegebenermaßen übermäßig komplex, sehr schwer zu verstehen und noch schwieriger über verschiedene Silizium-Architekturen hinweg richtig zu implementieren

In den letzten Jahren wurde auch noch das Vertrauen in diese Systeme erschüttert, da systematisch viele kritische Schwachstellen aufgedeckt wurden.

Das Null-Vertrauen-Modell

Die überwiegende Mehrheit der elektronischen Geräte auf dem Markt wird nicht vollständig im eigenen Haus von einem einzigen Anbieter entwickelt. Sie setzen sich vielmehr aus einer Vielzahl von Hardware- und Softwarekomponenten von Drittanbietern zusammen, die mit einigen proprietären IPs kombiniert werden, um den spezifischen funktionalen und finanziellen Beschränkungen des jeweiligen Produkts gerecht zu werden.

Softwarekomponenten von Drittanbietern sind oft in Form von undurchsichtigen Objektcode-Bibliotheken oder Black-Box-Binärdateien erhältlich. Der Mangel an Transparenz stellt einen bedeutenden Bedrohungsvektor für eingebettete Firmware dar, da das Produkt mit absichtlichen oder unbeabsichtigten Schwachstellen ausgeliefert werden kann, was für Angriffe ausgenutzt werden kann.

Wenn der Code von Drittanbietern ohne funktionale Trennung in das monolithische Firmware-Image eingebunden wird, kann ein einzelner Fehler oder eine einzelne Schwachstelle das gesamte System gefährden. Diese Praxis ist in ihrem Kern fehlerhaft. Alle Systemkomponenten – insbesondere die von Dritten bereitgestellten – sollten als fehlerbehaftet und daher als nicht vertrauenswürdig angesehen werden.

Dies führt zu einem neuen Entwurfsparadigma, das auf dem Konzept des Null-Vertrauens basiert: Kein einziger Funktionsblock sollte willkürlich auf alle Systemressourcen zugreifen können und daher sollte kein einziger Funktionsblock in der Lage sein, absichtlich oder unabsichtlich die Vertraulichkeit, Integrität und Verfügbarkeit (CIA, Confidentiality, Integrity, Availability) des gesamten Systems zu gefährden.

Das oben beschriebene Zero-Trust-Modell erfordert eine Hardware-gestützte Trennung zwischen jedem primären Bedrohungsvektor und dem Kern des Systems. Wenn die grundlegenden Funktionsblöcke betrachtet werden, die typischerweise in eingebetteten, verbundenen Geräten vorhanden sind, z.B. smarte Sensoren und IoT-Endknoten, lassen sich typischerweise die folgenden Elemente identifizieren:

  1. Ein Echtzeit-Betriebssystem (RTOS), auf dem eine Reihe von Software- Threads (Tasks) laufen
  2. Eine Reihe von Sensoren und Aktoren zur Steuerung externer physischer Systeme
  3. Eine Netzwerkschnittstelle, die einem Fernangriff ausgesetzt ist
  4. Eine Reihe kryptographischer Algorithmen, die zur Sicherung von Daten in Ruhe und in Bewegung und zur Bereitstellung von Aufmerksamkeitsdiensten für einen Host verwendet werden

Jedes dieser Elemente enthält wahrscheinlich Code von Drittanbietern. Er sollte als nicht vertrauenswürdig eingestuft werden und von den anderen Teilen des Systems isoliert sein.

Die Implementierung des oben genannten Null-Vertrauen-Modells erfordert mindestens vier verschiedene Blöcke funktionaler Trennung – oder »Zonen«. MMUs erlauben nur die Trennung zwischen Nutzer- und Kernfunktionen. Mehrere dieser Blöcke werden traditionell innerhalb einer monolithischen Infrastruktur zusammengefügt. Sie sind daher sehr schwer zu trennen und mit virtuellem Speicher und MMU zu schützen.

Darüber hinaus basieren traditionelle TEEs auf Hardwareprimitiven. TrustZone von Arm ist beispielsweise so konzipiert, dass sie nur einen Funktionsblock isoliert. Dies wird allgemein als »sichere Welt« bezeichnet und üblicherweise zur Kontrolle des Zugriffs auf kryptographische Schlüssel und sicherheitskritische Operationen wie z.B. sicheres Booten verwendet.

Das Haupt-RTOS und alle seine Aufgaben laufen in der verbleibenden einzigen nicht sicheren Welt – ohne dass ein Mechanismus für eine weitere Trennung übrig bleibt. Die inhärente binäre Beschränkung dieser traditionellen Architektur bietet einfach nicht genügend Trennungsebenen für ein modernes Null-Vertrauen-Konzept.

Armv7-M Hardware-Sicherheitsprimitive

Die Implementierung einer eingebetteten TEE erfordert in der Regel zusätzliche spezialisierte Hardware, innerhalb oder außerhalb des Anwendungsprozessors. In der Praxis macht dies die TEE-Implementierung sehr schwierig und anfällig für Fehler und Schwachstellen. Die Armv7-M-Architektur spezifiziert eine Reihe von Hardware-Sicherheitsprimitiven, die die TEE-unterstützende Hardware in fast allen Cortex-M-SoCs verfügbar machen.

Für Cortex-M-Prozessoren sind zwei Modi definiert. Der Handler-Modus ist immer privilegiert, der Thread-Modus dagegen kann privilegierte und unprivilegierte Zugriffsebenen haben.
© Bild: Hex-Five

Bild 1. Für Cortex-M-Prozessoren sind zwei Modi definiert. Der Handler-Modus ist immer privilegiert, der Thread-Modus dagegen kann privilegierte und unprivilegierte Zugriffsebenen haben.

Eine erste Gruppe von Sicherheitsprimitiven, die in Armv7-M-Kernen verfügbar sind, wird durch die Privilegstufen dargestellt. Ein Armv7-M-Mikrocontroller läuft jederzeit in einem bestimmten Modus und auf einer bestimmten Berechtigungsstufe. Gemäß dem Armv7-M-Architektur-Referenzhandbuch können Cortex-M-Prozessoren in zwei Modi laufen: Handler- und Thread-Modus (Bild 1).

Der Handler-Modus ist immer privilegiert, der Thread-Modus dagegen kann privilegierte und unprivilegierte Zugriffsebenen haben. Die Trennung von privilegierten und unprivilegierten Zugriffsebenen ermöglicht die Entwicklung robusterer Systeme. Sie bietet einen grundlegenden Sicherheitsmechanismus, indem die Speicherzugriffe auf bestimmte Regionen kontrolliert werden.

Ein zweites integriertes Sicherheitsmerkmal ist die Speicherschutzeinheit (MPU). Sie ist optional, aber in vielen Cortex-M-Prozessoren weit verbreitet. Die MPU ist ein programmierbarer Hardware-Block, der zur Definition von Berechtigungen für bestimmte Speicherregionen entsprechend den Privilegstufen verwendet werden kann.

Dies ermöglicht die Partitionierung der Funktionen zwischen Ausführungsumgebungen und dem Missbrauch bestimmter Ressourcen – d.h. die Definition des RAM-Speichers als nicht ausführbar (eXecute Never, XN), um den Missbrauch des Pufferspeichers zu begrenzen und Code-Injection-Angriffe zu verhindern.

Herausforderungen bei der Implementierung

TEEs zielen darauf ab, die Hardware-Isolation mehrerer Softwarekomponenten innerhalb des Systems durchzusetzen und gleichzeitig die Vertraulichkeit, Integrität und Verfügbarkeit – also die CIA-Triade – zu wahren. Eine moderne TEE muss dies gewährleisten:

  1. Isolierung von Code, Daten, Unterbrechungen und anderen Ressourcen
  2. Präventive zeitliche Trennung
  3. Funktionen für trap-and-emulate für privilegierte Befehle, um eine transparente Ausführung von Legacy-Anwendungen zu ermöglichen, die nicht so codiert sind, dass sie im unprivilegierten Modus sicher laufen.

Der TEE-Entwickler muss einige besondere Merkmale der Armv7-M-Architektur berücksichtigen, einschließlich der MPU-Konfiguration, spezielle privilegierte und unpräziser Busfehler.

Die in den Armv7-Cortex-M-Mikrocontrollern implementierte MPU kann entweder acht oder sechzehn programmierbare Speicherbereiche mit ihren programmierbaren Startadressen (MPU_RBAR) sowie Größen und Attributen (MPU_RASR) unterstützen. Für eine ordnungsgemäße TEE-Implementierung werden angepasst:

  1. Die Größe der MPU-Regionen durch einen Satz fester, natürlich ausgerichteter Zweierpotenzen (NAPOT, Naturally Aligned Power of Two) im Bereich von 32 Byte bis 4 GB kodiert
  2. Die Basisadresse der Region an die Größe der Region

Aus der Sicht eines Systementwicklers bringt dies harte Einschränkungen mit sich, die entweder zur Verschwendung von wertvollem Speicherplatz oder, noch schlimmer, zu unsachgemäßen Sicherheitseinstellungen führen, die ungeschützte »Löcher« hinterlassen, die äußerst schwierig zu erkennen und zu korrigieren sind.

Besondere privilegierte Anweisungen
Die Armv7-M-Befehlssatzarchitektur (ISA, Instruction Set Architecture) enthält einen genau definierten Satz von privilegierten Anweisungen. Das Hauptproblem bei diesen Befehlen besteht darin, dass sie, wenn sie als Thread im unprivilegierten Modus ausgeführt werden, stillschweigend fehlschlagen, anstatt Ausnahmen bei der Verletzung von Privilegien auszulösen. Dieses Verhalten stellt ein bedeutendes Problem für die TEEs dar, die trap-and-emulate vollständig für Code unterstützen wollen, der für den Betrieb in ungeschütztem Speicherplatz ausgelegt ist.

Nicht spezifizierte Bus-Fehler
Die Armv7-M-Architektur definiert einen auf Systemebene reservierten Speicherbereich namens System Control Space (SCS), der Register für die Systemkonfiguration sowie die Statusberichterstattung und -steuerung bereitstellt. Als ein Speicherbereich werden Lese- und Schreiboperationen in die SCS-Register durch normale Lade- und Speicherbefehle und nicht durch privilegierte MSR- und MRS-Befehle ausgeführt (Tabelle).

Liste der privilegierten Befehle, die keine Ausnahme für privilegierte Verletzungen verursachen, wenn sie im unprivilegierten Thread-Modus ausgeführt werden.
© Quelle: Hex_five

Tabelle. Liste der privilegierten Befehle, die keine Ausnahme für privilegierte Verletzungen verursachen, wenn sie im unprivilegierten Thread-Modus ausgeführt werden.

Der gesamte Systembereich ist jedoch insofern etwas Besonderes, als es sich um einen privilegierten Speicherbereich handelt, in dem die MPU-Richtlinien nicht durchgesetzt werden. Das bedeutet, dass selbst wenn die MPU richtig konfiguriert ist, um unprivilegierten Zugriff auf diesen Bereich zu verhindern, unprivilegierte Lese- und Schreiboperationen Busfehler auslösen, statt Speicherverwaltungsfehler (MemManage).

Je nach der spezifischen Implementierung der Mikroarchitektur können diese nicht spezifizierte Fehler auslösen, die schwierig und teuer zu handhaben sind – da der Kern den Busfehler einige Zyklen später auslöst, ohne die genaue Adresse und/oder Anweisung aufzuzeichnen, die den privilegierten Speicher verletzt hat und die emuliert werden müsste.

Seite 1 von 2

1. Viele vertrauenswürdige Zonen
2. Die Umsetzung der TEE mit mehreren Zonen

Auf Facebook teilenAuf Twitter teilenAuf Linkedin teilenVia Mail teilen

Verwandte Artikel

ARM Germany GmbH