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 będzie można korzystać z rutyn kryptograficznych, muszą być spełnione w szczególności te wymagania FIPS 140-3:

  • Przed udostępnieniem algorytmów kryptograficznych moduł musi sprawdzić własną integralność.
  • Przed udostępnieniem modułu musi on sprawdzić i zweryfikować zatwierdzone algorytmy kryptograficzne oparte na znanych odpowiedziach.

Dlaczego oddzielny moduł jądra

Weryfikacja FIPS 140-3 opiera się na założeniu, że certyfikowany moduł programowy lub sprzętowy nigdy nie jest zmieniany. W razie zmiany konieczne jest ponowne uzyskanie certyfikatu. Nie pasuje to wyraźnie do obecnych procesów tworzenia oprogramowania, dlatego moduły oprogramowania FIPS są z reguły zaprojektowane w taki sposób, aby jak najdokładniej skupiać się na komponentach kryptograficznych, tak aby zmiany niezwiązane z kryptografią nie wymagały ponownej oceny kryptografii.

Jądro GKI jest z założenia regularnie aktualizowane przez cały obsługiwany okres eksploatacji. Nie jest więc możliwe, aby całe jądro znajdowało się w granicach 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 rozwiąże ten problem, ale nie rozwiąże tego problemu, ponieważ zawartość binarna modułu FIPS zmieniałaby się znacznie częściej, niż jest to konieczne.

Przed wdrożeniem jądra w wersji 6.1 brana pod uwagę była możliwość skompilowania GKI z włączoną optymalizacją czasu połączenia (LTO), ponieważ była ona jednym z warunków wstępnych wdrożenia Control Flow Integrity Integrity, która jest ważną funkcją zabezpieczeń.

Dlatego cały kod zgodny z FIPS 140-3 jest spakowany w osobnym module jądra fips140.ko, który korzysta wyłącznie ze stabilnych interfejsów udostępnianych przez źródło jądra GKI, z którego został skompilowany. Gwarantuje to, że moduł może być używany z różnymi wersjami GKI tej samej generacji oraz że trzeba go zaktualizować i ponownie przesłać do certyfikacji tylko wtedy, gdy w kodzie umieszczonym przez moduł nie występują żadne błędy.

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. Po załadowaniu modułu wbudowane procedury kryptograficzne są wyrejestrowywane z Linux CryptoAPI i zastępowane przez te wykonywane przez moduł.

Oznacza to, że moduł fips140.ko jest całkowicie opcjonalny, a wdrożenie go ma sens tylko wtedy, gdy wymagana jest certyfikacja FIPS 140-3. Poza tym moduł nie zawiera żadnych dodatkowych funkcji, a niepotrzebne załadowanie go prawdopodobnie wpłynie na czas uruchamiania, nie przynosząc żadnych korzyści.

Jak wdrożyć moduł

Moduł można włączyć do kompilacji Androida, wykonując te czynności:

  • Dodaj nazwę modułu do pola BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Spowoduje to skopiowanie modułu do dysku ramdisk dostawcy.
  • Dodaj nazwę modułu do pola BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. Powoduje to dodanie nazwy modułu do elementu modules.load w środowisku docelowym. modules.load zawiera listę modułów ładowanych przez init przy uruchamianiu urządzenia.

Samodzielne sprawdzenie 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ę to po tym, jak program ładujący modułu Linuksa wprowadzi już standardowe zmiany, takie jak przetwarzanie relokacji ELF i wprowadzenie w tych sekcjach poprawek błędów dotyczących procesora. Podejmujemy te dodatkowe kroki, aby zapewnić prawidłowe odtworzenie skrótu:

  • Relokacje ELF są zachowywane w module, dzięki czemu można je stosować odwrotnie do danych wejściowych z HMAC.
  • Moduł odwraca wszystkie poprawki kodu wprowadzone przez jądro systemu wywołań połączeń Dynamic Shadow. W szczególności moduł ten zastępuje wszelkie instrukcje push lub wyskakujące ze stosu wywołań funkcji powielonych na podstawie obecnych instrukcji kodu uwierzytelniania wskaźnika (PAC).
  • Instalowanie wszelkich innych poprawek kodu jest wyłączone w module, w tym klucze statyczne i punkty śledzenia, a także punkty zaczepienia dostawcy.

Autotesty dotyczące znanej odpowiedzi

Wszystkie zaimplementowane algorytmy objęte normą FIPS 140-3 muszą przed użyciem wykonać samotest, w ramach którego uzyskano znaną odpowiedź. Zgodnie z wytycznymi FIPS 140-3 dotyczącymi implementacji, jeśli testowane jest zarówno szyfrowanie, jak i odszyfrowywanie, wystarczy jeden wektor testowy na algorytm korzystający z dowolnej z obsługiwanych długości kluczy.

W systemie Linux CryptoAPI można znaleźć priorytety algorytmu, zgodnie z którym może istnieć kilka implementacji tego samego algorytmu (np. zastosowanie specjalnych instrukcji dotyczących kryptografii i zastępcza dla procesorów, które ich nie stosują). Dlatego konieczne jest testowanie wszystkich implementacji tego samego algorytmu. Jest to konieczne, ponieważ Linux CryptoAPI zezwala na pominięcie wyboru opartego na priorytecie i wybranie algorytmu o niższym priorytecie.

