certyfikowany moduł kryptograficzny GKI z certyfikatem FIPS 140-3

Jądro GKI zawiera moduł jądra systemu Linux o nazwie fips140.ko, który jest zgodny z wymaganiami FIPS 140-3 modułów oprogramowania kryptograficznego. Ten moduł można przesłać do certyfikacji FIPS, jeśli wymaga tego usługa z jądrem GKI.

Zanim można używać procedur szyfrowania, należy spełnić te wymagania FIPS 140-3:

  • Przed udostępnieniem algorytmów kryptograficznych moduł musi sprawdzić własną integralność.
  • Zanim udostępnisz zatwierdzone algorytmy kryptograficzne, musisz je przetestować i zweryfikować za pomocą testów samokontroli z znanymi odpowiedziami.

Dlaczego oddzielny moduł jądra

Weryfikacja FIPS 140-3 opiera się na założeniu, że raz certyfikowany moduł oparty na oprogramowaniu lub sprzęcie nigdy nie ulega zmianie. Jeśli zmienisz dane, musisz je ponownie zatwierdzić. Nie pasuje to do procesów tworzenia oprogramowania stosowanych obecnie. W rezultacie moduły oprogramowania FIPS są zazwyczaj tak zaprojektowane, aby jak najściślej skupiały się na komponentach kryptograficznych, co zapewnia, że zmiany niezwiązane z kryptografia nie wymagają ponownej oceny kryptografii.

Rdzenie GKI mają być regularnie aktualizowane przez cały okres ich obsługi. Oznacza to, że nie jest możliwe, aby cały kernel mieścił się w ramach modułu FIPS, ponieważ taki moduł musiałby być ponownie certyfikowany po każdej aktualizacji jądra. Zdefiniowanie „modułu FIPS” jako podzbioru obrazu jądra ograniczyłoby ten problem, ale nie rozwiązałoby go, ponieważ zawartość binarna „modułu FIPS” nadal zmieniałaby się znacznie częściej niż to konieczne.

Przed wersją jądra 6.1 GKI był kompilowany z włączoną optymalizacją linkowania (LTO), ponieważ była ona warunkiem wstępnym dla integralności przepływu danych, która jest ważną funkcją zabezpieczeń.

Dlatego cały kod objęty wymaganiami FIPS 140-3 jest pakowany w oddzielny moduł jądra fips140.ko, który korzysta tylko ze stabilnych interfejsów udostępnionych przez źródło jądra GKI, z którego został skompilowany. Oznacza to, że moduł może być używany z różnymi wersjami GKI tej samej generacji i że musi zostać zaktualizowany i ponownie przesłany do certyfikacji tylko wtedy, gdy w kodzie, który jest zawarty w samym module, zostały poprawione jakieś problemy.

Kiedy używać modułu

Jądro GKI zawiera kod zależny od procedur kryptograficznych, które są również spakowane w module jądra FIPS 140-3. W związku z tym wbudowane rutyny kryptograficzne nie są przenoszone z jądra GKI, tylko kopiowane do modułu. Gdy moduł zostanie załadowany, wbudowane procedury szyfrowania zostaną usunięte z CryptoAPI Linux i zastąpione przez te, które są zawarte w module.

Oznacza to, że moduł fips140.ko jest całkowicie opcjonalny i należy go wdrożyć tylko wtedy, gdy wymagana jest certyfikacja FIPS 140-3. Poza tym moduł nie zapewnia żadnych dodatkowych funkcji, a jego niepotrzebne wczytywanie może wpłynąć na czas uruchamiania bez żadnej korzyści.

Jak wdrożyć moduł

Aby włączyć moduł do kompilacji Androida, wykonaj te czynności:

  • Dodaj nazwę modułu do BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Spowoduje to skopiowanie modułu do dysku ramdisk dostawcy.
  • Dodaj nazwę modułu do BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. W efekcie nazwa modułu zostanie dodana do elementu modules.load w docelowym pliku danych. modules.load zawiera listę modułów wczytywanych przez init podczas uruchamiania urządzenia.

