Kernel GKI zawiera moduł jądra systemu Linux o nazwie fips140.ko
, który jest zgodny z wymaganiami FIPS 140-3 dotyczącymi modułów oprogramowania kryptograficznego. Ten moduł można przesłać do standardu 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:
- Zanim udostępni algorytmy szyfrowania, moduł musi sprawdzić własną integralność.
- Moduł musi sprawdzać i weryfikować zatwierdzone algorytmy kryptograficzne przy użyciu testów autotestów ze 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 została zmieniona, musi być ponownie uzyskać certyfikat. 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 obsługi. Przez to nie można umieścić całego jądra w standardzie FIPS. granicą modułu, w związku z czym taki moduł wymagałby ponownego certyfikatu dla każdego jądra systemu . Definiowanie modułu FIPS jako podzbioru obrazu jądra, ale nie pozwoli go rozwiązać, ponieważ zawartość binarna „Moduł FIPS” zmieniałyby się znacznie częściej, niż trzeba.
Przed wersją 6.1 jądra można było wziąć pod uwagę także fakt, że GKI została skompilowana z Włączono LTO (optymalizacja czasu połączenia), ponieważ był on niezbędnym elementem kontroli Integralność przepływu, czyli ważna funkcja 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. Ten
co oznacza, że moduł może być używany z różnymi wersjami GKI tego samego
oraz że należy je zaktualizować i ponownie przesłać wyłącznie w celu uzyskania certyfikatu
sprawdź, czy w kodzie umieszczonym przez moduł nie występują żadne błędy.
Kiedy używać modułu
Kernel GKI zawiera kod, który zależy od algorytmów szyfrowania, które są również zapakowane w moduł jądra FIPS 140-3. Wbudowane procedury kryptograficzne nie są więc przenoszone z rdzenia 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. Zapewnia jedynie
warto wdrożyć go, jeśli 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 żadnych korzyści.
Jak wdrożyć moduł
Aby włączyć moduł w kompilacji Androida, wykonaj te czynności:
- Dodaj nazwę modułu do pola
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. Spowoduje to skopiowanie modułu na dysk RAM dostawcy. - Dodaj nazwę modułu do
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
. W efekcie nazwa modułu zostanie dodana domodules.load
w docelowym pliku.modules.load
zawiera listę modułów ładowanych przez taginit
, gdy uruchamianie urządzenia.
Sprawdzanie integralności
Moduł jądra FIPS 140-3 wykorzystuje skrót HMAC-SHA256 z własnego skrótu .code
i .rodata
w czasie wczytywania modułu, i porównuje go ze skrótem
omówione w ramach modułu. Odbywa się to po tym, jak w programie ładującym moduł
po wprowadzeniu standardowych zmian, takich jak przetwarzanie relokacji ELF i
lub instalowanie poprawek błędów procesora w tych sekcjach. Aby zapewnić prawidłowe odtworzenie podsumowania, należy wykonać te dodatkowe czynności:
- Relokacje ELF są zachowywane w module, więc można je zastosować na dane wejściowe HMAC.
- Moduł odwraca wszystkie poprawki kodu wprowadzone przez jądro dla dynamicznego stosu wywołań cienia. Konkretnie moduł zastępuje wszystkie instrukcje, które push lub pop ze stosu wywołań cieni, instrukcjami kodu uwierzytelniania wskaźnika (PAC), które były obecne pierwotnie.
- Instalowanie poprawek kodu we wszystkich innych przypadkach jest wyłączone w module, w tym klucze statyczne i oraz punkty zaczepienia dostawcy.
Autotesty dotyczące znanej odpowiedzi
Wdrożone algorytmy, które są objęte wymaganiami FIPS 140-3, muszą przed użyciem wykonać test samokontroli z znanymi odpowiedziami. Zgodnie z normą FIPS 140-3 Wskazówki dotyczące wdrażania 10.3.A. jeden wektor testowy na algorytm przy użyciu dowolnej z obsługiwanych długości kluczy to wystarczającą do szyfrowania, jeśli testowane jest zarówno szyfrowanie, jak i odszyfrowywanie.
W Linuksie CryptoAPI można znaleźć priorytety algorytmu, przy czym kilka z nich implementacji (np. wykorzystującą specjalne instrukcje dotyczące kryptografii, a kod zastępczy dla procesorów, które nie stosują tych instrukcji) tego samego algorytmu może współistnieć. Należy więc testować wszystkie implementacje tego samego algorytmem bezpieczeństwa. 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 tych usług: android12-5.10
, android13-5.10
, android13-5.15
,
jednak gałęzie jądra android14-5.15
, android14-6.1
i android15-6.6
tam, gdzie ma to uzasadnienie, różnice między wersjami jądra.
Algorytm | Implementacje | Odpowiednia | Definicja |
---|---|---|---|
aes |
aes-generic , aes-arm64 , aes-ce , biblioteka AES |
Tak | Zwykły szyfr blokowy AES bez trybu działania: obsługiwane są wszystkie rozmiary kluczy (128-, 192-bitowe i 256-bitowe). 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>) . Pozostałe implementacje są niezależne. |
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: stosowana konwencja to CS3 ; ostatnie dwa bloki tekstu zaszyfrowanego są zastępowane bezwarunkowo. Obsługiwane są wszystkie rozmiary kluczy AES. Szablon cts można skompilować 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że być komponowany z dowolną implementacją aes za pomocą ctr(<aes-impl>) . Pozostałe implementacje są niezależne. |
xts(aes) |
xts (szablon), xts-aes-neon , xts-aes-neonbs , xts-aes-ce |
Tak | AES-XTS: w jądrze w wersji 6.1 i starszych obsługiwane są wszystkie rozmiary klucza AES; w jądrze w wersji 6.6 i nowszych obsługiwane są tylko AES-128 i AES-256. Szablon xts może być komponowany z dowolną implementacją ecb(aes) za pomocą xts(<ecb(aes)-impl>) . Pozostałe implementacje są niezależne. we wszystkich implementacjach stosuje się słabą kontrolę klucza wymaganą przez FIPS; czyli klucze XTS, których pierwsza i druga połowa są równe, są odrzucane. |
gcm(aes) |
gcm (szablon), gcm-aes-ce |
Nr1 | AES-GCM: obsługiwane są wszystkie rozmiary klucza AES. Obsługiwane są tylko 96-bitowe tablice haseł. Podobnie jak w przypadku wszystkich innych trybów AES w tym module, wywołujący jest odpowiedzialny za podanie IV. 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 szyfrowania SHA-224: kod jest udostępniany z wykorzystaniem algorytmu SHA-256. |
sha256 |
Biblioteka sha256-generic , sha256-arm64 , sha256-ce , 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 | Funkcja kryptograficzna SHA-512 |
sha3-224 |
sha3-224-generic |
Tak | kryptograficzna funkcja skrótu 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ą wynikowego ciągu znaków (SHA3-384). Wszystkie długości skrótów używają tego samego algorytmu Keccak. |
sha3-512 |
sha3-512-generic |
Tak | Tak samo jak wyżej, ale z 512-bitowym skrótem o długości 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 z nazwą funkcji szyfrowania i z włączoną odpornością na przewidywanie: uwzględnione są kontrole 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 | To samo co algorytmy drbg_pr_* , ale z wyłączoną odpornością na prognozowanie. Kod jest udostępniany z wersją odporną na przewidywanie. W jądrze w wersji 5.10 DRBG o najwyższym priorytecie to drbg_nopr_hmac_sha256 . W jądrze w wersji 5.15 lub nowszej 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 zakłóceń 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
Na Androida 14 i nowszego (w tym
android-mainline
), utwórz moduł fips140.ko
ze źródła za pomocą
tych poleceń.
Tworzenie za pomocą Bazel:
tools/bazel run //common:fips140_dist
Kompilacja z użyciem
build.sh
(starsza wersja):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Te polecenia wykonują pełną kompilację, w tym jądro i fips140.ko
z osadzoną treścią skrótu HMAC-SHA256.
Wskazówki dla użytkowników
Wskazówki dla oficera ds. kryptowalut
Aby można było obsługiwać moduł jądra, system operacyjny musi być ograniczony do w trybie działania pojedynczego operatora. Android obsługuje to automatycznie przez wykorzystanie w procesorze sprzętu do zarządzania pamięcią.
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 zatwierdzony tryb działania.
Crypto Officer może uruchomić autotesty w dowolnym momencie, uruchamiając je ponownie urządzenia.
Wskazówki dla użytkownika
Użytkownikami modułu jądra są inne komponenty jądra, które muszą używać algorytmów kryptograficznych. Moduł jądra nie udostępnia dodatkowej logiki wykorzystanie algorytmów i nie przechowuje żadnych parametrów poza czasem potrzebne do przeprowadzenia operacji kryptograficznej.
Korzystanie z algorytmów na potrzeby zgodności z FIPS jest ograniczone do zatwierdzonych algorytmów. W celu spełnienia wymogów standardu FIPS 140-3 „service wskaźniki” funkcji
moduł zawiera 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.
-
Implementacje AES-GCM w module mogą być „algorytmem”, zatwierdzone” ale nie „moduł zatwierdzony”. 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 implementacjami GCM, które nie generują własnych IV. ↩