GKI-Kryptomodul, das gemäß FIPS 140-3 zertifiziert ist

Der GKI-Kernel enthält ein Linux-Kernelmodul namens fips140.ko, das die Anforderungen von FIPS 140-3 für kryptografische Softwaremodule erfüllt. Dieses Modul kann zur FIPS-Zertifizierung eingereicht werden, wenn dies für das Produkt, in dem der GKI-Kernel ausgeführt wird, erforderlich ist.

Insbesondere müssen die folgenden FIPS 140-3-Anforderungen erfüllt sein, bevor die Krypto-Routinen verwendet werden können:

  • Das Modul muss seine eigene Integrität prüfen, bevor kryptografische Algorithmen verfügbar gemacht werden.
  • Das Modul muss seine genehmigten kryptografischen Algorithmen mithilfe von Selbsttests mit bekannten Antworten testen und überprüfen, bevor sie verfügbar gemacht werden.

Warum ein separates Kernelmodul

Die FIPS 140-3-Validierung basiert auf der Annahme, dass ein software- oder hardwarebasiertes Modul nach der Zertifizierung nicht mehr geändert wird. Andernfalls muss es noch einmal zertifiziert werden. Dies entspricht nicht den derzeit verwendeten Softwareentwicklungsprozessen. Aufgrund dieser Anforderung sind FIPS-Softwaremodule in der Regel so konzipiert, dass sie sich so eng wie möglich auf die kryptografischen Komponenten konzentrieren, damit Änderungen, die nicht mit der Kryptografie zusammenhängen, keine Neubewertung der Kryptografie erfordern.

Der GKI-Kernel soll während der gesamten unterstützten Lebensdauer regelmäßig aktualisiert werden. Daher ist es nicht möglich, dass sich der gesamte Kernel innerhalb der FIPS-Modulgrenze befindet, da ein solches Modul bei jeder Kernelaktualisierung neu zertifiziert werden müsste. Wenn das „FIPS-Modul“ als Teil des Kernel-Images definiert wird, wird dieses Problem zwar gemildert, aber nicht gelöst, da sich der Binärinhalt des „FIPS-Moduls“ immer noch viel häufiger als nötig ändern würde.

Vor der Kernelversion 6.1 war ein weiterer Aspekt, dass GKI mit aktivierter LTO (Link Time Optimization) kompiliert wurde, da LTO eine Voraussetzung für die Control Flow Integrity ist, eine wichtige Sicherheitsfunktion.

Daher wird der gesamte Code, der den FIPS 140-3-Anforderungen unterliegt, in einem separaten Kernelmodul fips140.ko verpackt, das nur auf stabilen Schnittstellen basiert, die von der GKI-Kernelquelle bereitgestellt werden, aus der es erstellt wurde. Das bedeutet, dass das Modul mit verschiedenen GKI-Releases derselben Generation verwendet werden kann und nur aktualisiert und zur Zertifizierung noch einmal eingereicht werden muss, wenn Probleme im Code behoben wurden, der sich im Modul selbst befindet.

Einsatzmöglichkeiten des Moduls

Der GKI-Kernel selbst enthält Code, der von den Krypto-Routinen abhängt, die auch im FIPS 140-3-Kernelmodul enthalten sind. Daher werden die integrierten Krypto-Routinen nicht aus dem GKI-Kernel verschoben, sondern in das Modul kopiert. Wenn das Modul geladen wird, werden die integrierten Krypto-Routinen von der Linux CryptoAPI abgemeldet und durch die vom Modul bereitgestellten ersetzt.

Das fips140.ko-Modul ist also völlig optional und sollte nur bereitgestellt werden, wenn eine FIPS 140-3-Zertifizierung erforderlich ist. Darüber hinaus bietet das Modul keine zusätzlichen Funktionen. Wenn es unnötig geladen wird, wirkt sich das wahrscheinlich nur auf die Bootzeit aus, ohne einen Vorteil zu bieten.

Modul bereitstellen

Das Modul kann mit den folgenden Schritten in den Android-Build eingefügt werden:

  • Fügen Sie BOARD_VENDOR_RAMDISK_KERNEL_MODULES den Namen des Moduls hinzu. Dadurch wird das Modul in das RAM-Disk des Anbieters kopiert.
  • Fügen Sie BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD den Namen des Moduls hinzu. Dadurch wird der Modulname modules.load im Ziel hinzugefügt. modules.load enthält die Liste der Module, die von init beim Starten des Geräts geladen werden.

Selbsttest der Integrität

