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 elementumodules.load
w docelowym pliku danych.modules.load
zawiera listę modułów wczytywanych przezinit
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.1
i android15-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.
-
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. ↩