Nach FIPS 140-3 zertifiziertes GKI-Kryptomodul

Der GKI-Kernel enthält ein Linux-Kernelmodul mit dem Namen fips140.ko, das die FIPS 140-3-Anforderungen für kryptografische Softwaremodule erfüllt. Dieses Modul kann für die FIPS-Zertifizierung eingereicht werden, wenn das Produkt, das den GKI-Kernel ausführt, dies erfordert.

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

  • Das Modul muss seine eigene Integrität prüfen, bevor kryptografische Algorithmen zur Verfügung gestellt werden.
  • Das Modul muss seine genehmigten kryptografischen Algorithmen mithilfe von Selbsttests bekannter Antworten testen und verifizieren, bevor sie verfügbar gemacht werden.

Warum ein separates Kernelmodul?

Die Validierung gemäß FIPS 140-3 basiert auf der Idee, dass ein Software- oder Hardwaremodul nach der Zertifizierung nie mehr geändert werden kann. Wenn sie geändert wird, muss sie neu zertifiziert werden. Dies entspricht nicht ohne Weiteres den heute verwendeten Softwareentwicklungsprozessen. Aufgrund dieser Anforderung sind die FIPS-Softwaremodule im Allgemeinen 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 sollte während seiner gesamten unterstützten Lebensdauer regelmäßig aktualisiert werden. Dadurch ist es nicht möglich, dass sich der gesamte Kernel innerhalb der FIPS-Modulgrenze befindet, sodass ein solches Modul bei jeder Kernel-Aktualisierung neu zertifiziert werden muss. Wenn Sie das FIPS-Modul als Teil des Kernel-Images definieren, wird dieses Problem zwar verringert, 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 Kernel-Version 6.1 war eine weitere Überlegung, dass GKI mit aktivierter Linkzeitoptimierung kompiliert wurde, da LTO eine Voraussetzung für die Kontrollflussintegrität war, ein wichtiges Sicherheitsfeature.

Daher wird jeglicher Code, der unter die FIPS 140-3-Anforderungen fällt, in ein separates Kernelmodul fips140.ko gepackt, das nur stabile Schnittstellen nutzt, die von der GKI-Kernel-Quelle bereitgestellt werden, aus der er erstellt wurde. Dies garantiert, dass das Modul mit verschiedenen GKI-Releases derselben Generation verwendet werden kann und nur aktualisiert und noch einmal 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ängig ist, die auch im FIPS 140-3-Kernelmodul verpackt sind. Daher werden die integrierten Kryptoroutinen nicht tatsächlich aus dem GKI-Kernel verschoben, 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 ersetzt.

Das bedeutet, dass das Modul fips140.ko vollständig optional ist und nur bereitgestellt werden kann, wenn eine FIPS 140-3-Zertifizierung erforderlich ist. Darüber hinaus bietet das Modul keine zusätzliche Funktionalität. Ein unnötiges Laden des Moduls wirkt sich nur wahrscheinlich auf die Startzeit aus, ohne dass ein Vorteil entsteht.

So stellen Sie das Modul bereit

Das Modul kann mithilfe der folgenden Schritte in den Android-Build eingebunden werden:

  • Fügen Sie den Modulnamen zu BOARD_VENDOR_RAMDISK_KERNEL_MODULES hinzu. Dadurch wird das Modul auf die Anbieter-RAMdisk kopiert.
  • Fügen Sie den Modulnamen zu BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD hinzu. Dies führt dazu, dass der Modulname auf dem Ziel zu modules.load hinzugefügt wird. modules.load enthält die Liste der Module, die beim Starten des Geräts von init geladen werden.

Selbstprüfung der Integrität

Das Kernelmodul FIPS 140-3 vergleicht den HMAC-SHA256-Digest seiner eigenen .code- und .rodata-Abschnitte zum Zeitpunkt des Modulladevorgangs mit dem im Modul aufgezeichneten Digest. Dies erfolgt, nachdem das Linux-Modulladeprogramm bereits die üblichen Änderungen wie die ELF-Neuzuweisungsverarbeitung und alternatives Patchen für CPU-Fehler in diesen Abschnitten vorgenommen hat. Mit den folgenden zusätzlichen Schritten sorgen Sie dafür, dass der Digest richtig reproduziert werden kann:

  • ELF-Verschiebungen werden im Modul beibehalten, damit sie umgekehrt auf die Eingabe des HMAC angewendet werden können.
  • Das Modul kehrt alle Code-Patches um, die vom Kernel für den Dynamic Shadow Call Stack erstellt wurden. Insbesondere ersetzt das Modul alle Anweisungen, die den Shadow-Call-Stack per Push- oder Pop-up aus dem Shadow-Call-Stack knacken, durch die ursprünglichen PAC-Anweisungen (Pointer Authentication Code).
  • Alle anderen Code-Patching sind für das Modul deaktiviert, einschließlich statischer Schlüssel und daher Tracepoints sowie Anbieter-Hooks.

Selbsttests mit bekannten Antworten

Alle implementierten Algorithmen, die durch die FIPS 140-3-Anforderungen abgedeckt sind, müssen vor ihrer Verwendung einen Selbsttest mit bekannten Antworten durchführen. Gemäß FIPS 140-3 Implementation Guidance 10.3.A ist ein einzelner Testvektor pro Algorithmus, der eine der unterstützten Schlüssellängen verwendet, für Verschlüsselungen ausreichend, solange sowohl Verschlüsselung als auch Entschlüsselung getestet werden.