Das FIPS 140-3-Kernelmodul nimmt beim Laden des Moduls den HMAC-SHA256-Digest seiner eigenen .code- und .rodata-Abschnitte und vergleicht ihn mit dem im Modul aufgezeichneten Digest. Dies geschieht, nachdem der Linux-Modul-Ladeprogramm die üblichen Änderungen wie die ELF-Umsetzung und alternative Patches für CPU-Fehler an diesen Abschnitten vorgenommen hat. Die folgenden zusätzlichen Schritte werden ausgeführt, damit der Digest korrekt reproduziert werden kann:

  • ELF-Verschiebungen bleiben im Modul erhalten, damit sie in umgekehrter Reihenfolge auf die Eingabe des HMAC angewendet werden können.
  • Das Modul macht alle Code-Patches rückgängig, die vom Kernel für den dynamischen Schatten-Stack vorgenommen wurden. Insbesondere ersetzt das Modul alle Anweisungen, die vom Schatten-Callstack auf den Stack schieben oder vom Stack poppen, durch die ursprünglich vorhandenen Pointer Authentication Code (PAC)-Anweisungen.
  • Alle anderen Code-Patches sind für das Modul deaktiviert, einschließlich statischer Schlüssel und damit auch Tracepoints sowie Anbieter-Hooks.

Selbsttests mit bekannten Antworten

Alle implementierten Algorithmen, die den FIPS 140-3-Anforderungen unterliegen, müssen vor der Verwendung einen Selbsttest mit bekannten Antworten durchführen. Gemäß der FIPS 140-3-Implementierungsanleitung 10.3.A ist für Chiffren ein einzelner Testvektor pro Algorithmus mit einer beliebigen der unterstützten Schlüssellängen ausreichend, solange sowohl Verschlüsselung als auch Entschlüsselung getestet werden.

Die Linux CryptoAPI kennt Algorithmusprioritäten, bei denen 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 müssen alle Implementierungen desselben Algorithmus getestet werden. Das ist notwendig, da die Linux CryptoAPI die prioritätsbasierte Auswahl umgehen und stattdessen einen Algorithmus mit niedrigerer Priorität auswählen lässt.

Im Modul enthaltene Algorithmen

Alle Algorithmen, die im FIPS 140-3-Modul enthalten sind, sind nachfolgend aufgeführt. Dies gilt für die Kernel-Branches android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1 und android15-6.6. Unterschiede zwischen den Kernelversionen werden gegebenenfalls vermerkt.

Algorithmus Implementierungen Genehmigungsfähig Definition
aes aes-generic, aes-arm64, aes-ce, AES-Bibliothek Ja AES-Blockverschlüsselung ohne Betriebsmodus: Alle Schlüsselgrößen (128 Bit, 192 Bit und 256 Bit) werden unterstützt. Alle Implementierungen mit Ausnahme der Bibliotheksimplementierung können über eine Vorlage mit einem Betriebsmodus kombiniert 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 mithilfe von 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 mithilfe von 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 mithilfe 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 mithilfe von 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 mithilfe 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: In der Kernelversion 6.1 und niedriger werden alle AES-Schlüsselgrößen unterstützt. In der Kernelversion 6.6 und höher werden nur AES-128 und AES-256 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 bedeutet, dass XTS-Schlüssel, deren erste und zweite Hälfte gleich sind, abgelehnt werden.
gcm(aes) gcm (Vorlage), gcm-aes-ce Nein1 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 Aufrufer für die Bereitstellung der IVs verantwortlich. Die gcm-Vorlage kann mit allen Implementierungen von ctr(aes) und ghash mithilfe von gcm_base(<ctr(aes)-impl>,<ghash-impl>) erstellt werden. Die anderen Implementierungen sind eigenständig.
sha1 sha1-generic, sha1-ce Ja Kryptografische SHA-1-Hash-Funktion
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 SHA-256-Hash-Funktion: Zusätzlich zur standardmäßigen CryptoAPI-Schnittstelle wird für SHA-256 eine Bibliotheksschnittstelle bereitgestellt. Diese Bibliothek-Schnittstelle 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
sha3-224 sha3-224-generic Ja Kryptografische Hash-Funktion SHA3-224. Nur in Kernelversion 6.6 und höher vorhanden.
sha3-256 sha3-256-generic Ja Wie zuvor, aber mit einer Digest-Länge von 256 Bit (SHA3-256). Für alle Digestlängen wird dieselbe Keccak-Implementierung verwendet.
sha3-384 sha3-384-generic Ja Wie zuvor, jedoch mit einer Digestlänge von 384 Bit (SHA3-384). Für alle Digestlängen wird dieselbe Keccak-Implementierung verwendet.
sha3-512 sha3-512-generic Ja Wie zuvor, aber mit einer Digestlänge von 512 Bit (SHA3-512). Für alle Digestlängen wird dieselbe Keccak-Implementierung verwendet.
hmac hmac (Vorlage) Ja HMAC (Keyed-Hash Message Authentication Code): Die hmac-Vorlage kann mit jedem SHA-Algorithmus oder jeder SHA-Implementierung mit 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: Es sind Systemdiagnosen enthalten. Nutzer dieser Benutzeroberfläche erhalten eigene DRBG-Instanzen.
stdrng drbg_nopr_hmac_sha1, drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512 Ja Entspricht den drbg_pr_*-Algorithmen, aber ohne Deaktivierung der Vorhersageresistenz. Der Code wird für die variante verwendet, die nicht durch Vorhersagen beeinflusst wird. In der Kernelversion 5.10 hat das DRBG mit der höchsten Priorität die Kennung drbg_nopr_hmac_sha256. In der Kernelversion 5.15 und höher ist es drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng Nein Der Jitter-RNG, entweder Version 2.2.0 (Kernelversion 6.1 und niedriger) oder Version 3.4.0 (Kernelversion 6.6 und höher). Nutzer dieser Benutzeroberfläche erhalten eigene Jitter-RNG-Instanzen. Die von den DRBGs verwendeten Instanzen werden nicht wiederverwendet.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce Nein
xctr(aes) xctr-aes-neon, xctr-aes-ce Nein Nur in Kernelversion 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