Sprawdzanie integralności

Moduł jądra FIPS 140-3 pobiera skrót HMAC-SHA256 własnych sekcji .code i .rodata w czasie wczytywania modułu i porównuje go ze skrótem zarejestrowanym w module. Dzieje się tak po tym, jak ładowarka modułów Linuxa wprowadziła już typowe modyfikacje, takie jak przetwarzanie przeniesienia ELF i łatki alternatywne dla poprawek procesora w tych sekcjach. Aby zapewnić prawidłowe odtworzenie podsumowania, należy wykonać te dodatkowe czynności:

  • Przekierowania ELF są zachowywane w module, aby można było zastosować je w odwrotnej kolejności do danych wejściowych funkcji HMAC.
  • Moduł odwraca wszystkie poprawki kodu wprowadzone przez jądro dla dynamicznego stosu wywołań cienia. W szczególności moduł zastępuje wszystkie instrukcje, które zostały wypchnięte lub wsunięte ze stosu wywołań cieni, instrukcjami kodu uwierzytelniania wskaźnika (PAC), które były obecne pierwotnie.
  • W przypadku modułu wyłączone jest wszelkie inne poprawianie kodu, w tym klucze statyczne i punkty śledzenia oraz punkty zaczepienia dostawcy.

testy samodzielne z znanymi odpowiedziami.

Wdrożone algorytmy, które podlegają wymaganiom FIPS 140-3, muszą przed użyciem wykonać test samokontroli z znanymi odpowiedziami. Zgodnie z FIPS 140-3 Wskazówki dotyczące implementacji 10.3.A, jeden wektor testowy na algorytm, który używa dowolnej obsługiwanej długości klucza, wystarcza do szyfrowania, o ile testowane są zarówno szyfrowanie, jak i odszyfrowywanie.

Interfejs CryptoAPI w systemie Linux obsługuje priorytety algorytmów, w których ramach może współistnieć kilka implementacji tego samego algorytmu (np. jedna z użyciem specjalnych instrukcji szyfrowania i awaryjne dla procesorów, które nie obsługują tych instrukcji). Dlatego trzeba przetestować wszystkie implementacje tego samego algorytmu. Jest to konieczne, ponieważ interfejs CryptoAPI w Linuxie umożliwia pominięcie wyboru na podstawie priorytetu i zamiast tego wybranie algorytmu o niższym priorytecie.

Algorytmy uwzględnione w module

Wszystkie algorytmy zawarte w module FIPS 140-3: Dotyczy to gałęzi jądra android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1android15-6.6, ale w stosownych przypadkach różnice między wersjami jądra są zaznaczone.

