Android 7.0 i nowsze wersje obsługują szyfrowanie oparte na plikach (FBE). Szyfrowanie na poziomie pliku umożliwia szyfrowanie różnych plików za pomocą różnych kluczy, które można odblokować niezależnie.
Z tego artykułu dowiesz się, jak włączyć szyfrowanie plików na nowych urządzeniach oraz jak aplikacje systemowe mogą korzystać z interfejsów Direct Boot API, aby zapewnić użytkownikom jak najlepszą ochronę.
Wszystkie urządzenia z Androidem 10 lub nowszym muszą używać szyfrowania opartego na plikach.
Bezpośredni rozruch
Szyfrowanie plików umożliwia nową funkcję wprowadzoną w Androidzie 7.0, zwaną Direct Boot. Bezpośrednie uruchamianie pozwala szyfrowanym urządzeniom uruchamiać się bezpośrednio na ekranie blokady. Wcześniej na zaszyfrowanych urządzeniach korzystających z szyfrowania całego dysku (FDE) użytkownicy musieli podać dane logowania, aby uzyskać dostęp do danych. W efekcie telefon nie mógł wykonywać żadnych operacji oprócz najbardziej podstawowych. 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 użytkowników 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 dostęp do tych obszarów. Wprowadziliśmy zmiany w cyklu życia aplikacji, aby umożliwić im powiadamianie o odblokowaniu pamięci CE użytkownika w odpowiedzi na wprowadzenie przez niego po raz pierwszy danych logowania na ekranie blokady lub, w przypadku profilu służbowego, wyzwanie wyzwania służbowego. Urządzenia z Androidem 7.0 muszą obsługiwać te nowe interfejsy API i cykle życia niezależnie od tego, czy implementują FBE. Bez FBE pamięć DE i CE jest zawsze odblokowana.
Pełna implementacja szyfrowania plików w systemach plików Ext4 i F2FS jest dostępna w Projekcie Android Open Source (AOSP) i musi być włączona 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, muszą zadbać o to, aby w ramach uruchamiania bezpośredniego były dostępne co najmniej te pakiety:
- Dialer i usługi telefoniczne
- Metoda wprowadzania haseł na ekranie blokady
Przykłady i źródło
Android udostępnia referencyjne szyfrowanie oparte na plikach, w którym vold (system/vold) zapewnia funkcje do zarządzania urządzeniami i woluminami pamięci masowej na Androidzie. Dodanie FBE zapewnia vold kilka nowych poleceń do obsługi zarządzania kluczami w przypadku kluczy CE i DE 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:
- Dialer AOSP (pakiety/aplikacje/Dialer)
- Zegar (pakiety/aplikacje/DeskClock)
- LatinIME (packages/inputmethods/LatinIME)*
- Aplikacja Ustawienia (pakiety/aplikacje/Ustawienia)*
- SystemUI (frameworks/base/packages/SystemUI)*
* Aplikacje systemowe, które używają atrybutu manifestu defaultToDeviceProtectedStorage
Więcej przykładów aplikacji i usług obsługujących szyfrowanie można znaleźć, uruchamiając polecenie mangrep directBootAware
w katalogu frameworków lub pakietów w drzewie źródeł 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. Nie obsługujemy wersji Keymaster 0.3, ponieważ nie zapewnia ona niezbędnych funkcji ani wystarczającej ochrony kluczy szyfrowania.
- Keymaster/Keystore i Gatekeeper muszą być wdrażane w zaufanym środowisku wykonania (TEE), aby zapewnić ochronę kluczy DE. Dzięki temu nieautoryzowany system operacyjny (niestandardowy system operacyjny wgrany na urządzeniu) nie może po prostu poprosić o klucze 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 włączyć ją w jądrze w wersji 5.1 lub nowszej, użyj:
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 adoptowalną pamięć lub używa szyfrowania metadanych w pamięci wewnętrznej, włącz też opcje konfiguracji jądra potrzebne do szyfrowania metadanych zgodnie z opisem 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 trakcie ich przesyłania na urządzenie do przechowywania danych lub z niego. Wspólne jądra Androida (w wersji 4.14 lub nowszej) zawierają środowisko, które umożliwia stosowanie szyfrowania w linii, gdy dostępne jest wsparcie dla sterownika sprzętu i producenta. Ramę szyfrowania w postaci kodu wbudowanego 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łączanie szyfrowania opartego na plikach
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. Może to byćaes-256-cts
,aes-256-heh
,adiantum
lubaes-256-hctr2
. Jeśli nie podasz żadnej wartości, zostanie użyta wartość domyślnaaes-256-cts
, jeślicontents_encryption_mode
toaes-256-xts
, lubadiantum
, jeślicontents_encryption_mode
toadiantum
. - 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. Polityki szyfrowania w wersji 2 korzystają z bezpieczniejszej i bardziej elastycznej funkcji derywacji klucza. Domyślnie jest to wersja 2, jeśli urządzenie zostało uruchomione w Androidzie 11 lub nowszym (zgodnie z parametremro.product.first_api_level
), lub wersja 1, jeśli urządzenie zostało uruchomione w Androidzie 10 lub starszym. - Flaga
inlinecrypt_optimized
wybiera format szyfrowania zoptymalizowany pod kątem sprzętu do szyfrowania w strumieniu danych, który nie obsługuje efektywnie dużej liczby kluczy. Dokonuje tego, wyodrębniając jeden klucz szyfrowania zawartości pliku na klucz CE lub DE, a nie jeden na plik. Generowanie wektorów inicjalizacji (IV) jest odpowiednio dostosowywane. - Flaga
emmc_optimized
jest podobna do flagiinlinecrypt_optimized
, ale wybiera też metodę generowania IV, która ogranicza IV 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 tablice 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. Można go używać tylko w połączeniu z opcjąinlinecrypt
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. Używaj tego parametru tylko do włączania korzystania z hardware'owego szyfrowania w internecie, 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ętowego szyfrowania w strumieniu, zalecane ustawienie dla większości urządzeń to fileencryption=aes-256-xts
. Jeśli używasz sprzętowego szyfrowania w ramach, zalecane ustawienie dla większości urządzeń to fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
(lub równoważne fileencryption=::inlinecrypt_optimized
). Na urządzeniach bez żadnej formy przyspieszenia AES zamiast AES można użyć Adiantum, ustawiając 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 chcesz użyć sprzętowego szyfrowania w strumieniu, dodaj opcję 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ęć dostosowywana
Od Androida 9 można używać razem FBE i adoptable storage.
Wskazanie opcji fileencryption
fstab dla userdata
powoduje automatyczne włączenie FBE i szyfrowania metadanych w przypadku adoptowanego magazynu danych. 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żyj tych właściwości:
ro.crypto.volume.options
(nowy w Androidzie 11) wybiera format szyfrowania FBE w pamięci adoptowanej. Ma tę samą składnię co argument opcjifileencryption
fstab i korzysta z tych samych wartości domyślnych. Aby dowiedzieć się, jakie wartości należy tu użyć, zapoznaj się z zaleceniami dotyczącymifileencryption
powyżej.ro.crypto.volume.metadata.encryption
wybiera format szyfrowania metadanych w pamięci wewnętrznej. 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 pole odpowiadające pierwszemu polu w elementotypiero.crypto.volume.options
, które jest oddzielone 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ń należy wyraźnie ustawić wartośćaes-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
Interfejs HAL Keymaster powinien być uruchamiany w ramach klasy early_hal
.
Wynika to z tego, że FBE wymaga, aby Keymaster był gotowy do obsługi żądań na etapie wczytywania post-fs-data
, czyli wtedy, gdy vold
konfiguruje początkowe klucze.
Wykluczanie katalogów
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 systemowy klucz 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 klucz, który init
stosuje do katalogów, można kontrolować za pomocą argumentu encryption=<action>
w komendach 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
Na Androidzie 9 i starszych 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. Jeśli takie modyfikacje zostaną wprowadzone, producent urządzenia powinien uwzględnić zasady SELinux, które przyznają dostęp tylko aplikacjom, które muszą korzystać z niezaszyfrowanego katalogu. Powinny one wykluczać wszystkie niesprawdzone aplikacje.
Jedynym znanym dozwolonym przypadkiem użycia jest obsługa starszych funkcji OTA.
Obsługa bezpośredniego rozruchu w aplikacji systemowej
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 dla aplikacji systemowych. Atrybut directBootAware
jest dostępny dla wszystkich.
<application android:directBootAware="true" android:defaultToDeviceProtectedStorage="true">
Atrybut directBootAware
na poziomie aplikacji to skrót oznaczający, że wszystkie komponenty w aplikacji są szyfrowane.
Atrybut defaultToDeviceProtectedStorage
przekierowuje domyślną lokalizację pamięci aplikacji na pamięć DE zamiast na pamięć CE.
Aplikacje systemowe korzystające z tego parametru muszą dokładnie sprawdzić wszystkie dane przechowywane w domyślnej lokalizacji i zmienić ścieżki danych wrażliwych, aby używać pamięci CE. Producenci urządzeń korzystający z tej opcji powinni dokładnie sprawdzić dane, które przechowują, aby mieć pewność, ż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 wieloużytkownika otrzymuje osobny klucz szyfrowania. Każdy użytkownik otrzymuje 2 klucze: DE i CE. Użytkownik 0 musi najpierw zalogować się na urządzeniu, ponieważ jest to użytkownik specjalny. Dotyczy to zarządzania urządzeniami.
Aplikacje obsługujące kryptowaluty w ten sposób nawiązują interakcje z użytkownikami:
INTERACT_ACROSS_USERS
i INTERACT_ACROSS_USERS_FULL
pozwalają aplikacji działać na wszystkich użytkownikach 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 działać w obszarach DE, ale odblokowanie dostępu dla jednego użytkownika nie oznacza, że wszyscy użytkownicy na urządzeniu mają dostęp. Aplikacja powinna sprawdzić ten stan przed próbą uzyskania dostępu do tych obszarów.
Każdy identyfikator użytkownika profilu służbowego otrzymuje też 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 miejsca na dane chronionego za pomocą funkcji szyfrowania na partycji userdata. Zdecydowanie zalecamy, aby urządzenia z FBE obsługiwały OTA za pomocą aktualizacji systemu A/B. Ponieważ aktualizację OTA można zastosować podczas normalnej pracy, nie trzeba przywracać danych, aby uzyskać dostęp do zaszyfrowanego 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 (na przykład
misc_ne
) na partycjiuserdata
. - Skonfiguruj ten katalog najwyższego poziomu tak, aby nie był szyfrowany (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 mieć pewność, że zaimplementowana wersja funkcji działa zgodnie z oczekiwaniami, najpierw uruchom wiele testów szyfrowania CTS, takich 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ż wykonać te testy ręcznie. Na urządzeniu z włączonym FBE:
- Sprawdź, czy istnieje zmienna
ro.crypto.state
.- Upewnij się, że
ro.crypto.state
jest zaszyfrowane
- Upewnij się, że
- Sprawdź, czy istnieje zmienna
ro.crypto.type
.- Upewnij się, że
ro.crypto.type
ma wartośćfile
.
- Upewnij się, że
Testerzy mogą też sprawdzić, czy pamięć CE jest zablokowana, zanim urządzenie zostanie odblokowane po raz pierwszy od uruchomienia. Aby to zrobić, użyj wersji userdebug
lub eng
, ustaw kod PIN, wzór lub hasło dla głównego użytkownika i ponownym uruchom 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 w systemie bez głowy (większość urządzeń Automotive), główny użytkownik to 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ą wyświetlane 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. Te testy upstream nie są jednak oficjalnie obsługiwane przez Androida.
Szczegóły implementacji AOSP
W tej sekcji znajdziesz szczegółowe informacje o implementacji AOSP oraz opis działania szyfrowania na poziomie 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
- Szyfrowanie nazw 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: 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 w przestrzeni użytkownika.
Więcej informacji o fscrypt znajdziesz w dokumentacji jądra.
Klasy pamięci
W tabeli poniżej znajdziesz więcej informacji o kluczach FBE i katalogach, które chronią:
Klasa pamięci | Opis | Katalogi |
---|---|---|
Niezaszyfrowane | Katalogi w /data , które nie mogą lub nie muszą być chronione za pomocą FBE. Na urządzeniach, które korzystają z szyfrowania metadanych, te katalogi nie są w rzeczywistości odszyfrowane, ale są chronione przez klucz szyfrowania metadanych, który jest odpowiednikiem systemu DE. |
|
System DE | dane zaszyfrowane na urządzeniu, które nie są powiązane z konkretnym użytkownikiem; |
|
Włączanie | tymczasowe pliki systemowe, które nie muszą przetrwać po ponownym uruchomieniu; | /data/per_boot |
Użytkownik CE (wewnętrzny) | Dane zaszyfrowane przy użyciu danych logowania użytkownika w pamięci wewnętrznej |
|
Użytkownik DE (wewnętrzny) | Dane zaszyfrowane na urządzeniu dla 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ć) | Dane zaszyfrowane na urządzeniu dla poszczególnych użytkowników w przystosowywanej pamięci |
|
Przechowywanie i ochrona kluczy
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. W tabeli poniżej wymieniono lokalizacje, w których przechowywane są różne klucze FBE:
Typ klucza | Lokalizacja klucza | Klasa pamięci lokalizacji klucza |
---|---|---|
Klucz systemowy DE | /data/unencrypted |
Niezaszyfrowane |
Klucze użytkownika CE (wewnętrzne) | /data/misc/vold/user_keys/ce/${user_id} |
System DE |
Klucze użytkownika DE (wewnętrzne) | /data/misc/vold/user_keys/de/${user_id} |
System DE |
Klucze użytkownika CE (adopcyjne) | /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} |
Użytkownik CE (wewnętrzny) |
Klucze użytkownika DE (adoptowane) | /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 też 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. Ochrona przed przywracaniem jest również wymagana w przypadku klucza Keystore, co umożliwia bezpieczne usunięcie kluczy FBE na urządzeniach, na których Keymaster obsługuje ochronę przed przywracaniem. W razie braku możliwości odwrócenia zmian jako alternatywa stosowana jest wartość tagu identyfikatora aplikacji klucza Keystore, czyli szyfrogram SHA-512 o długości 16 384 losowych bajtach zapisany w pliku secdiscardable
. Aby odzyskać klucz FBE, trzeba odzyskać wszystkie te bajty.
Klucze CE dla pamięci wewnętrznej są chronione na wyższym poziomie, co oznacza, że nie można ich odblokować bez znajomości czynnika wiedzy blokady ekranu (LSKF) użytkownika (kodu PIN, wzoru lub hasła), zabezpieczonego tokenu resetowania kodu dostępu lub kluczy po stronie klienta i serwera w ramach operacji Resume-on-Reboot. Tokeny resetowania hasła można tworzyć tylko w przypadku profili służbowych i w pełni zarządzanych urządzeń.
W tym celu vold
szyfruje każdy klucz CE do pamięci wewnętrznej za pomocą klucza AES-256-GCM wygenerowanego na podstawie hasła syntetycznego użytkownika.
Hasło syntetyczne to niezmienne, szyfrowane hasło o wysokiej entropii, które jest generowane losowo dla każdego użytkownika. 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 zużycie pamięci około 2 MiB. Ponieważ klucze LSKF są zwykle krótkie, ten krok zwykle nie zapewnia większego bezpieczeństwa. Główna warstwa zabezpieczeń to Secure Element (SE) lub ograniczanie szybkości na poziomie TEE, jak opisano poniżej.
Jeśli urządzenie ma element zabezpieczeń (SE), LockSettingsService
przekształca rozciągnięty klucz LSKF w losowy sekret o wysokiej entropii przechowywany w SE za pomocą interfejsu Weaver HAL. 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. Umożliwia to ograniczenie liczby prób LSKF narzucone przez SE.
Jeśli na urządzeniu nie ma SE, LockSettingsService
używa rozciągniętego LSKF jako hasła Gatekeeper. LockSettingsService
następnie szyfruje syntetyczne hasło dwukrotnie: 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ą rejestracji w usłudze Gatekeeper. Umożliwia to ograniczenie szybkości prób LSKF narzucone przez TEE.
Gdy zmienisz klucz LSKF, LockSettingsService
usunie wszystkie informacje związane z powiązaniem 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 zabezpieczenia opisane w tym artykule są stosowane nawet wtedy, gdy użytkownik nie ma LSKF.