Modul aus Quellcode erstellen

Für Android 14 und höher (einschließlich android-mainline) erstellen Sie das fips140.ko-Modul mit den folgenden Befehlen aus der Quelle.

  • Mit Bazel erstellen:

    tools/bazel run //common:fips140_dist
  • Mit build.sh (alt) erstellen:

    BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh

Mit diesen Befehlen wird ein vollständiger Build ausgeführt, einschließlich des Kernels und des fips140.ko-Moduls mit dem eingebetteten HMAC-SHA256-Digest-Inhalt.

Anleitung für Endnutzer

Leitfaden für Krypto-Officer

Zum Betrieb des Kernel-Moduls muss das Betriebssystem auf einen einzelnen Betriebsmodus beschränkt werden. Dies wird von Android automatisch mithilfe der Speicherverwaltungshardware im Prozessor verwaltet.

Das Kernelmodul kann nicht separat installiert werden. Es ist Teil der Gerätefirmware und wird beim Starten automatisch geladen. Sie wird nur in einem genehmigten Betriebsmodus betrieben.

Der Krypto-Beauftragte kann die Selbsttests jederzeit durch einen Neustart des Geräts ausführen lassen.

Anleitung für Nutzer

Nutzer des Kernelmoduls sind andere Kernelkomponenten, die kryptografische Algorithmen verwenden müssen. Das Kernelmodul bietet keine zusätzliche Logik bei der Verwendung der Algorithmen und speichert keine Parameter über die Zeit hinaus, die für die Ausführung eines kryptografischen Vorgangs erforderlich ist.

Die Verwendung der Algorithmen zur Einhaltung der FIPS-Compliance ist auf genehmigte Algorithmen beschränkt. Um die FIPS 140-3-Anforderung an den „Dienstindikator“ zu erfüllen, stellt das Modul die Funktion fips140_is_approved_service bereit, die angibt, ob ein Algorithmus genehmigt ist.

Fehler beim Selbsttest

Bei einem Fehler beim Selbsttest führt das Kernel-Modul dazu, dass der Kernel in den Notfallmodus wechselt und das Gerät nicht weiter hochfährt. Wenn das Problem durch einen Neustart des Geräts nicht behoben wird, muss es im Wiederherstellungsmodus gestartet werden, um das Problem durch einen Neu-Flash des Geräts zu beheben.


  1. Es wird erwartet, dass die AES-GCM-Implementierungen des Moduls als „Algorithmus genehmigt“ eingestuft werden können, aber nicht als „Modul genehmigt“. Sie können validiert werden, aber AES-GCM kann aus Sicht eines FIPS-Moduls nicht als genehmigter Algorithmus betrachtet werden. Das liegt daran, dass die FIPS-Modulanforderungen für GCM nicht mit GCM-Implementierungen kompatibel sind, die keine eigenen IV generieren.