Algorytm Implementacje Odpowiednia Definicja
aes aes-generic, aes-arm64, aes-ce, biblioteka AES Tak Szyfr blokowy AES bez trybu działania: obsługiwane są wszystkie rozmiary kluczy (128, 192 i 256 bitów). Wszystkie implementacje inne niż implementacja biblioteki można tworzyć za pomocą szablonu.
cmac(aes) cmac (szablon), cmac-aes-neon, cmac-aes-ce Tak AES-CMAC: obsługiwane są wszystkie rozmiary kluczy AES. Szablon cmac może być komponowany z dowolną implementacją aes za pomocą cmac(<aes-impl>). Inne implementacje są samodzielne.
ecb(aes) ecb (szablon), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce Tak AES-ECB: obsługiwane są wszystkie rozmiary kluczy AES. Szablon ecb może być komponowany z dowolną implementacją aes za pomocą ecb(<aes-impl>). Inne implementacje są samodzielne.
cbc(aes) cbc (szablon), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce Tak AES-CBC: obsługiwane są wszystkie rozmiary kluczy AES. Szablon cbc może być komponowany z dowolną implementacją aes za pomocą ctr(<aes-impl>). Inne implementacje są samodzielne.
cts(cbc(aes)) cts (szablon), cts-cbc-aes-neon, cts-cbc-aes-ce Tak AES-CBC-CTS lub AES-CBC z kradzieżą tekstu zaszyfrowanego: użyta konwencja to CS3; 2 końcowe bloki tekstu zaszyfrowanego są zamieniane bezwarunkowo. Obsługiwane są wszystkie rozmiary kluczy AES.Szablon cts może utworzyć z dowolną implementacją cbc za pomocą cts(<cbc(aes)-impl>). Inne implementacje są samodzielne.
ctr(aes) ctr (szablon), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce Tak AES-CTR: obsługiwane są wszystkie rozmiary kluczy AES. Szablon ctr można skompilować z dowolną implementacją aes za pomocą ctr(<aes-impl>). Inne implementacje są samodzielne.
xts(aes) xts (szablon), xts-aes-neon, xts-aes-neonbs, xts-aes-ce Tak AES-XTS: w jądrze w wersji 6.1 lub starszej obsługiwane są wszystkie rozmiary kluczy AES; w przypadku jądra w wersji 6.6 i nowszych obsługiwane są tylko klucze AES-128 i AES-256. Szablon xts można skompilować z dowolną implementacją ecb(aes) za pomocą xts(<ecb(aes)-impl>). Inne implementacje są samodzielne. Wszystkie implementacje implementują sprawdzanie słabych kluczy wymagane przez FIPS, czyli odrzucają klucze XTS, których pierwsza i druga połowa są równe.
gcm(aes) gcm (szablon), gcm-aes-ce Nie1 AES-GCM: obsługiwane są wszystkie rozmiary klucza AES. Obsługiwane są tylko 96-bitowe tablice haseł. Tak jak w przypadku wszystkich innych trybów AES w tym module, za dostarczanie IV odpowiada element wywołujący. Szablon gcm może zawierać dowolne implementacje komponentów ctr(aes) i ghash w języku gcm_base(<ctr(aes)-impl>,<ghash-impl>). Inne implementacje są samodzielne.
sha1 sha1-generic, sha1-ce Tak Funkcja kryptograficzna SHA-1
sha224 sha224-generic, sha224-arm64, sha224-ce Tak Funkcja kryptograficznego haszowania SHA-224: kod jest wspólny z SHA-256.
sha256 sha256-generic, sha256-arm64, sha256-ce, biblioteka SHA-256 Tak Funkcja kryptograficznego haszowania SHA-256: oprócz standardowego interfejsu CryptoAPI udostępniamy interfejs biblioteki do SHA-256. Ten interfejs biblioteki używa innej implementacji.
sha384 sha384-generic, sha384-arm64, sha384-ce Tak Funkcja szyfrowania SHA-384: kod jest udostępniany z wykorzystaniem algorytmu SHA-512.
sha512 sha512-generic, sha512-arm64, sha512-ce Tak Kryptograficzna funkcja skrótu SHA-512
sha3-224 sha3-224-generic Tak Funkcja kryptograficzna SHA3-224. Dostępne tylko w jądrze w wersji 6.6 lub nowszej.
sha3-256 sha3-256-generic Tak To samo co poprzednio, ale ze skrótem o długości 256 bitów (SHA3-256). Wszystkie długości skrótu używają tej samej implementacji Keccak.
sha3-384 sha3-384-generic Tak To samo co poprzednie, ale z 384-bitową długością danych uwierzytelniających (SHA3-384). Wszystkie długości skrótów używają tej samej implementacji Keccak.
sha3-512 sha3-512-generic Tak To samo co poprzednie, ale z 512-bitową długością digesu (SHA3-512). Wszystkie długości skrótów używają tego samego algorytmu Keccak.
hmac hmac (szablon) Tak HMAC (kluczowy kod uwierzytelniania wiadomości oparty na wartościach hash): szablon hmac może być skompilowany z dowolnym algorytmem SHA lub jego implementacją za pomocą funkcji hmac(<sha-alg>) lub hmac(<sha-impl>).
stdrng drbg_pr_hmac_sha1, drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512 Tak HMAC_DRBG instancjonowany za pomocą nazwanej funkcji szyfrowania i z włączoną odpornością na przewidywanie: uwzględniono sprawdzanie stanu. Użytkownicy tego interfejsu otrzymują własne instancje DRBG.
stdrng drbg_nopr_hmac_sha1, drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512 Tak Taki sam jak algorytm drbg_pr_*, ale z wyłączoną odpornością na prognozy. Kod jest udostępniany z wersją odporną na przewidywanie. W kernelu w wersji 5.10 DRBG o najwyższym priorytecie to drbg_nopr_hmac_sha256. W wersji jądra 5.15 i nowszych jest to drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng Nie Jitter RNG w wersji 2.2.0 (jądro w wersji 6.1 lub starszej) lub 3.4.0 (jądro w wersji 6.6 lub nowszej). Użytkownicy tego interfejsu otrzymują własne instancje Jitter RNG. Nie używają ponownie instancji używanych przez DRBG.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce Nie
xctr(aes) xctr-aes-neon, xctr-aes-ce Nie Jest dostępny tylko w jądrze w wersji 5.15 i nowszych.
cbcmac(aes) cbcmac-aes-neon, cbcmac-aes-ce Nie
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce Nie

