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

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 dies für das Produkt, auf dem der GKI-Kernel ausgeführt wird, erforderlich ist.

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

  • Das Modul muss seine eigene Integrität prüfen, bevor es kryptografische Algorithmen zur Verfügung stellt.
  • Das Modul muss seine genehmigten kryptografischen Algorithmen mit kryptografischen Algorithmus-Selbsttests ausführen und überprüfen, bevor es sie zur Verfügung stellt.

Warum ein separates Kernelmodul?

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

Der GKI-Kernel soll während seiner gesamten unterstützten Lebensdauer regelmäßig aktualisiert werden. Daher ist es nicht möglich, den gesamten Kernel innerhalb der FIPS-Modulgrenze zu platzieren, da ein solches Modul bei jeder Kernelaktualisierung neu zertifiziert werden müsste. Wenn das „FIPS-Modul“ als Teilmenge des Kernel-Image definiert wird, wird dieses Problem zwar gemildert, aber nicht gelöst, da sich die Binärinhalte des „FIPS-Moduls“ immer noch viel häufiger ändern würden als erforderlich.

Vor Kernel-Version 6.1 wurde GKI mit aktivierter LTO (Link Time Optimization) kompiliert, da LTO eine Voraussetzung für die Control Flow Integrity war, 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 eingereicht werden muss, wenn Probleme im Code behoben wurden, der vom Modul selbst ausgeführt wird.

Wann sollte das Modul verwendet werden?

Der GKI-Kernel selbst enthält Code, der von den Kryptoroutinen abhängt, die ebenfalls im FIPS 140-3-Kernelmodul enthalten sind. Daher werden die integrierten Kryptoroutinen nicht 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 ausgeführten Routinen ersetzt.

Das bedeutet, dass das Modul fips140.ko völlig optional ist und nur bereitgestellt werden sollte, wenn eine FIPS 140-3-Zertifizierung erforderlich ist. Darüber hinaus bietet das Modul keine zusätzlichen Funktionen und das unnötige Laden kann sich nur auf die Startzeit auswirken, ohne einen Vorteil zu bieten.

Modul bereitstellen

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 in die Vendor-Ramdisk kopiert.
  • Fügen Sie den Modulnamen zu BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD hinzu. Dadurch wird der Modulname auf dem Zielgerät zu modules.load hinzugefügt. modules.load enthält die Liste der Module, die von init beim Starten des Geräts geladen werden.

Integritätsprüfung

Das FIPS 140-3-Kernelmodul verwendet bei der Ladezeit des Moduls den HMAC-SHA256-Digest seiner eigenen Abschnitte .code und .rodata und vergleicht ihn mit dem im Modul aufgezeichneten Digest. Dies erfolgt, nachdem der Linux-Modul-Loader bereits die üblichen Änderungen an diesen Abschnitten vorgenommen hat, z. B. die Verarbeitung der ELF-Verschiebung und das Patchen von Alternativen für CPU-Fehler. Die folgenden zusätzlichen Schritte werden ausgeführt, um sicherzustellen, dass der Digest korrekt reproduziert werden kann:

  • ELF-Verschiebungen bleiben im Modul erhalten, damit sie umgekehrt auf die Eingabe des HMAC angewendet werden können.
  • Das Modul macht alle Code-Patches rückgängig, die vom Kernel für Dynamic Shadow Call Stack vorgenommen wurden. Insbesondere ersetzt das Modul alle Anweisungen, die Daten aus dem Shadow Call Stack abrufen oder in ihn schreiben, durch die ursprünglich vorhandenen PAC-Anweisungen (Pointer Authentication Code).
  • Alle anderen Code-Patches sind für das Modul deaktiviert, einschließlich statischer Schlüssel und damit auch Tracepoints sowie Vendor-Hooks.

Selbsttests für kryptografische Algorithmen

Das FIPS 140-3-Kernelmodul erfüllt die Anforderungen für Selbsttests für kryptografische Algorithmen von FIPS 140-3 durch die Implementierung von Tests mit bekannten Antworten. Die implementierten Tests variieren je nach Algorithmus und entsprechen der FIPS 140-3-Implementierungsanleitung 10.3.A.

In der Regel ist nur ein Testvektor pro Algorithmus erforderlich. Die FIPS-Selbsttests für kryptografische Algorithmen dienen nur zur Validierung der grundlegenden Funktionen. Umfassende Tests werden separat mit dem Cryptographic Algorithm Validation Program (CAVP) und der kryptografischen Testsuite des Upstream-Kernels durchgeführt.

