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

Der GKI-Kernel enthält ein Linux-Kernel-Modul namens fips140.ko, das den Anforderungen von FIPS 140-3 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.

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

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

Warum ein separates Kernel-Modul?

Die FIPS 140‑3-Validierung basiert auf der Annahme, dass ein software- oder hardwarebasiertes Modul nach der Zertifizierung nicht mehr geändert wird. Wenn sich die Zertifizierung ändert, muss sie neu zertifiziert werden. Dies entspricht nicht ohne Weiteres 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, um sicherzustellen, dass Änderungen, die nicht mit der Kryptografie zusammenhängen, keine Neubewertung der Kryptografie erfordern.

Der GKI-Kernel soll während seines gesamten unterstützten Lebenszyklus regelmäßig aktualisiert werden. Daher ist es nicht möglich, den gesamten Kernel innerhalb der FIPS-Modulgrenze zu platzieren, da ein solches Modul bei jedem Kernel-Update neu zertifiziert werden müsste. Wenn das „FIPS-Modul“ als Teilmenge des Kernel-Images definiert wird, wird dieses Problem zwar gemildert, aber nicht gelöst, da sich die binären Inhalte des „FIPS-Moduls“ immer noch viel häufiger als nötig ändern würden.

Vor Kernelversion 6.1 wurde GKI mit aktivierter LTO (Link Time Optimization) kompiliert, da LTO eine Voraussetzung für Control Flow Integrity war, ein wichtiges Sicherheitsfeature.

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 vom GKI-Kernelquellcode bereitgestellt werden, aus dem es erstellt wurde. Das bedeutet, dass das Modul mit verschiedenen GKI-Releases derselben Generation verwendet werden kann und nur dann aktualisiert und zur Zertifizierung eingereicht werden muss, wenn Probleme im Code behoben wurden, der vom Modul selbst übertragen wird.

Wann sollte das Modul verwendet werden?

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

Das bedeutet, dass das fips140.ko-Modul völlig optional ist und es nur sinnvoll ist, es bereitzustellen, wenn eine FIPS 140-3-Zertifizierung erforderlich ist. Darüber hinaus bietet das Modul keine zusätzlichen Funktionen. Das unnötige Laden des Moduls wirkt sich wahrscheinlich nur auf die Bootzeit aus, ohne dass dies einen Vorteil bietet.

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 dem modules.load auf dem Ziel 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 berechnet beim Laden des Moduls den HMAC-SHA256-Digest der Abschnitte .code und .rodata und vergleicht ihn mit dem im Modul aufgezeichneten Digest. Dies erfolgt, nachdem der Linux-Modul-Loader bereits die üblichen Änderungen wie die Verarbeitung der ELF-Verschiebung und das Patchen von Alternativen für CPU-Errata an diesen Abschnitten vorgenommen hat. Außerdem werden die folgenden zusätzlichen Schritte 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. Das Modul ersetzt alle Anweisungen, die Daten in den Shadow Call Stack einfügen oder daraus entfernen, durch die ursprünglich vorhandenen PAC-Anweisungen (Pointer Authentication Code).
  • Das Patchen von anderem Code ist für das Modul deaktiviert, einschließlich statischer Schlüssel und damit auch Tracepoints sowie Anbieter-Hooks.

Die 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 der unterstützten Schlüssellängen ausreichend, sofern sowohl die Ver- als auch die Entschlüsselung getestet werden.

Die Linux CryptoAPI kennt das Konzept der Algorithmusprioritäten, bei dem mehrere Implementierungen (z. B. eine mit speziellen Kryptoanweisungen und eine Fallback-Implementierung für CPUs, die diese Anweisungen nicht unterstützen) desselben Algorithmus nebeneinander existieren können. Daher müssen alle Implementierungen desselben Algorithmus getestet werden. Dies ist erforderlich, 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 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 und android15-6.6. Unterschiede zwischen den Kernel-Versionen werden gegebenenfalls angegeben.