Algorytmy zawarte w module

Wszystkie algorytmy uwzględnione w module FIPS 140-3 są wymienione poniżej. 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 podane są 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 skomponować z trybem działania z poziomu 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ć utworzony z dowolną implementacją elementu aes za pomocą atrybutu 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ć utworzony z dowolną implementacją elementu aes za pomocą atrybutu ecb(<aes-impl>). Pozostałe implementacje są niezależne.
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ć utworzony z dowolną implementacją elementu aes za pomocą atrybutu ctr(<aes-impl>). Pozostałe implementacje są niezależne.
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; dwa ostatnie bloki tekstu szyfru są zastępowane bezwarunkowo.Obsługiwane są wszystkie rozmiary kluczy AES.Szablon cts może utworzyć z dowolną implementacją cbc za pomocą cts(<cbc(aes)-impl>).Pozostałe implementacje są niezależne.
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ć utworzony z dowolną implementacją elementu aes za pomocą atrybutu 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 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że być utworzony z dowolną implementacją elementu ecb(aes) za pomocą atrybutu xts(<ecb(aes)-impl>). Pozostałe implementacje są niezależne. Wszystkie implementacje wykorzystują słabe sprawdzenie klucza wymagane przez FIPS. Oznacza to, że klucze XTS, których pierwsza i druga połowa są jednakowe, są odrzucane.
gcm(aes) gcm (szablon), gcm-aes-ce Nr1 AES-GCM: obsługiwane są wszystkie rozmiary kluczy AES. Obsługiwane są tylko 96-bitowe pliki IV. 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>). Pozostałe implementacje są niezależne.
sha1 sha1-generic, sha1-ce Tak kryptograficzna funkcja skrótu 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 szyfrowania SHA-256: oprócz tradycyjnego interfejsu CryptoAPI, do funkcji szyfrowania SHA-256 dostępny jest interfejs biblioteki. Interfejs tego biblioteki ma inną implementację.
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 kryptograficzna funkcja skrótu SHA3-224, Występuje tylko w jądrze w wersji 6.6 lub nowszej.
sha3-256 sha3-256-generic Tak Tak samo jak wyżej, ale z 256-bitowym skrótem o długości SHA3-256. Wszystkie długości skrótu używają tej samej implementacji Keccak.
sha3-384 sha3-384-generic Tak Tak samo jak wyżej, ale z 384-bitowym skrótem o długości SHA3-384. Wszystkie długości skrótu używają tej samej implementacji 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ótu używają tej samej implementacji Keccak.
hmac hmac (szablon) Tak HMAC (Keyed-Hash Message Authentication Code): szablon hmac może zawierać dowolny algorytm SHA lub implementację przy użyciu hmac(<sha-alg>) bądź hmac(<sha-impl>).
stdrng drbg_pr_hmac_sha1, drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512 Tak Wystąpienie HMAC_DRBG z nazwaną funkcją skrótu i włączoną odpornością na prognozy: uwzględniane 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 Taki sam jak algorytm drbg_pr_*, ale z wyłączoną odpornością na prognozy. Kod jest udostępniany wariantowi odpornem na prognozy. 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 Występuje tylko w jądrze w wersji 5.15 lub nowszej.
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ń.

  • Tworzenie w Bazelu:

    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 dyrektora ds. kryptowalut

Aby można było obsługiwać moduł jądra, system operacyjny musi działać w trybie jednego operatora. Android obsługuje je automatycznie za pomocą sprzętu do zarządzania pamięcią w procesorze.

Modułu jądra nie można zainstalować osobno. Jest on częścią oprogramowania układowego urządzenia i ładowany automatycznie podczas rozruchu. Działa ona tylko w zatwierdzonym trybie działania.

Crypto Officer może umożliwić przeprowadzenie autotestów w dowolnym momencie, ponownie uruchamiając urządzenie.

Wskazówki dla użytkownika

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

Stosowanie algorytmów do celów zgodności z FIPS jest ograniczone do zatwierdzonych algorytmów. Aby spełnić wymóg „wskaźnika usługi” standardu FIPS 140-3, moduł zawiera funkcję fips140_is_approved_service, która wskazuje, czy algorytm został zatwierdzony.

Błędy autotestu

W przypadku niepowodzenia autotestu moduł jądra wywołuje panikę, a urządzenie nie uruchamia się dalej. Jeśli zrestartowanie urządzenia nie rozwiąże problemu, urządzenie musi uruchomić się w trybie przywracania, aby naprawić problem, ponownie instalując urządzenie.


  1. Implementacje AES-GCM w module mogą być zatwierdzone przez algorytm, ale nie jako zatwierdzone. Można je zweryfikować, ale z punktu widzenia modułu FIPS AES-GCM nie może być uznawany za zatwierdzony algorytm. Dzieje się tak, ponieważ wymagania modułu FIPS w GCM są niezgodne z implementacjami GCM, które nie generują własnych IV.