Skompiluj moduł na podstawie źródła

W przypadku Androida 14 i nowszych wersji (w tym android-mainline) utwórz moduł fips140.ko ze źródła, używając tych poleceń.

  • Kompilowanie za pomocą Bazel:

    tools/bazel run //common:fips140_dist
  • Kompilacja z wykorzystaniem build.sh (starszej wersji):

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

Te polecenia wykonują pełną kompilację, w tym jądro i moduł fips140.ko z umieszczoną w niej skrótem HMAC-SHA256.

Wskazówki dla użytkowników

Wskazówki dla oficera ds. kryptowalut

Aby moduł jądra mógł działać, system operacyjny musi być ograniczony do trybu pojedynczego operatora. Android automatycznie zarządza tym za pomocą sprzętu do zarządzania pamięcią w procesorze.

Moduł jądra nie może być instalowany osobno. Jest on częścią oprogramowania urządzenia i ładowany automatycznie podczas uruchamiania. Działa ona tylko w zatwierdzonym trybie działania.

Osoba odpowiedzialna za bezpieczeństwo może w każdej chwili uruchomić testy diagnostyczne, ponownie uruchamiając urządzenie.

Wskazówki dla użytkowników

Użytkownikami modułu jądra są inne komponenty jądra, które muszą używać algorytmów kryptograficznych. Moduł jądra nie zapewnia dodatkowej logiki w użyciu algorytmów i nie przechowuje żadnych parametrów poza czasem potrzebnym do wykonania operacji kryptograficznej.

Korzystanie z algorytmów na potrzeby zgodności z FIPS jest ograniczone do zatwierdzonych algorytmów. Aby spełnić wymóg FIPS 140-3 dotyczący „wskaźnika usługi”, moduł udostępnia funkcję fips140_is_approved_service, która wskazuje, czy algorytm został zatwierdzony.

Błędy autotestu

W przypadku niepowodzenia autotestu moduł jądra powoduje panikę jądra, a urządzenie nie uruchamia się. Jeśli ponowne uruchomienie urządzenia nie rozwiąże problemu, musisz uruchomić je w trybie odzyskiwania, aby rozwiązać problem przez ponowne zaflashowanie urządzenia.


  1. Implementacje AES-GCM w module mogą być zatwierdzone przez algorytm, ale nie jako zatwierdzone. Można je weryfikować, ale AES-GCM nie jest uznawany za zatwierdzony algorytm z poziomu modułu FIPS. Dzieje się tak, ponieważ wymagania dotyczące modułu FIPS dla GCM są niezgodne z wdrożeniami GCM, które nie generują własnych IV.