Wenn ein Algorithmus mehrere Implementierungen hat, auf die der Nutzer zugreifen kann oder die von den Diensten des Moduls verwendet werden, müssen gemäß FIPS 140-3 alle diese Implementierungen selbst getestet werden. Dies ist relevant für die Integrationsstrategie, die traditionell von der Linux CryptoAPI verwendet wird, bei der jeder Algorithmus mehrere für Nutzer zugängliche Implementierungen haben kann. Im Kernel android16-6.12 hat SHA-256 beispielsweise drei Implementierungen: sha256-generic, sha256-arm64 und sha256-ce. Auf CPUs mit den ARMv8-Kryptoerweiterungen wird standardmäßig sha256-ce verwendet, aber Nutzer können weiterhin explizit auf die anderen zugreifen. Daher werden alle drei Implementierungen vom Modul selbst getestet.

Im Kernel android17-6.18 und höher verwenden einige Algorithmen eine einfachere Integrationsstrategie. Im Kernel android17-6.18 hat SHA-256 beispielsweise eine einzige Implementierung sha256-lib, die beim Laden des Moduls automatisch den geeigneten Code für die CPU auswählt. Daher testet das Modul nur sha256-lib selbst.

Im Modul enthaltene Algorithmen

Alle im FIPS 140-3-Modul enthaltenen Algorithmen sind unten aufgeführt. Dies gilt für die Kernel-Branches android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1, android15-6.6, android16-6.12 und android17-6.18. Unterschiede zwischen den Kernelversionen werden gegebenenfalls angegeben.

