Android 7.0 i nowsze wersje obsługują szyfrowanie oparte na plikach (FBE). Szyfrowanie na podstawie plików umożliwia szyfrowanie różnych plików za pomocą różnych kluczy, które można odblokowywać niezależnie.
Z tego artykułu dowiesz się, jak włączyć szyfrowanie na podstawie plików na nowych urządzeniach i jak aplikacje systemowe mogą korzystać z interfejsów API bezpośredniego rozruchu, aby zapewnić użytkownikom najlepsze i najbezpieczniejsze środowisko.
Wszystkie urządzenia z Androidem 10 lub nowszym muszą używać szyfrowania opartego na plikach.
Bezpośredni rozruch
Szyfrowanie na podstawie plików włącza nową funkcję bezpośredniego uruchamiania, którą wprowadziliśmy w Androidzie 7.0. Bezpośrednie uruchamianie pozwala szyfrowanym urządzeniom uruchamiać się bezpośrednio na ekranie blokady. Wcześniej na zaszyfrowanych urządzeniach korzystających z szyfrowania pełnego dysku (FDE) użytkownicy musieli podać dane logowania, aby uzyskać dostęp do jakichkolwiek danych, co uniemożliwiało telefonowi wykonywanie wszystkich czynności poza podstawowymi. Na przykład nie działały alarmy, usługi ułatwień dostępu były niedostępne, a telefony nie mogły odbierać połączeń. Mogły wykonywać tylko podstawowe operacje w dialerze alarmowym.
Wprowadzenie szyfrowania opartego na plikach (FBE) i nowych interfejsów API, które informują aplikacje o szyfrowaniu, umożliwia tym aplikacjom działanie w ograniczonym kontekście. Może się to zdarzyć, zanim użytkownicy podadzą swoje dane logowania, a prywatne informacje o użytkownikach pozostają chronione.
Na urządzeniu z funkcją FBE każdy użytkownik ma 2 miejsca na dane dostępne dla aplikacji:
- Pamięć zaszyfrowana (CE) to domyślna lokalizacja pamięci, która jest dostępna dopiero po odblokowaniu urządzenia przez użytkownika.
- Pamięć zaszyfrowana na urządzeniu (DE), czyli lokalizacja pamięci dostępna zarówno w trybie bezpośredniego uruchamiania, jak i po odblokowaniu urządzenia przez użytkownika.
Dzięki temu profile służbowe są bezpieczniejsze, ponieważ można chronić więcej niż jednego użytkownika naraz, ponieważ szyfrowanie nie opiera się już tylko na haśle podczas uruchamiania.
Interfejs Direct Boot API umożliwia aplikacjom obsługującym szyfrowanie na dostęp do każdego z tych obszarów. W cyklu życia aplikacji wprowadziliśmy zmiany, aby uwzględnić potrzebę powiadamiania aplikacji o odblokowaniu pamięci CE przez użytkownika w odpowiedzi na pierwsze wpisanie danych logowania na ekranie blokady lub w przypadku profilu służbowego, który zawiera wyzwanie służbowe. Urządzenia z Androidem 7.0 muszą obsługiwać nowe interfejsy API i cykle życia niezależnie od tego, czy zostały wdrożone FBE. Bez FBE pamięć DE i CE jest zawsze odblokowana.
Pełna implementacja szyfrowania opartego na plikach w systemach plików Ext4 i F2FS jest udostępniana w ramach projektu Android Open Source Project (AOSP) i można ją włączyć tylko na urządzeniach spełniających wymagania. Producenci, którzy zdecydują się na korzystanie z FBE, mogą szukać sposobów optymalizacji tej funkcji w zależności od używanego układu na chipie (SoC).
Wszystkie niezbędne pakiety w AOSP zostały zaktualizowane, aby obsługiwały bezpośrednie uruchamianie. Jeśli jednak producenci urządzeń używają niestandardowych wersji tych aplikacji, chcą dopilnować, by istniały co najmniej pakiety bezpośredniego rozruchu, które zapewniają następujące usługi:
- Usługi telefoniczne i telefon
- Metoda wprowadzania haseł na ekranie blokady
Przykłady i źródło
Android udostępnia referencyjną implementację szyfrowania na podstawie plików, w której funkcja Vold (system/vold) umożliwia zarządzanie urządzeniami pamięci masowej i woluminami na Androidzie. Dodanie FBE udostępnia kilka nowych poleceń, które umożliwiają zarządzanie klawiszami CE i DE przez wielu użytkowników. Oprócz zmian w jądrze, które umożliwiają korzystanie z funkcji szyfrowania plików w jądrze, wiele pakietów systemowych, w tym ekran blokady i interfejs SystemUI, zostało zmodyfikowanych, aby obsługiwały funkcje FBE i Direct Boot. Należą do nich:
- AOSP Dialer (pakiety/aplikacje/telefon)
- Zegar biurkowy (pakiety/aplikacje/DeskClock)
- LatinIME (pakiety/metody wejściowe/LatinIME)*
- Aplikacja Ustawienia (pakiety/aplikacje/ustawienia)*
- SystemUI (ramki/base/pakiety/SystemUI)*
* Aplikacje systemowe, które używają atrybutu manifestu defaultToDeviceProtectedStorage
Więcej przykładów aplikacji i usług, które korzystają z szyfrowania, można znaleźć, uruchamiając polecenie mangrep directBootAware
w katalogu platform lub pakietów w drzewie źródłowym AOSP.
Zależności
Aby można było bezpiecznie korzystać z implementacji FBE w AOSP, urządzenie musi spełniać te zależności:
- Obsługa jądra w przypadku szyfrowania Ext4 lub F2FS.
- Obsługa Keymastera w przypadku HAL w wersji 1.0 lub nowszej. Usługa Keymaster 0.3 nie jest obsługiwana, ponieważ nie zapewnia ona niezbędnych możliwości i nie zapewnia wystarczającej ochrony kluczy szyfrowania.
- Systemy Keymaster/Keystore i Gatekeeper muszą być zaimplementowane w zaufanym środowisku wykonawczym (TEE), aby zapewnić ochronę kluczy DE, tak aby nieautoryzowany system operacyjny (niestandardowy system operacyjny wyświetlony na urządzeniu) nie mógł po prostu żądać kluczy DE.
- Główny element zaufania sprzętowego i weryfikacja podczas uruchamiania są wymagane do zainicjowania Keymastera, aby klucze DE nie były dostępne dla nieautoryzowanego systemu operacyjnego.
Implementacja
Przede wszystkim aplikacje takie jak budziki, telefon i ułatwienia dostępu powinny być zgodne z android:directBootAware zgodnie z dokumentacją dla deweloperów dotyczącą DirectBoot.
Obsługa jądra
Obsługa jądra dla szyfrowania Ext4 i F2FS jest dostępna w powszechnie używanych jądrach Androida w wersji 3.18 i nowszych. Aby je włączyć w jądrze w wersji 5.1 lub nowszej, użyj polecenia:
CONFIG_FS_ENCRYPTION=y
W przypadku starszych jąder użyj opcji CONFIG_EXT4_ENCRYPTION=y
, jeśli userdata
system plików urządzenia to Ext4, lub CONFIG_F2FS_FS_ENCRYPTION=y
, jeśli userdata
system plików urządzenia to F2FS.
Jeśli Twoje urządzenie obsługuje pamięć możliwą do wdrożenia lub korzysta z szyfrowania metadanych w pamięci wewnętrznej, włącz też opcje konfiguracji jądra potrzebne do szyfrowania metadanych, jak opisano w dokumentacji szyfrowania metadanych.
Oprócz funkcjonalnego wsparcia szyfrowania Ext4 lub F2FS producenci urządzeń powinni również włączyć przyspieszenie kryptograficzne, aby przyspieszyć szyfrowanie plików i poprawić komfort użytkownika. Na przykład na urządzeniach z procesorem ARM64 można włączyć akcelerację ARMv8 CE (Cryptography Extensions), ustawiając te opcje konfiguracji jądra:
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_SHA2_ARM64_CE=y
Aby jeszcze bardziej zwiększyć wydajność i zredukować zużycie energii, producenci urządzeń mogą też rozważyć wdrożenie sprzętu do szyfrowania w transmisji, który szyfruje i odszyfrowuje dane w drodze do lub z urządzenia do przechowywania danych. Typowe jądra Androida (w wersji 4.14 i nowszej) zawierają platformę, która pozwala na używanie wbudowanego szyfrowania, gdy dostępna jest obsługa sterowników sprzętu i dostawców. Wbudowaną platformę szyfrowania można włączyć, ustawiając te opcje konfiguracji jądra:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
Jeśli urządzenie korzysta z pamięci UFS, włącz też:
CONFIG_SCSI_UFS_CRYPTO=y
Jeśli urządzenie korzysta z pamięci eMMC, włącz też:
CONFIG_MMC_CRYPTO=y
Włącz szyfrowanie na podstawie plików
Włączenie FBE na urządzeniu wymaga włączenia go na pamięci wewnętrznej (userdata
). W ten sposób automatycznie włączysz FBE na pamięci adoptowanej. W razie potrzeby format szyfrowania na pamięci adoptowanej można jednak zastąpić.
Pamięć wewnętrzna
Funkcja FBE jest włączana przez dodanie opcji fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]]
do kolumny fs_mgr_flags w wierszu fstab
w pliku userdata
. Ta opcja określa format szyfrowania w pamięci wewnętrznej. Zawiera maksymalnie 3 parametry rozdzielone dwukropkiem:
- Parametr
contents_encryption_mode
określa, który algorytm kryptograficzny jest używany do szyfrowania zawartości pliku. Może to byćaes-256-xts
lubadiantum
. Od Androida 11 można go też pozostawić pusty, aby użyć domyślnego algorytmu (aes-256-xts
). - Parametr
filenames_encryption_mode
określa, który algorytm kryptograficzny jest używany do szyfrowania nazw plików. To może byćaes-256-cts
,aes-256-heh
,adiantum
lubaes-256-hctr2
. Jeśli nie podasz żadnej wartości, domyślna wartość toaes-256-cts
, jeślicontents_encryption_mode
ma wartośćaes-256-xts
, lubadiantum
, jeślicontents_encryption_mode
ma wartośćadiantum
. - Parametr
flags
, nowy w Androidzie 11, to lista flag rozdzielana znakiem+
. Obsługiwane są te flagi:- Flaga
v1
wybiera zasady szyfrowania w wersji 1, a flagav2
– zasady szyfrowania w wersji 2. Zasady szyfrowania w wersji 2 wykorzystują bezpieczniejszą i bardziej elastyczną funkcję pobierania kluczy. Domyślnie jest to wersja 2, jeśli urządzenie zostało uruchomione na Androidzie 11 lub nowszym (zgodnie z wartością parametruro.product.first_api_level
), lub wersja 1, jeśli urządzenie zostało uruchomione na Androidzie 10 lub starszym. - Flaga
inlinecrypt_optimized
wybiera format szyfrowania zoptymalizowany pod kątem wbudowanego sprzętu do szyfrowania, który nie obsługuje wydajnie dużej liczby kluczy. Jest to możliwe dzięki pobieraniu tylko 1 klucza szyfrowania zawartości pliku na klucz CE lub DE zamiast jednego dla każdego pliku. Generowanie IV (wektorów inicjujących) jest odpowiednio dostosowywane. - Flaga
emmc_optimized
jest podobna doinlinecrypt_optimized
, ale wybiera również metodę generowania IV, która ogranicza liczbę bitów do 32 bitów. Tej flagi należy używać tylko w przypadku sprzętu do szyfrowania w transmisji zgodnego ze specyfikacją JEDEC eMMC v5.2, który obsługuje tylko 32-bitowe IV. W przypadku innego sprzętowego szyfrowania w strumieniu danych użyj zamiast tegoinlinecrypt_optimized
. Tego parametru nie należy używać w przypadku pamięci na bazie UFS, ponieważ specyfikacja UFS zezwala na użycie 64-bitowych IV. - Na urządzeniach, które obsługują klucze zapakowane sprzętowo, flaga
wrappedkey_v0
umożliwia używanie kluczy zapakowanych sprzętowo w przypadku FBE. Tej opcji można używać tylko w połączeniu z opcją podłączeniainlinecrypt
i flagąinlinecrypt_optimized
lubemmc_optimized
. - Flaga
dusize_4k
wymusza, aby rozmiar jednostki danych szyfrowania wynosił 4096 bajtów, nawet jeśli rozmiar bloku w systemie plików nie wynosi 4096 bajtów. Rozmiar jednostki danych szyfrowania to poziom szczegółowości szyfrowania treści pliku. Ta flaga jest dostępna od Androida 15. Tego parametru należy używać tylko do włączania korzystania z hardware'owego szyfrowania w przesyłaniu, które nie obsługuje jednostek danych większych niż 4096 bajtów, na urządzeniu, które używa rozmiaru strony większego niż 4096 bajtów i korzysta z systemu plików f2fs.
- Flaga
Jeśli nie używasz sprzętu do szyfrowania wbudowanego, dla większości urządzeń zalecamy ustawienie fileencryption=aes-256-xts
. Jeśli używasz sprzętu do szyfrowania wbudowanego, dla większości urządzeń zalecane jest ustawienie fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
(lub odpowiednik fileencryption=::inlinecrypt_optimized
). Na urządzeniach bez żadnej akceleracji AES możesz użyć Adiantum zamiast AES (ustawienie fileencryption=adiantum
).
Od Androida 14 AES-HCTR2 jest preferowanym trybem szyfrowania nazw plików na urządzeniach z przyspieszonymi instrukcjami kryptograficznymi. Jednak tylko nowsze jądra Androida obsługują
AES-HCTR2. W przyszłej wersji Androida ma to być domyślny tryb szyfrowania nazw plików. Jeśli jądro obsługuje AES-HCTR2, można włączyć szyfrowanie nazw plików, ustawiając wartość filenames_encryption_mode
na aes-256-hctr2
. W najprostszym przypadku można użyć funkcji fileencryption=aes-256-xts:aes-256-hctr2
.
Na urządzeniach z Androidem 10 lub starszym można też użyć wartości fileencryption=ice
, aby określić użycie trybu szyfrowania zawartości pliku FSCRYPT_MODE_PRIVATE
. Ten tryb nie jest obsługiwany przez wspólne jądra Androida, ale może być implementowany przez dostawców za pomocą niestandardowych poprawek do jądra. Format na dysku wygenerowany przez ten tryb był specyficzny dla dostawcy. Na urządzeniach z Androidem 11 lub nowszym ten tryb nie jest już dozwolony i zamiast niego należy użyć standardowego formatu szyfrowania.
Domyślnie szyfrowanie zawartości plików odbywa się za pomocą interfejsu szyfrowania jądra Linuksa. Jeśli zamiast tego chcesz używać sprzętu do szyfrowania wbudowanego, dodaj też opcję podłączenia inlinecrypt
. Pełna linia fstab
może wyglądać tak:
/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
Pamięć elastyczna
Od Androida 9 FBE i pamięć adaptacyjna mogą być używane razem.
Wskazanie opcji fileencryption
w pliku fstab w przypadku userdata
powoduje automatyczne włączanie FBE i szyfrowania metadanych w przystosowywanym magazynie. Możesz jednak zastąpić formaty szyfrowania FBE lub metadanych w przypadku adoptowanego miejsca na dane, ustawiając właściwości w PRODUCT_PROPERTY_OVERRIDES
.
Na urządzeniach z Androidem 11 lub nowszym używaj tych właściwości:
ro.crypto.volume.options
(nowy w Androidzie 11) wybiera format szyfrowania FBE w pamięci wewnętrznej. Ma tę samą składnię co argument opcjifileencryption
fstab i korzysta z tych samych wartości domyślnych. Zapoznaj się powyżej z zaleceniami dotyczącymifileencryption
, aby dowiedzieć się, z czego tu korzystać.ro.crypto.volume.metadata.encryption
wybiera format szyfrowania metadanych w pamięci adoptowanej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.
Na urządzeniach z Androidem 10 lub starszym używaj tych właściwości:
ro.crypto.volume.contents_mode
wybiera tryb szyfrowania treści. Jest to odpowiednik pierwszego polaro.crypto.volume.options
rozdzielonego dwukropkiem.ro.crypto.volume.filenames_mode
wybiera tryb szyfrowania nazw plików. Jest to pole odpowiadające drugiemu polu oddzielonemu dwukropkiem wro.crypto.volume.options
, z tą różnicą, że domyślnie na urządzeniach z Androidem 10 lub starszym jest to poleaes-256-heh
. Na większości urządzeń trzeba to zastąpić ustawieniemaes-256-cts
.ro.crypto.fde_algorithm
iro.crypto.fde_sector_size
wybierz format szyfrowania metadanych w pamięci adoptowanej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.
Integracja z Keymasterem
HAL Keymaster należy uruchamiać jako część klasy early_hal
.
Wynika to z tego, że FBE wymaga, aby Keymaster był gotowy do obsługi żądań na etapie uruchamiania post-fs-data
, czyli na etapie konfigurowania kluczy początkowych w vold
.
Wyklucz katalogi
init
stosuje systemowy klucz DE do wszystkich katalogów najwyższego poziomu w /data
, z wyjątkiem katalogów, które muszą być niezaszyfrowane, takich jak katalog zawierający sam klucz systemowy DE oraz katalogi zawierające katalogi użytkownika CE lub DE. Klucze szyfrowania są stosowane rekurencyjnie i nie można ich zastąpić podkatalogami.
W Androidzie 11 i nowszych kluczach, które mają zastosowanie do katalogów, init
można sterować za pomocą argumentu encryption=<action>
do polecenia mkdir
w skryptach init. Możliwe wartości <action>
są opisane w README dla języka inicjalizacji Androida.
W Androidzie 10 działania szyfrowania init
zostały zakodowane na stałe w tym miejscu:
/system/extras/libfscrypt/fscrypt_init_extensions.cpp
W Androidzie 9 i starszych lokalizacji lokalizacja była:
/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp
Możesz dodać wyjątki, aby uniemożliwić szyfrowanie niektórych katalogów. Po wprowadzeniu takich modyfikacji producent urządzenia powinien zastosować zasady SELinux, które przyznają dostęp tylko tym aplikacjom, które muszą korzystać z niezaszyfrowanego katalogu. Powinno to wykluczyć wszystkie niezaufane aplikacje.
Jedynym znanym dozwolonym przypadkiem użycia jest obsługa starszych funkcji OTA.
Obsługa bezpośredniego rozruchu w aplikacjach systemowych
Ustawienie aplikacji na potrzeby funkcji Bezpośredniego uruchamiania
Aby ułatwić szybkie przenoszenie aplikacji systemowych, dodaliśmy 2 nowe atrybuty, które można ustawić na poziomie aplikacji. Atrybut defaultToDeviceProtectedStorage
jest dostępny tylko w przypadku aplikacji systemowych. Atrybut directBootAware
jest dostępny dla wszystkich.
<application android:directBootAware="true" android:defaultToDeviceProtectedStorage="true">
Atrybut directBootAware
na poziomie aplikacji to skrócony sposób oznaczania wszystkich komponentów w aplikacji jako obsługujących szyfrowanie.
Atrybut defaultToDeviceProtectedStorage
przekierowuje domyślną lokalizację pamięci aplikacji na pamięć DE zamiast na pamięć CE.
Aplikacje systemowe korzystające z tej flagi muszą dokładnie kontrolować wszystkie dane przechowywane w domyślnej lokalizacji i zmieniać ścieżki danych wrażliwych, aby korzystać z pamięci CE. Producenci urządzeń korzystający z tej opcji powinni dokładnie sprawdzić dane, które przechowują, aby upewnić się, że nie zawierają one danych osobowych.
W tym trybie dostępne są te interfejsy System API, które umożliwiają w razie potrzeby jawne zarządzanie kontekstem obsługiwanym przez pamięć CE. Są one odpowiednikami interfejsów Device Protected.
Context.createCredentialProtectedStorageContext()
Context.isCredentialProtectedStorage()
Obsługa wielu użytkowników
Każdy użytkownik w środowisku wielu użytkowników otrzymuje oddzielny klucz szyfrowania. Każdy użytkownik otrzymuje 2 klucze: DE i CE. Użytkownik 0 musi najpierw zalogować się na urządzeniu, ponieważ jest użytkownikiem specjalnym. Jest to istotne w przypadku administracji urządzeniem.
Aplikacje wykrywające kryptowaluty współdziałają z użytkownikami w taki sposób:
INTERACT_ACROSS_USERS
i INTERACT_ACROSS_USERS_FULL
umożliwiają aplikacji działanie wśród wszystkich użytkowników urządzenia. Te aplikacje mają jednak dostęp tylko do katalogów zaszyfrowanych za pomocą CE w przypadku użytkowników, którzy są już odblokowani.
Aplikacja może swobodnie korzystać z interakcji w Niemczech, ale jeden użytkownik bez blokady nie oznacza, że wszyscy użytkownicy na urządzeniu są odblokowani. Aplikacja powinna sprawdzić ten stan przed próbą uzyskania dostępu do tych obszarów.
Każdy identyfikator użytkownika profilu służbowego również otrzymuje 2 klucze: DE i CE. Gdy wyzwanie służbowe zostanie spełnione, użytkownik profilu zostanie odblokowany, a administrator kluczy (w profilu TEE) będzie mógł udostępnić klucz TEE profilu.
Obsługa aktualizacji
Partycja odzyskiwania nie ma dostępu do pamięci chronionej przez DE na partycji userdata. Zdecydowanie zalecamy, aby urządzenia z FBE obsługiwały OTA za pomocą aktualizacji systemu A/B. OTA można zastosować podczas normalnego działania, więc nie trzeba przywracać dostępu do danych na zaszyfrowanym dysku.
Jeśli używasz starszego rozwiązania OTA, które wymaga przywrócenia, aby uzyskać dostęp do pliku OTA na partycji userdata
:
- Utwórz katalog najwyższego poziomu (np.
misc_ne
) w partycjiuserdata
. - Skonfiguruj niezaszyfrowany katalog najwyższego poziomu (patrz Wykluczanie katalogów).
- Utwórz katalog w katalogu najwyższego poziomu, aby przechowywać pakiety OTA.
- Dodaj regułę SELinux i konteksty plików, aby kontrolować dostęp do tego katalogu i jego zawartości. Tylko proces lub aplikacje otrzymujące aktualizacje OTA powinny mieć możliwość odczytu i zapisu w tym katalogu. Żadna inna aplikacja ani proces nie powinny mieć dostępu do tego katalogu.
Weryfikacja
Aby upewnić się, że wdrożona wersja funkcji działa zgodnie z oczekiwaniami, najpierw uruchom liczne testy szyfrowania CTS, takie jak DirectBootHostTest i EncryptionTest.
Jeśli urządzenie ma Androida 11 lub nowszego, uruchom też vts_kernel_encryption_test:
atest vts_kernel_encryption_test
lub:
vts-tradefed run vts -m vts_kernel_encryption_test
Producenci urządzeń mogą też wykonywać poniższe testy ręczne. Na urządzeniu z włączonym FBE:
- Sprawdź, czy
ro.crypto.state
istnieje- Upewnij się, że
ro.crypto.state
jest zaszyfrowane
- Upewnij się, że
- Sprawdź, czy istnieje zmienna
ro.crypto.type
.- Sprawdź, czy
ro.crypto.type
ma wartośćfile
- Sprawdź, czy
Testerzy mogą też sprawdzić, czy pamięć CE jest zablokowana, zanim urządzenie zostanie odblokowane po raz pierwszy od uruchomienia. Aby to zrobić, użyj kompilacji userdebug
lub eng
, ustaw kod PIN, wzór lub hasło na głównym koncie użytkownika i zrestartuj urządzenie. Przed odblokowaniem urządzenia uruchom to polecenie, aby sprawdzić pamięć CE użytkownika głównego. Jeśli urządzenie korzysta z trybu użytkownika systemu bez interfejsu graficznego (większość urządzeń motoryzacyjnych), głównym użytkownikiem jest użytkownik 10, więc uruchom:
adb root; adb shell ls /data/user/10
Na innych urządzeniach (w większości przypadków nie są to urządzenia motoryzacyjne) głównym użytkownikiem jest użytkownik 0, a zatem:
adb root; adb shell ls /data/user/0
Sprawdź, czy wymienione nazwy plików są zakodowane w formacie Base64, co oznacza, że pliki są zaszyfrowane, a klucz do ich odszyfrowania nie jest jeszcze dostępny. Jeśli nazwy plików są wymienione w postaci zwykłego tekstu, coś jest nie tak.
Producentów urządzeń zachęcamy też do przetestowania upstreamowych testów Linuksa dla fscrypt na swoich urządzeniach lub jądrach. Te testy są częścią zestawu testów xfstests dotyczących systemu plików. Jednak testy te nie są oficjalnie obsługiwane przez Androida.
Szczegóły implementacji AOSP
Ta sekcja zawiera szczegółowe informacje o implementacji AOSP oraz sposób działania szyfrowania na podstawie plików. Producenci urządzeń nie powinni wprowadzać żadnych zmian, aby korzystać z FBE i Direct Boot na swoich urządzeniach.
szyfrowanie fscrypt
Implementacja AOSP korzysta z szyfrowania „fscrypt” (obsługiwanego przez ext4 i f2fs) w jądrze i zazwyczaj jest skonfigurowana tak, aby:
- Szyfrowanie zawartości pliku za pomocą AES-256 w trybie XTS
- Szyfruj nazwy plików za pomocą AES-256 w trybie CBC-CTS
Obsługiwane jest też szyfrowanie Adiantum. Gdy szyfrowanie Adiantum jest włączone, zarówno zawartość plików, jak i ich nazwy są szyfrowane za pomocą Adiantum.
fscrypt obsługuje 2 wersje zasad szyfrowania: wersję 1 i 2. Wersja 1 została wycofana, a wymagania dotyczące zgodności z CDD w przypadku urządzeń z Androidem 11 lub nowszym są zgodne tylko z wersją 2. Zasady szyfrowania w wersji 2 używają funkcji HKDF-SHA512 do wyprowadzania rzeczywistych kluczy szyfrowania z kluczy dostarczonych przez przestrzeń użytkownika.
Więcej informacji o szyfrowaniu fscrypt znajdziesz w dokumentacji nadrzędnego jądra.
Klasy pamięci
W tabeli poniżej znajdziesz bardziej szczegółową listę kluczy FBE i katalogów, które są przez nie chronione:
Klasa pamięci masowej | Opis | Katalogi |
---|---|---|
Niezaszyfrowane | Katalogi w /data , które nie mogą lub nie muszą być chronione za pomocą FBE. Na urządzeniach szyfrowanych metadanych katalogi te nie są w rzeczywistości niezaszyfrowane, lecz chronione przez klucz szyfrowania metadanych, który jest odpowiednikiem systemu DE. |
|
System DE | Dane zaszyfrowane na urządzeniu niepowiązane z konkretnym użytkownikiem |
|
Zależnie od rozruchu | tymczasowe pliki systemowe, które nie muszą przetrwać po ponownym uruchomieniu; | /data/per_boot |
Użytkownik CE (wewnętrzny) | Szyfrowane dane logowania poszczególnych użytkowników w pamięci wewnętrznej |
|
Użytkownik DE (wewnętrzny) | Szyfrowane przez urządzenie dane poszczególnych użytkowników w pamięci wewnętrznej |
|
Oznaczenie CE użytkownika (możliwość dostosowania) | Dane zaszyfrowane przy użyciu danych logowania użytkownika w pamięci dostosowywanej |
|
Użytkownik DE (można dostosować) | Szyfrowane przez urządzenie dane poszczególnych użytkowników w pamięci masowej |
|
Przechowywanie kluczy i ich ochrona
Wszystkie klucze FBE są zarządzane przez vold
i są przechowywane w zaszyfrowanej formie na dysku, z wyjątkiem klucza uruchamiania, który nie jest wcale przechowywany. Poniższa tabela zawiera lokalizacje, w których przechowywane są różne klucze FBE:
Typ klucza | Lokalizacja klucza | Klasa pamięci lokalizacji klucza |
---|---|---|
Systemowy klucz DE | /data/unencrypted |
Niezaszyfrowane |
Klucze CE (wewnętrzne) użytkownika | /data/misc/vold/user_keys/ce/${user_id} |
System DE |
Klucze wewnętrzne (wewnętrzne) użytkownika | /data/misc/vold/user_keys/de/${user_id} |
System DE |
Klucze CE (adaptacyjne) użytkownika | /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} |
Użytkownik CE (wewnętrzny) |
Klucze DE (dostępne) użytkownika | /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} |
Użytkownik DE (wewnętrzny) |
Jak widać w poprzedniej tabeli, większość kluczy FBE jest przechowywana w katalogach zaszyfrowanych za pomocą innego klucza FBE. Kluczy nie można odblokować, dopóki nie odblokuje się klasa pamięci, która je zawiera.
vold
stosuje również warstwę szyfrowania do wszystkich kluczy FBE. Każdy klucz (oprócz kluczy CE do pamięci wewnętrznej) jest szyfrowany za pomocą algorytmu AES-256-GCM przy użyciu własnego klucza Keystore, który nie jest dostępny poza TEE. Dzięki temu kluczy FBE nie można odblokować, dopóki nie uruchomi się nieznany system operacyjny, co jest wymagane przez weryfikację podczas uruchamiania. Oporność na wycofanie jest też żądana dla klucza magazynu kluczy, co umożliwia bezpieczne usuwanie kluczy FBE na urządzeniach, na których Keymaster obsługuje rezystancję względem wycofania. W razie braku możliwości odwrócenia zmian jako awaryjny klucz zapasowy używany jest hasz SHA-512 o długości 16 384 losowych bajtach zapisany w pliku secdiscardable
, który jest przechowywany razem z kluczem jako tag identyfikatora aplikacji klucza Keystore. Aby odzyskać klucz FBE, trzeba odzyskać wszystkie te bajty.
Klucze CE do pamięci wewnętrznej są silniejsze, dzięki czemu nie można ich odblokować bez znajomości współczynnika wiedzy (LSKF) użytkownika (kodu PIN, wzoru lub hasła), bezpiecznego tokena resetowania kodu dostępu lub zarówno klucza po stronie klienta, jak i klucza po stronie serwera w przypadku operacji przy ponownym uruchomieniu. Tokeny resetowania kodu dostępu można tworzyć tylko dla profili służbowych i w pełni zarządzanych urządzeń.
W tym celu vold
szyfruje każdy klucz CE w pamięci wewnętrznej za pomocą klucza AES-256-GCM pobranego z hasła syntetycznego użytkownika.
Hasło syntetyczne to stały tajny klucz kryptograficzny o wysokiej entropii, który jest generowany losowo dla każdego użytkownika. Konto LockSettingsService
w system_server
zarządza hasłem syntetycznym i sposobami jego ochrony.
Aby chronić syntetyczne hasło za pomocą klucza LSKF,LockSettingsService
najpierw rozciągasz ten klucz, przepuszczając go przez funkcję scrypt
, aby uzyskać czas około 25 ms i wykorzystanie pamięci około 2 MiB. Ponieważ klucze LSKF są zwykle krótkie, ten krok zwykle nie zapewnia dużej ochrony. Główną warstwą zabezpieczeń jest Secure Element (SE) lub wymuszane przez TEE ograniczenie szybkości opisane poniżej.
Jeśli urządzenie ma bezpieczny element (SE), LockSettingsService
mapuje rozciągnięty LSKF na losowy obiekt tajny o wysokiej entropii przechowywany w SE przy użyciu HAL Weaver. LockSettingsService
następnie dwukrotnie szyfruje hasło syntetyczne: najpierw za pomocą klucza oprogramowania wygenerowanego na podstawie rozciągniętego klucza LSKF i tajemnicy Weavera, a potem za pomocą klucza Keystore bez uwierzytelniania. Powoduje to wymuszanie przez SE ograniczenie liczby przypuszczalnych operacji LSKF.
Jeśli urządzenie nie ma zabezpieczenia zabezpieczonego, LockSettingsService
zamiast tego używa rozciągniętego LSKF jako hasła bramki. LockSettingsService
następnie szyfruje syntetyczne hasło dwa razy: najpierw za pomocą klucza oprogramowania wygenerowanego na podstawie rozciągniętego klucza LSKF i ciągu znaków skrótu pliku, a potem za pomocą klucza Keystore, który jest powiązany z autoryzacją w rejestrze Gatekeeper. Umożliwia to ograniczenie szybkości prób LSKF narzucone przez TEE.
Gdy zmienisz klucz LSKF, LockSettingsService
usunie wszystkie informacje powiązane z połączeniem hasła syntetycznego ze starym kluczem LSKF. Na urządzeniach, które obsługują klucze Keystore z obsługą Weaver lub przywracania, gwarantuje to bezpieczne usunięcie starego powiązania. Z tego powodu opisane tu zabezpieczenia są stosowane nawet wtedy, gdy użytkownik nie ma ustawionego LSKF.