Bei der Linux CryptoAPI werden Algorithmusprioritäten festgelegt, bei denen mehrere Implementierungen desselben Algorithmus gleichzeitig vorhanden sein können, z. B. eine mit speziellen Kryptoanweisungen und ein Fallback für CPUs, die diese Anweisungen nicht implementieren. Daher müssen alle Implementierungen desselben Algorithmus getestet werden. Dies ist erforderlich, da die Linux CryptoAPI es zulässt, dass die prioritätsbasierte Auswahl umgangen und stattdessen ein Algorithmus mit niedrigerer Priorität ausgewählt wird.

Im Modul enthaltene Algorithmen

Alle Algorithmen, die im FIPS 140-3-Modul enthalten sind, sind im Folgenden aufgeführt. Dies gilt für die Kernel-Zweige 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 jedoch gegebenenfalls vermerkt.

Algorithmus Implementierungen Zuweisbar 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 mit einem Betriebsmodus über eine Vorlage erstellt 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 aes-Implementierung mit cmac(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen.
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 aes-Implementierung mit ecb(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen.
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 aes-Implementierung mit ctr(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen.
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 Vorlage cts kann mit einer beliebigen cbc-Implementierung mit 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 Vorlage ctr kann mit einer beliebigen aes-Implementierung mit ctr(<aes-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen.
xts(aes) xts (Vorlage), xts-aes-neon, xts-aes-neonbs, xts-aes-ce Ja AES-XTS: In Kernel-Version 6.1 und niedriger werden alle AES-Schlüsselgrößen unterstützt; ab Kernel-Version 6.6 werden nur AES-128 und AES-256 unterstützt. Die Vorlage xts kann mit einer beliebigen ecb(aes)-Implementierung mit xts(<ecb(aes)-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen. Alle Implementierungen implementieren die von FIPS geforderte schwache Schlüsselprüfung. Das heißt, XTS-Schlüssel, deren erste und zweite Hälfte identisch sind, werden abgelehnt.
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 einer beliebigen Implementierung von ctr(aes) und ghash mithilfe von gcm_base(<ctr(aes)-impl>,<ghash-impl>) erstellt werden. Die anderen Implementierungen sind eigenständige Implementierungen.
sha1 sha1-generic, sha1-ce Ja SHA-1-kryptografische Hash-Funktion
sha224 sha224-generic, sha224-arm64 und sha224-ce Ja SHA-224-Kryptografie-Hash-Funktion: Der Code wird an SHA-256 weitergegeben.
sha256 sha256-generic, sha256-arm64, sha256-ce, SHA-256-Bibliothek Ja SHA-256-Kryptografische Hash-Funktion: Zusätzlich zur herkömmlichen CryptoAPI-Schnittstelle wird für SHA-256 eine Bibliotheksschnittstelle bereitgestellt. Diese Bibliotheksoberfläche verwendet eine andere Implementierung.
sha384 sha384-generic, sha384-arm64 und sha384-ce Ja SHA-384-Kryptografische Hash-Funktion: Der Code wird an SHA-512 weitergegeben.
sha512 sha512-generic, sha512-arm64 und sha512-ce Ja SHA-512-kryptografische Hash-Funktion
sha3-224 sha3-224-generic Ja SHA3-224-kryptografische Hash-Funktion. Nur ab Kernel-Version 6.6 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 Digest-Lä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 512-Bit-Digest-Länge (SHA3-512). Für alle Digest-Längen wird dieselbe Keccak-Implementierung verwendet.
hmac hmac (Vorlage) Ja HMAC (Keyed-Hash Message Authentication Code, Schlüssel-Hash-Nachrichtenauthentifizierungscode): Die Vorlage hmac kann mit einem beliebigen SHA-Algorithmus oder einer 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 wird mit der benannten Hash-Funktion instanziiert und die Vorhersageresistenz aktiviert. Systemdiagnosen sind enthalten. Nutzer 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, aber mit deaktivierter Vorhersageresistenz. Der Code wird an die vorhersageresistente Variante weitergegeben. In Kernel-Version 5.10 ist drbg_nopr_hmac_sha256 der DRBG mit der höchsten Priorität. Ab Kernel-Version 5.15 ist dies 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 ihre eigenen 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 ab Kernel-Version 5.15 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 Quelle erstellen

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

  • Erstellen Sie mit Bazel:

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

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

Diese Befehle führen einen vollständigen Build aus, einschließlich des Kernels und des Moduls fips140.ko mit eingebetteten HMAC-SHA256-Digest-Inhalten.

Anleitung für Endnutzer

Anleitung für Crypto Officers

Für den Betrieb des Kernelmoduls muss das Betriebssystem auf einen Einzeloperatormodus beschränkt sein. Android übernimmt dies automatisch über die Speicherverwaltungshardware im Prozessor.

Das Kernelmodul kann nicht separat installiert werden. Es ist Teil der Firmware des Geräts und wird beim Booten automatisch geladen. Es wird nur in einem genehmigten Betriebsmodus ausgeführt.

Der Crypto Officer kann jederzeit veranlassen, dass die Selbsttests ausgeführt werden, indem er das Gerät neu startet.

Anleitung für Nutzer

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

Die Verwendung der Algorithmen zum Zweck der FIPS-Compliance ist auf zugelassene Algorithmen beschränkt. Das Modul stellt eine fips140_is_approved_service-Funktion bereit, die angibt, ob ein Algorithmus genehmigt wurde, um die FIPS 140-3-Anforderung des Dienstindikators zu erfüllen.

Fehler beim automatischen Test

Wenn ein Selbsttest fehlschlägt, löst das Kernelmodul eine Panik im Kernel aus und das Gerät startet nicht weiter. 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 "durch den Algorithmus genehmigt", aber nicht "Modul genehmigt" werden können. Sie können validiert werden, aber AES-GCM kann aus Sicht des 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.