Algorithmus Implementierungen Genehmigungsfähig Definition
aes aes-generic, aes-arm64, aes-ce, AES-Bibliothek Ja Einfache AES-Blockverschlüsselung ohne Betriebsmodus: Alle Schlüssellängen (128 Bit, 192 Bit und 256 Bit) werden unterstützt. Alle Implementierungen außer 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üssellängen werden unterstützt. Die cmac Vorlage kann mit jeder Implementierung von aes mit cmac() kombiniert 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üssellängen werden unterstützt. Die Vorlage ecb kann mit jeder Implementierung von aes mit ecb() kombiniert 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üssellängen werden unterstützt. Die cbc Vorlage kann mit jeder Implementierung von aes mit cbc() kombiniert 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 Ciphertext Stealing: Die verwendete Konvention ist CS3. Die letzten beiden Ciphertext-Blöcke werden bedingungslos ausgetauscht. Alle AES-Schlüssellängen werden unterstützt. Die cts Vorlage kann mit jeder Implementierung von cbc mit cts() kombiniert 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üssellängen werden unterstützt. Die ctr Vorlage kann mit jeder Implementierung von aes mit ctr() kombiniert werden. Die anderen Implementierungen sind eigenständig.
xts(aes) xts (Vorlage), xts-aes-neon, xts-aes-neonbs, xts-aes-ce Ja AES-XTS: In Kernel 6.1 und niedriger werden alle AES-Schlüssellängen unterstützt. In Kernel 6.6 und höher werden nur AES-128 und AES-256 unterstützt. Die xts Vorlage kann mit jeder Implementierung von ecb(aes) mit xts() kombiniert werden. Die anderen Implementierungen sind eigenständig. Alle Implementierungen führen die von FIPS geforderte Überprüfung auf schwache Schlüssel durch. Das heißt, XTS-Schlüssel, deren erste und zweite Hälfte gleich sind, werden abgelehnt.
gcm(aes) gcm (Vorlage), gcm-aes-ce Nein 1 AES-GCM: Alle AES-Schlüssellängen werden unterstützt. Nur 96-Bit-IVs werden 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 jeder Implementierung von ctr(aes) und ghash mit gcm_base(,) kombiniert werden. Die anderen Implementierungen sind eigenständig.
sha1 Kernel 6.12 und niedriger: sha1-generic, sha1-ce Ja Die kryptografische Hash-Funktion SHA-1. In Kernel 6.18 und höher entfernt.
sha224 Kernel 6.18 und höher: sha224-lib. Kernel 6.12 und niedriger: sha224-generic, sha224-arm64, sha224-ce Ja Kryptografische Hash-Funktion SHA-224: Der Code wird mit SHA-256 geteilt.
sha256 Kernel 6.18 und höher: sha256-lib. Kernel 6.12 und niedriger: sha256-generic, sha256-arm64, sha256-ce, SHA-256-Bibliothek Ja Kryptografische Hash-Funktion SHA-256.
sha384 Kernel 6.18 und höher: sha384-lib. Kernel 6.12 und niedriger: sha384-generic, sha384-arm64, sha384-ce Ja Kryptografische Hash-Funktion SHA-384: Der Code wird mit SHA-512 geteilt.
sha512 Kernel 6.18 und höher: sha512-lib. Kernel 6.12 und niedriger: sha512-generic, sha512-arm64, sha512-ce Ja Kryptografische Hash-Funktion SHA-512.
sha3-224 Kernel 6.6 und höher: sha3-224-generic Ja Kryptografische Hash-Funktion SHA3-224.
sha3-256 Kernel 6.6 und höher: sha3-256-generic Ja Wie oben, aber mit einer Digest-Länge von 256 Bit (SHA3-256). Alle Digest-Längen verwenden dieselbe Keccak-Implementierung.
sha3-384 Kernel 6.6 und höher: sha3-384-generic Ja Wie oben, aber mit einer Digest-Länge von 384 Bit (SHA3-384). Alle Digest-Längen verwenden dieselbe Keccak-Implementierung.
sha3-512 Kernel 6.6 und höher: sha3-512-generic Ja Wie oben, aber mit einer Digest-Länge von 512 Bit (SHA3-512). Alle Digest-Längen verwenden dieselbe Keccak-Implementierung.
hmac hmac (Vorlage) Ja Keyed-Hash Message Authentication Code (HMAC): Die hmac Vorlage kann mit jedem SHA-Algorithmus oder jeder Implementierung mit hmac() oder hmac() kombiniert werden.
stdrng Alle Kernel: drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512. Kernel 6.6 und niedriger: drbg_pr_hmac_sha1 Ja HMAC_DRBG, instanziiert mit der genannten Hash-Funktion und aktivierter Vorhersagebeständigkeit: Gesundheitsprüfungen sind enthalten. Nutzer dieser Schnittstelle erhalten eigene DRBG-Instanzen.
stdrng Alle Kernel: drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512. Kernel 6.6 und niedriger: drbg_nopr_hmac_sha1 Ja Wie die drbg_pr_*-Algorithmen, aber mit deaktivierter Vorhersagebeständigkeit. Der Code wird mit der vorhersagebeständigen Variante geteilt. In Kernel 5.10 ist drbg_nopr_hmac_sha256 der DRBG mit der höchsten Priorität. In Kernel 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 Schnittstelle erhalten eigene Jitter RNG-Instanzen. Sie verwenden nicht die Instanzen, die von den DRBGs verwendet werden.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce Nein
xctr(aes) Kernel 5.15 und höher: xctr-aes-neon, xctr-aes-ce Nein
cbcmac(aes) cbcmac-aes-neon, cbcmac-aes-ce Nein
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce Nein

1. Die AES-GCM-Implementierungen des Moduls können algorithmisch, aber nicht modulbezogen genehmigt werden. 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 IVs generieren.

Modul aus Quelle erstellen

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

  • Mit Bazel erstellen:

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

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

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

Anleitung für Endnutzer

Anleitung für Crypto Officer

Um das Kernelmodul zu verwenden, muss das Betriebssystem auf einen einzelnen Betriebsmodus beschränkt sein. Dies wird von Android automatisch mit der Speicherverwaltungshardware im Prozessor erledigt.

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

Der Crypto Officer kann die Selbsttests jederzeit ausführen lassen, indem er das Gerät neu startet.

Anleitung für Nutzer

Die 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-Anforderungen ist auf genehmigte Algorithmen beschränkt. Um die FIPS 140-3-Anforderung für den „Dienstindikator“ zu erfüllen, bietet das Modul eine Funktion fips140_is_approved_service, die angibt, ob ein Algorithmus genehmigt ist.

Fehler bei Selbsttests

Wenn ein Selbsttest fehlschlägt, führt das Kernelmodul dazu, dass der Kernel abstürzt und das Gerät nicht weiter startet. Wenn das Problem durch einen Neustart des Geräts nicht behoben wird, muss das Gerät im Wiederherstellungsmodus gestartet werden, um das Problem durch erneutes Flashen des Geräts zu beheben.