Algorithmus Implementierungen Genehmigungsfähig Definition
aes aes-generic, aes-arm64, aes-ce, AES-Bibliothek Ja Reine AES-Blockchiffre 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 Vorlage cmac kann mit einer beliebigen Implementierung von aes mithilfe von cmac(<aes-impl>) zusammengesetzt 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 Vorlage ecb kann mit einer beliebigen Implementierung von aes mithilfe von ecb(<aes-impl>) zusammengesetzt 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 Vorlage cbc kann mit einer beliebigen Implementierung von aes mithilfe von ctr(<aes-impl>) zusammengesetzt 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 Geheimtextblöcke werden bedingungslos getauscht. Alle AES-Schlüsselgrößen werden unterstützt. Die cts-Vorlage kann mit einer beliebigen Implementierung von cbc mithilfe von cts(<cbc(aes)-impl>) zusammengestellt 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 Vorlage ctr kann mit einer beliebigen Implementierung von aes mithilfe von ctr(<aes-impl>) zusammengesetzt werden. Die anderen Implementierungen sind eigenständig.
xts(aes) xts (Vorlage), xts-aes-neon, xts-aes-neonbs, xts-aes-ce Ja AES-XTS: In Kernelversion 6.1 und niedriger werden alle AES-Schlüsselgrößen unterstützt. In Kernelversion 6.6 und höher werden nur AES-128 und AES-256 unterstützt. Die Vorlage xts kann mit einer beliebigen Implementierung von ecb(aes) mithilfe von xts(<ecb(aes)-impl>) zusammengesetzt 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 Vorlage gcm kann mit beliebigen Implementierungen von ctr(aes) und ghash mithilfe von gcm_base(<ctr(aes)-impl>,<ghash-impl>) zusammengestellt 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: Neben der standardmäßigen CryptoAPI-Schnittstelle wird auch eine Bibliotheksschnittstelle für SHA-256 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
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 oben, aber mit einer Digest-Länge von 256 Bit (SHA3-256). Für alle Digest-Längen wird dieselbe Keccak-Implementierung verwendet.
sha3-384 sha3-384-generic Ja Wie oben, aber mit einer Digestlänge von 384 Bit (SHA3-384). Für alle Digest-Längen wird dieselbe Keccak-Implementierung verwendet.
sha3-512 sha3-512-generic Ja Wie oben, aber mit einer Digest-Länge von 512 Bit (SHA3-512). Für alle Digest-Längen wird dieselbe Keccak-Implementierung verwendet.
hmac hmac (Vorlage) Ja HMAC (Keyed-Hash Message Authentication Code): Die Vorlage hmac kann mit einem beliebigen SHA-Algorithmus oder einer beliebigen 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, das mit der benannten Hash-Funktion und aktivierter Vorhersagebeständigkeit instanziiert wurde: Systemdiagnosen sind enthalten. Nutzer dieser Schnittstelle erhalten eigene 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, aber ohne deaktivierte Vorhersage-Resistenz. Der Code wird für die vorhersagefeste Variante freigegeben. In Kernelversion 5.10 ist drbg_nopr_hmac_sha256 der DRBG mit der höchsten Priorität. In Kernelversion 5.15 und höher ist es drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng Nein Jitter RNG, entweder Version 2.2.0 (Kernel-Version 6.1 und niedriger) oder Version 3.4.0 (Kernel-Version 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) 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 dem Quellcode erstellen

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

  • 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 einschließlich des Kernels und des fips140.ko-Moduls mit den darin eingebetteten HMAC-SHA256-Digest-Inhalten ausgeführt.

Anleitung für Endnutzer

Anleitung für Crypto Officer

Damit das Kernelmodul ausgeführt werden kann, muss das Betriebssystem auf einen einzelnen Betriebsmodus beschränkt sein. Dies wird automatisch von Android mithilfe von Hardware zur Speicherverwaltung im Prozessor erledigt.

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

Der Crypto Officer kann die Selbsttests jederzeit durch Neustarten des Geräts auslösen.

Anleitung für Nutzer

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

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

Fehler beim automatischen Test

Wenn der Selbsttest fehlschlägt, führt das Kernelmodul dazu, dass der Kernel abstürzt und das Gerät nicht weiter hochfährt. 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.


  1. Es wird erwartet, dass die AES-GCM-Implementierungen des Moduls „algorithm approved“ (algorithmusgenehmigt), aber nicht „module approved“ (modulgenehmigt) sein können. 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.