Der GKI- Kernel enthält ein Linux-Kernelmodul namens fips140.ko
, das den FIPS 140-3- Anforderungen für kryptografische Softwaremodule entspricht. Dieses Modul kann zur FIPS-Zertifizierung eingereicht werden, wenn das Produkt, auf dem der GKI-Kernel ausgeführt wird, dies erfordert.
Für den Einsatz der Kryptoroutinen müssen insbesondere folgende FIPS 140-3-Anforderungen erfüllt sein:
- Das Modul muss seine eigene Integrität überprüfen, bevor es kryptografische Algorithmen zur Verfügung stellt.
- Das Modul muss seine genehmigten kryptografischen Algorithmen mithilfe von Selbsttests mit bekannten Antworten testen und verifizieren, bevor es sie zur Verfügung stellt.
Warum ein separates Kernelmodul
Die FIPS 140-3-Validierung basiert auf der Idee, dass ein einmal zertifiziertes software- oder hardwarebasiertes Modul nie mehr geändert wird. Im Falle einer Änderung muss eine Rezertifizierung erfolgen. Dies entspricht nicht ohne weiteres den heute verwendeten Softwareentwicklungsprozessen, und aufgrund dieser Anforderung sind FIPS-Softwaremodule im Allgemeinen so konzipiert, dass sie sich so stark wie möglich auf die kryptografischen Komponenten konzentrieren, um sicherzustellen, dass Änderungen, die nicht mit der Kryptografie zusammenhängen, auch berücksichtigt werden erfordern keine Neubewertung der Kryptographie.
Der GKI-Kernel soll während seiner gesamten unterstützten Lebensdauer regelmäßig aktualisiert werden. Dies macht es unmöglich, dass sich der gesamte Kernel innerhalb der FIPS-Modulgrenze befindet, da ein solches Modul bei jedem Kernel-Update erneut zertifiziert werden müsste. Das Definieren des „FIPS-Moduls“ als Teilmenge des Kernel-Images würde dieses Problem mildern, aber nicht lösen, da sich die binären Inhalte des „FIPS-Moduls“ immer noch viel häufiger als nötig ändern würden.
Vor der Kernel-Version 6.1 war eine weitere Überlegung, dass GKI mit aktiviertem LTO (Link Time Optimization) kompiliert wurde, da LTO eine Voraussetzung für die Kontrollflussintegrität war, eine wichtige Sicherheitsfunktion.
Daher wird der gesamte Code, der von den FIPS 140-3-Anforderungen abgedeckt wird, in ein separates Kernelmodul fips140.ko
gepackt, das nur auf stabilen Schnittstellen basiert, die von der GKI-Kernelquelle bereitgestellt werden, aus der es erstellt wurde. Dies garantiert, dass das Modul mit verschiedenen GKI-Versionen derselben Generation verwendet werden kann und dass es nur dann aktualisiert und erneut zur Zertifizierung eingereicht werden muss, wenn Probleme im Code behoben wurden, der vom Modul selbst getragen wird.
Wann soll das Modul verwendet werden?
Der GKI-Kernel selbst trägt Code, der von den Kryptoroutinen abhängt, die auch im FIPS 140-3-Kernelmodul gepackt sind. Daher werden die integrierten Kryptoroutinen nicht tatsächlich aus dem GKI-Kernel entfernt, sondern in das Modul kopiert. Wenn das Modul geladen wird, werden die integrierten Kryptoroutinen von der Linux CryptoAPI abgemeldet und durch die vom Modul bereitgestellten Routinen ersetzt.
Das bedeutet, dass das Modul fips140.ko
völlig optional ist und seine Bereitstellung nur dann sinnvoll ist, wenn eine FIPS 140-3-Zertifizierung erforderlich ist. Darüber hinaus bietet das Modul keine zusätzliche Funktionalität und ein unnötiges Laden wird sich wahrscheinlich nur auf die Startzeit auswirken, ohne einen Nutzen zu bringen.
So stellen Sie das Modul bereit
Das Modul kann mit den folgenden Schritten in den Android-Build eingebunden werden:
- Fügen Sie den Modulnamen zu
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
hinzu. Dadurch wird das Modul auf die Ramdisk des Herstellers kopiert. - Fügen Sie den Modulnamen zu
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
hinzu. Dadurch wird der Modulname zumodules.load
auf dem Ziel hinzugefügt.modules.load
enthält die Liste der Module, die voninit
beim Booten des Geräts geladen werden.
Der Integritäts-Selbstcheck
Das FIPS 140-3-Kernelmodul nimmt den HMAC-SHA256-Digest seiner eigenen .code
und .rodata
Abschnitte zum Zeitpunkt des Modulladens und vergleicht ihn mit dem im Modul aufgezeichneten Digest. Dies geschieht, nachdem der Linux-Modullader bereits die üblichen Änderungen vorgenommen hat, wie z. B. die ELF-Verlagerungsverarbeitung und das alternative Patchen für CPU-Fehler in diesen Abschnitten. Um sicherzustellen, dass der Digest korrekt reproduziert werden kann, werden folgende zusätzliche Schritte unternommen:
- ELF-Verschiebungen bleiben im Modul erhalten, sodass sie umgekehrt auf die Eingabe des HMAC angewendet werden können.
- Alle anderen Code-Patches sind für das Modul deaktiviert, einschließlich statischer Schlüssel und damit Tracepoints sowie Hersteller-Hooks.
Die Selbsttests mit bekannter Antwort
Alle implementierten Algorithmen, die von den FIPS 140-3-Anforderungen abgedeckt werden, müssen vor der Verwendung einen Selbsttest mit bekannter Antwort durchführen. Gemäß FIPS 140-3 Implementation Guidance 10.3.A ist ein einzelner Testvektor pro Algorithmus unter Verwendung einer der unterstützten Schlüssellängen für Verschlüsselungen ausreichend, sofern sowohl Verschlüsselung als auch Entschlüsselung getestet werden.
Die Linux-CryptoAPI verfügt über eine Vorstellung von Algorithmusprioritäten, bei der mehrere Implementierungen (z. B. eine mit speziellen Kryptoanweisungen und ein Fallback für CPUs, die diese Anweisungen nicht implementieren) desselben Algorithmus nebeneinander existieren können. Daher besteht die Notwendigkeit, alle Implementierungen desselben Algorithmus zu testen. Dies ist notwendig, da die Linux-CryptoAPI es ermöglicht, die prioritätsbasierte Auswahl zu umgehen und stattdessen einen Algorithmus mit niedrigerer Priorität auszuwählen.
Im Modul enthaltene Algorithmen
Alle Algorithmen, die im FIPS 140-3-Modul enthalten sind, sind wie folgt aufgeführt. Dies gilt für die Kernelzweige android12-5.10
, android13-5.10
, android13-5.15
, android14-5.15
und android14-6.1
, wobei gegebenenfalls auf Unterschiede zwischen den Kernelversionen hingewiesen wird.
Algorithmus | Implementierungen | Genehmigend | Definition |
---|---|---|---|
aes | aes-generic , aes-arm64 , aes-ce , AES-Bibliothek | Ja | Einfache AES-Blockverschlüsselung ohne Betriebsmodus: Alle Schlüsselgrößen (128 Bit, 192 Bit und 256 Bit) werden unterstützt. Alle Implementierungen außer der Bibliotheksimplementierung können über eine Vorlage mit einem Betriebsmodus zusammengestellt werden. |
cmac(aes) | cmac (Vorlage), cmac-aes-neon , cmac-aes-ce | Ja | AES-CMAC: Alle AES-Schlüsselgrößen werden unterstützt. Die cmac Vorlage kann mit jeder Implementierung von aes unter Verwendung cmac(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. |
ecb(aes) | ecb (Vorlage), ecb-aes-neon , ecb-aes-neonbs , ecb-aes-ce | Ja | AES-ECB: Alle AES-Schlüsselgrößen werden unterstützt. Die ecb Vorlage kann mit jeder Implementierung von aes unter Verwendung ecb(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. |
cbc(aes) | cbc (Vorlage), cbc-aes-neon , cbc-aes-neonbs , cbc-aes-ce | Ja | AES-CBC: Alle AES-Schlüsselgrößen werden unterstützt. Die cbc Vorlage kann mit jeder Implementierung von aes unter Verwendung von ctr(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. |
cts(cbc(aes)) | cts (Vorlage), cts-cbc-aes-neon , cts-cbc-aes-ce | Ja | AES-CBC-CTS oder AES-CBC mit Geheimtextdiebstahl: Die verwendete Konvention ist CS3 ; Die letzten beiden Geheimtextblöcke werden bedingungslos ausgetauscht. Alle AES-Schlüsselgrößen werden unterstützt. Die cts Vorlage kann mit jeder Implementierung von cbc unter Verwendung cts(<cbc(aes)-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. |
ctr(aes) | ctr (Vorlage), ctr-aes-neon , ctr-aes-neonbs , ctr-aes-ce | Ja | AES-CTR: Alle AES-Schlüsselgrößen werden unterstützt. Die ctr Vorlage kann mit jeder Implementierung von aes unter Verwendung von ctr(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. |
xts(aes) | xts (Vorlage), xts-aes-neon , xts-aes-neonbs , xts-aes-ce | Ja | AES-XTS: Alle AES-Schlüsselgrößen werden unterstützt. Die xts Vorlage kann mit jeder Implementierung von ecb(aes) mithilfe von xts(<ecb(aes)-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig. Alle Implementierungen implementieren die von FIPS geforderte Prüfung auf schwache Schlüssel; Das heißt, XTS-Schlüssel, deren erste und zweite Hälfte gleich sind, werden abgelehnt. |
gcm(aes) | gcm (Vorlage), gcm-aes-ce | Nr. 1 | AES-GCM: Alle AES-Schlüsselgrößen werden unterstützt. Es werden nur 96-Bit-IVs unterstützt. Wie bei allen anderen AES-Modi in diesem Modul ist der Anrufer für die Bereitstellung der IVs verantwortlich. Die gcm Vorlage kann mit beliebigen Implementierungen von ctr(aes) und ghash unter Verwendung von gcm_base(<ctr(aes)-impl>,<ghash-impl>) zusammengestellt werden. Die anderen Implementierungen sind eigenständig. |
sha1 | sha1-generic , sha1-ce | Ja | Kryptografische Hash-Funktion SHA-1 |
sha224 | sha224-generic , sha224-arm64 , sha224-ce | Ja | Kryptografische Hash-Funktion SHA-224: Der Code wird mit SHA-256 geteilt. |
sha256 | sha256-generic , sha256-arm64 , sha256-ce , SHA-256-Bibliothek | Ja | Kryptografische Hash-Funktion SHA-256: Zusätzlich zur herkömmlichen CryptoAPI-Schnittstelle wird für SHA-256 eine Bibliotheksschnittstelle bereitgestellt. Diese Bibliotheksschnittstelle verwendet eine andere Implementierung. |
sha384 | sha384-generic , sha384-arm64 , sha384-ce | Ja | Kryptografische Hash-Funktion SHA-384: Der Code wird mit SHA-512 geteilt. |
sha512 | sha512-generic , sha512-arm64 , sha512-ce | Ja | Kryptografische Hash-Funktion SHA-512 |
hmac | hmac (Vorlage) | Ja | HMAC (Keyed-Hash Message Authentication Code): Die hmac Vorlage kann mit jedem SHA-Algorithmus oder jeder SHA-Implementierung unter Verwendung von hmac(<sha-alg>) oder hmac(<sha-impl>) erstellt werden. |
stdrng | drbg_pr_hmac_sha1 , drbg_pr_hmac_sha256 , drbg_pr_hmac_sha384 , drbg_pr_hmac_sha512 | Ja | HMAC_DRBG instanziiert mit der benannten Hash-Funktion und mit aktivierter Vorhersageresistenz: Integritätsprüfungen sind enthalten. Benutzer dieser Schnittstelle erhalten ihre eigenen DRBG-Instanzen. |
stdrng | drbg_nopr_hmac_sha1 , drbg_nopr_hmac_sha256 , drbg_nopr_hmac_sha384 , drbg_nopr_hmac_sha512 | Ja | Wie die drbg_pr_* Algorithmen, jedoch mit deaktivierter Vorhersageresistenz. Der Code wird mit der vorhersageresistenten Variante geteilt. In Kernel-Version 5.10 ist drbg_nopr_hmac_sha256 der DRBG mit der höchsten Priorität. In Kernel-Version 5.15 und höher ist es drbg_pr_hmac_sha512 . |
jitterentropy_rng | jitterentropy_rng | NEIN | Version 2.2.0 des Jitter RNG : Benutzer dieser Schnittstelle erhalten ihre eigenen Jitter RNG-Instanzen. Sie verwenden die von den DRBGs verwendeten Instanzen nicht wieder. |
xcbc(aes) | xcbc-aes-neon , xcbc-aes-ce | NEIN | |
xctr(aes) | xctr-aes-neon , xctr-aes-ce | NEIN | Nur in Kernel-Version 5.15 und höher vorhanden. |
cbcmac(aes) | cbcmac-aes-neon , cbcmac-aes-ce | NEIN | |
essiv(cbc(aes),sha256) | essiv-cbc-aes-sha256-neon , essiv-cbc-aes-sha256-ce | NEIN |
Erstellen des Moduls aus dem Quellcode
Auf Android 14 und höher (einschließlich android-mainline
) kann das fips140.ko
Modul aus den GKI-Kernelquellen erstellt werden, indem Folgendes verwendet wird:
tools/bazel run //common:fips140_dist
Unter Android 13 und niedriger kann das fips140.ko
Modul aus den GKI-Kernelquellen erstellt werden mit:
BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Dadurch wird der vollständige Build mit dem Kernel und dem fips140.ko
Modul durchgeführt, wobei der korrekte HMAC-SHA256-Digest seines Inhalts eingebettet ist.
Erstellen Sie in Android 14 und höher mit Bazel statt build/build.sh
indem Sie den folgenden Befehl verwenden:
tools/bazel run //common:fips140_dist
Anleitung für Endbenutzer
Anleitung für den Krypto-Beauftragten
Um das Kernelmodul bedienen zu können, muss das Betriebssystem auf einen einzigen Bedienermodus beschränkt sein. Dies wird von Android automatisch mithilfe der Speicherverwaltungshardware im Prozessor erledigt.
Das Kernelmodul kann nicht separat installiert werden; Es ist Teil der Geräte-Firmware und wird beim Booten automatisch geladen. Der Betrieb erfolgt nur in einer zugelassenen Betriebsart.
Der Crypto Officer kann die Durchführung der Selbsttests jederzeit durch einen Neustart des Gerätes veranlassen.
Benutzerführung
Die Benutzer des Kernelmoduls sind andere Kernelkomponenten, die kryptografische Algorithmen verwenden müssen. Das Kernelmodul stellt keine zusätzliche Logik bei der Verwendung der Algorithmen bereit und speichert keine Parameter über die Zeit hinaus, die für die Durchführung einer kryptografischen Operation erforderlich ist.
Die Verwendung der Algorithmen zum Zwecke der FIPS-Konformität ist auf genehmigte Algorithmen beschränkt. Um die FIPS 140-3-Anforderung „Service Indicator“ zu erfüllen, stellt das Modul eine Funktion fips140_is_approved_service
bereit, die angibt, ob ein Algorithmus genehmigt ist.
Fehler beim Selbsttest
Im Falle eines Selbsttestfehlers führt das Kernelmodul dazu, dass der Kernel in Panik gerät und das Gerät nicht weiter bootet. Wenn das Problem durch einen Neustart des Geräts nicht behoben wird, muss das Gerät im Wiederherstellungsmodus starten, um das Problem durch ein erneutes Flashen des Geräts zu beheben.
Es wird erwartet, dass die AES-GCM-Implementierungen des Moduls „vom Algorithmus genehmigt“, aber nicht „vom Modul genehmigt“ werden können. Sie können validiert werden, AES-GCM kann jedoch aus Sicht des FIPS-Moduls nicht als genehmigter Algorithmus betrachtet werden. Dies liegt daran, dass die FIPS-Modulanforderungen für GCM nicht mit GCM-Implementierungen kompatibel sind, die keine eigenen IVs generieren. ↩