Szyfrowanie oparte na plikach

Android 7.0 i nowsze obsługują szyfrowanie oparte na plikach (FBE). Szyfrowanie oparte na plikach umożliwia szyfrowanie różnych plików przy użyciu różnych kluczy, które można odblokować niezależnie.

W tym artykule opisano, jak włączyć szyfrowanie oparte na plikach na nowych urządzeniach oraz w jaki sposób aplikacje systemowe mogą korzystać z interfejsów API bezpośredniego rozruchu, aby zapewnić użytkownikom najlepszą i najbezpieczniejszą możliwą obsługę.

Wszystkie urządzenia z systemem Android 10 i nowszym muszą korzystać z szyfrowania plików.

Rozruch bezpośredni

Szyfrowanie oparte na plikach umożliwia nową funkcję wprowadzoną w systemie Android 7.0 o nazwie Direct Boot . Direct Boot umożliwia zaszyfrowanym urządzeniom uruchamianie 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 uwierzytelniające, zanim można było uzyskać dostęp do jakichkolwiek danych, uniemożliwiając telefonowi wykonywanie wszystkich 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ń, ale ograniczały się jedynie do podstawowych operacji wybierania numerów alarmowych.

Wraz z wprowadzeniem szyfrowania opartego na plikach (FBE) i nowych interfejsów API informujących aplikacje o szyfrowaniu, możliwe jest, że aplikacje te będą działać w ograniczonym kontekście. Może się to zdarzyć, zanim użytkownicy podają swoje dane uwierzytelniające, jednocześnie chroniąc prywatne informacje o użytkownikach.

Na urządzeniu obsługującym FBE każdy użytkownik urządzenia ma do dyspozycji dwie lokalizacje przechowywania aplikacji:

  • Pamięć szyfrowana poświadczeniami (CE), która jest domyślną lokalizacją przechowywania i jest dostępna dopiero po odblokowaniu urządzenia przez użytkownika.
  • Urządzenie szyfrowane (DE), czyli miejsce przechowywania dostępne zarówno w trybie bezpośredniego rozruchu, jak i po odblokowaniu urządzenia przez użytkownika.

To oddzielenie sprawia, że ​​profile do pracy są bezpieczniejsze, ponieważ umożliwia ochronę więcej niż jednego użytkownika jednocześnie, ponieważ szyfrowanie nie opiera się już wyłącznie na haśle podczas uruchamiania.

Interfejs API Direct Boot umożliwia aplikacjom obsługującym szyfrowanie dostęp do każdego z tych obszarów. Wprowadzono zmiany w cyklu życia aplikacji, aby uwzględnić potrzebę powiadamiania aplikacji, gdy pamięć CE użytkownika zostanie odblokowana w odpowiedzi na pierwsze wprowadzenie danych uwierzytelniających na ekranie blokady lub w przypadku profilu służbowego zapewniającego wyzwanie służbowe . Urządzenia z systemem Android 7.0 muszą obsługiwać te nowe interfejsy API i cykle życia niezależnie od tego, czy implementują FBE, czy nie. Chociaż bez FBE, pamięć DE i CE będzie zawsze w stanie odblokowanym.

Pełna implementacja szyfrowania opartego na plikach w systemach plików Ext4 i F2FS jest dostępna w projekcie Android Open Source Project (AOSP) i należy ją włączyć tylko na urządzeniach spełniających wymagania. Producenci decydujący się na użycie FBE mogą chcieć zbadać sposoby optymalizacji tej funkcji w oparciu o używany system na chipie (SoC).

Wszystkie niezbędne pakiety w AOSP zostały zaktualizowane, aby obsługiwały rozruch bezpośredni. Jeśli jednak producenci urządzeń korzystają z niestandardowych wersji tych aplikacji, będą chcieli mieć pewność, że dostępne będą co najmniej pakiety obsługujące rozruch bezpośredni, zapewniające następujące usługi:

  • Usługi telefoniczne i dialer
  • Metoda wprowadzania haseł na ekranie blokady

Przykłady i źródło

Android zapewnia referencyjną implementację szyfrowania opartego na plikach, w której vold ( system/vold ) zapewnia funkcjonalność zarządzania urządzeniami pamięci masowej i woluminami w systemie Android. Dodanie FBE zapewnia voldowi kilka nowych poleceń wspierających zarządzanie kluczami CE i DE wielu użytkowników. Oprócz podstawowych zmian polegających na wykorzystaniu możliwości szyfrowania plików w jądrze , wiele pakietów systemowych, w tym ekran blokady i SystemUI, zostało zmodyfikowanych w celu obsługi funkcji FBE i Direct Boot. Obejmują one:

  • Dialer AOSP (pakiety/aplikacje/Dialer)
  • Zegar na biurko (pakiety/aplikacje/DeskClock)
  • LatinIME (pakiety/metody wprowadzania/LatinIME)*
  • Ustawienia aplikacji (pakiety/aplikacje/Ustawienia)*
  • SystemUI (frameworki/baza/pakiety/SystemUI)*

* Aplikacje systemowe korzystające z 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 drzewa źródłowego AOSP.

Zależności

Aby bezpiecznie korzystać z implementacji AOSP FBE, urządzenie musi spełniać następujące zależności:

  • Obsługa jądra dla szyfrowania Ext4 lub szyfrowania F2FS.
  • Obsługa Keymastera z HAL w wersji 1.0 lub nowszej. Nie ma wsparcia dla Keymaster 0.3, ponieważ nie zapewnia on niezbędnych możliwości i nie zapewnia wystarczającej ochrony kluczy szyfrujących.
  • 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 wgrany na urządzenie) nie mógł po prostu zażądać kluczy DE.
  • Sprzętowy katalog zaufania i zweryfikowany rozruch powiązane z inicjalizacją Keymastera są wymagane, aby zapewnić, że klucze DE nie będą dostępne dla nieautoryzowanego systemu operacyjnego.

Realizacja

Przede wszystkim aplikacje takie jak budziki, telefon i funkcje ułatwień dostępu powinny mieć wersję Android:directBootAware zgodnie z dokumentacją programisty Direct Boot .

Wsparcie jądra

Obsługa jądra dla szyfrowania Ext4 i F2FS jest dostępna w popularnych jądrach Androida w wersji 3.18 i nowszych. Aby włączyć tę funkcję w jądrze w wersji 5.1 lub wyższej, użyj:

CONFIG_FS_ENCRYPTION=y

W przypadku starszych jąder użyj CONFIG_EXT4_ENCRYPTION=y , jeśli system plików userdata twojego urządzenia to Ext4, lub użyj CONFIG_F2FS_FS_ENCRYPTION=y jeśli system plików userdata twojego urządzenia to F2FS.

Jeśli Twoje urządzenie będzie obsługiwać pamięć masową lub będzie korzystać z szyfrowania metadanych w pamięci wewnętrznej, włącz także opcje konfiguracji jądra potrzebne do szyfrowania metadanych, zgodnie z opisem w dokumentacji dotyczącej szyfrowania metadanych .

Oprócz funkcjonalnej obsługi szyfrowania Ext4 lub F2FS producenci urządzeń powinni także włączyć akcelerację kryptograficzną, aby przyspieszyć szyfrowanie plików i poprawić wygodę użytkownika. Na przykład na urządzeniach opartych na ARM64 można włączyć akcelerację ARMv8 CE (Cryptography Extensions), ustawiając następujące opcje konfiguracji jądra:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

Aby jeszcze bardziej poprawić wydajność i zmniejszyć zużycie energii, producenci urządzeń mogą również rozważyć wdrożenie wbudowanego sprzętu szyfrującego , który szyfruje/odszyfrowuje dane w drodze do/z urządzenia pamięci masowej. Wspólne jądra systemu Android (wersja 4.14 i nowsze) zawierają strukturę umożliwiającą użycie szyfrowania wbudowanego, gdy dostępna jest obsługa sprzętu i sterowników dostawcy. Wbudowaną strukturę szyfrowania można włączyć, ustawiając następujące opcje konfiguracji jądra:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Jeśli Twoje urządzenie korzysta z pamięci masowej opartej na UFS, włącz także:

CONFIG_SCSI_UFS_CRYPTO=y

Jeśli Twoje urządzenie korzysta z pamięci masowej opartej na eMMC, włącz także:

CONFIG_MMC_CRYPTO=y

Włączanie szyfrowania opartego na plikach

Włączenie FBE na urządzeniu wymaga włączenia go w pamięci wewnętrznej ( userdata ). To również automatycznie włącza FBE na nadającą się do adaptacji pamięć masową; jednakże w razie potrzeby format szyfrowania dostępnej pamięci może zostać zastąpiony.

Pamięć wewnętrzna

FBE można włączyć, dodając opcję fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] do kolumny fs_mgr_flags w wierszu fstab dla userdata . Ta opcja określa format szyfrowania w pamięci wewnętrznej. Zawiera maksymalnie trzy parametry oddzielone dwukropkami:

  • Parametr contents_encryption_mode określa, jaki algorytm kryptograficzny jest używany do szyfrowania zawartości pliku. Może to być aes-256-xts lub adiantum . Od Androida 11 można również pozostawić puste, aby określić domyślny algorytm, którym jest 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 lub aes-256-hctr2 . Jeśli nie określono, domyślnie jest to aes-256-cts , jeśli contents_encryption_mode to aes-256-xts lub adiantum , jeśli contents_encryption_mode to adiantum .
  • Parametr flags , nowy w Androidzie 11, to lista flag oddzielonych znakiem + . Obsługiwane są następujące flagi:
    • Flaga v1 wybiera zasady szyfrowania w wersji 1; flaga v2 wybiera zasady szyfrowania w wersji 2. Zasady szyfrowania w wersji 2 wykorzystują bezpieczniejszą i elastyczną funkcję wyprowadzania klucza . Wartość domyślna to v2, jeśli urządzenie działa na systemie Android 11 lub nowszym (jak określono w ro.product.first_api_level ) lub v1, jeśli urządzenie działa na systemie Android 10 lub niższym.
    • Flaga inlinecrypt_optimized wybiera format szyfrowania zoptymalizowany pod kątem sprzętu do szyfrowania inline, który nie obsługuje efektywnie dużej liczby kluczy. Robi to poprzez wyprowadzenie tylko jednego klucza szyfrowania zawartości pliku na klucz CE lub DE, a nie jednego na plik. Generowanie IV (wektorów inicjujących) jest odpowiednio dostosowywane.
    • Flaga emmc_optimized jest podobna do inlinecrypt_optimized , ale wybiera również metodę generowania IV, która ogranicza IV do 32 bitów. Tej flagi należy używać wyłącznie na sprzęcie do szyfrowania wbudowanego, który jest zgodny ze specyfikacją JEDEC eMMC v5.2 i dlatego obsługuje tylko 32-bitowe IV. Na innym sprzęcie do szyfrowania inline użyj zamiast tego inlinecrypt_optimized . Tej flagi nie należy nigdy używać w przypadku pamięci masowej opartej na UFS; specyfikacja UFS pozwala na użycie 64-bitowych IV.
    • Na urządzeniach obsługujących klucze opakowane sprzętowo flaga wrappedkey_v0 umożliwia użycie kluczy opakowanych sprzętowo dla FBE. Można tego używać tylko w połączeniu z opcją montowania inlinecrypt i flagą inlinecrypt_optimized lub emmc_optimized .
    • Flaga dusize_4k wymusza, aby rozmiar jednostki danych szyfrowania wynosił 4096 bajtów, nawet jeśli rozmiar bloku systemu plików nie wynosi 4096 bajtów. Rozmiar jednostki danych szyfrowania to stopień szczegółowości szyfrowania zawartości pliku. Ta flaga jest dostępna od Androida 15 (eksperymentalny AOSP). Tej flagi należy używać wyłącznie w celu umożliwienia korzystania ze sprzętu do szyfrowania wbudowanego, który nie obsługuje jednostek danych większych niż 4096 bajtów, na urządzeniu korzystającym ze strony o rozmiarze większym niż 4096 bajtów i korzystającym z systemu plików f2fs.

Jeśli nie używasz wbudowanego sprzętu do szyfrowania, zalecanym ustawieniem dla większości urządzeń jest fileencryption=aes-256-xts . Jeśli używasz sprzętu do szyfrowania inline, zalecanym ustawieniem dla większości urządzeń jest fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (lub równoważnie fileencryption=::inlinecrypt_optimized ). Na urządzeniach bez żadnej formy akceleracji AES zamiast AES można używać Adiantum , ustawiając fileencryption=adiantum .

Od wersji Androida 14 preferowanym trybem szyfrowania nazw plików dla urządzeń z instrukcjami przyspieszonej kryptografii jest AES-HCTR2. Jednak tylko nowsze jądra Androida obsługują AES-HCTR2. W przyszłej wersji Androida planuje się, że stanie się to domyślnym trybem szyfrowania nazw plików. Jeśli twoje jądro obsługuje AES-HCTR2, można włączyć szyfrowanie nazw plików, ustawiając filenames_encryption_mode na aes-256-hctr2 . W najprostszym przypadku można to zrobić za pomocą fileencryption=aes-256-xts:aes-256-hctr2 .

Na urządzeniach z systemem Android 10 lub starszym akceptowana jest także fileencryption=ice określająca użycie trybu szyfrowania zawartości pliku FSCRYPT_MODE_PRIVATE . Ten tryb nie jest zaimplementowany w popularnych jądrach Androida, ale dostawcy mogą go zaimplementować, korzystając z niestandardowych poprawek jądra. Format na dysku utworzony w tym trybie był zależny od dostawcy. Na urządzeniach z systemem Android 11 lub nowszym ten tryb nie jest już dozwolony i zamiast tego należy użyć standardowego formatu szyfrowania.

Domyślnie szyfrowanie zawartości plików odbywa się przy użyciu interfejsu API kryptografii jądra Linuksa. Jeśli zamiast tego chcesz używać sprzętu do szyfrowania inline, dodaj także opcję montowania inlinecrypt . Na przykład pełna linia fstab może wyglądać następująco:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Możliwość dostosowania przechowywania

Od wersji Androida 9 można używać jednocześnie FBE i adaptowalnej pamięci masowej .

Określenie opcji fstab fileencryption plików dla userdata automatycznie włącza zarówno szyfrowanie FBE, jak i metadanych w dostępnej pamięci masowej. Można jednak zastąpić formaty szyfrowania FBE i/lub metadanych w dostępnej pamięci masowej, ustawiając właściwości w PRODUCT_PROPERTY_OVERRIDES .

Na urządzeniach z systemem Android 11 lub nowszym użyj następujących właściwości:

  • ro.crypto.volume.options (nowość w Androidzie 11) wybiera format szyfrowania FBE w dostępnej pamięci. Ma tę samą składnię, co argument opcji fstab fileencryption i używa tych samych ustawień domyślnych. Zobacz zalecenia dotyczące fileencryption powyżej, aby dowiedzieć się, czego tutaj użyć.
  • ro.crypto.volume.metadata.encryption wybiera format szyfrowania metadanych w dostępnej pamięci masowej. Zobacz dokumentację dotyczącą szyfrowania metadanych .

Na urządzeniach z systemem Android 10 lub starszym użyj następujących właściwości:

  • ro.crypto.volume.contents_mode wybiera tryb szyfrowania zawartości. Jest to odpowiednik pierwszego rozdzielonego dwukropkiem pola ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode wybiera tryb szyfrowania nazw plików. Jest to odpowiednik drugiego pola oddzielonego ro.crypto.volume.options , z tą różnicą, że wartością domyślną na urządzeniach z systemem Android 10 lub starszym jest aes-256-heh . Na większości urządzeń należy to wyraźnie zastąpić aes-256-cts .
  • ro.crypto.fde_algorithm i ro.crypto.fde_sector_size wybierają format szyfrowania metadanych w dostępnej pamięci masowej. Zobacz dokumentację dotyczącą szyfrowania metadanych .

Integracja z Keymasterem

Keymaster HAL powinien zostać uruchomiony jako część klasy early_hal . Dzieje się tak dlatego, że FBE wymaga, aby Keymaster był gotowy do obsługi żądań w fazie rozruchu post-fs-data , czyli wtedy, gdy vold konfiguruje początkowe klucze.

Z wyłączeniem katalogów

init stosuje systemowy klucz DE do wszystkich katalogów najwyższego poziomu /data , z wyjątkiem katalogów, które muszą być niezaszyfrowane, takich jak katalog zawierający sam systemowy klucz DE i katalogi zawierające katalogi CE lub DE użytkownika. Klucze szyfrujące obowiązują rekurencyjnie i nie można ich zastąpić podkatalogami.

W systemie Android 11 i nowszych wersjach klucz, który init ma zastosowanie do katalogów, można kontrolować za pomocą argumentu encryption=<action> polecenia mkdir w skryptach init. Możliwe wartości <action> są udokumentowane w pliku README dla języka inicjującego Androida .

W systemie Android 10 init działania szyfrujące zostały zakodowane na stałe w następującej lokalizacji:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

W Androidzie 9 i wcześniejszych lokalizacja była następująca:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Możliwe jest dodanie wyjątków, aby w ogóle uniemożliwić szyfrowanie niektórych katalogów. W przypadku wprowadzenia tego typu modyfikacji producent urządzenia powinien uwzględnić zasady SELinux , które przyznają dostęp tylko aplikacjom, które muszą korzystać z niezaszyfrowanego katalogu. Powinno to wykluczyć wszystkie niezaufane aplikacje.

Jedynym znanym akceptowalnym przypadkiem użycia jest obsługa starszych funkcji OTA.

Obsługa bezpośredniego rozruchu w aplikacjach systemowych

Udostępnianie aplikacji funkcji Direct Boot

Aby ułatwić szybką migrację aplikacji systemowych, na poziomie aplikacji można ustawić dwa nowe atrybuty. 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 jest skrótem oznaczającym wszystkie komponenty aplikacji jako obsługujące szyfrowanie.

Atrybut defaultToDeviceProtectedStorage przekierowuje domyślną lokalizację przechowywania aplikacji tak, aby wskazywała magazyn DE zamiast wskazywać magazyn CE. Aplikacje systemowe korzystające z tej flagi muszą dokładnie sprawdzić wszystkie dane przechowywane w domyślnej lokalizacji i zmienić ścieżki wrażliwych danych, aby mogły korzystać z magazynu CE. Producenci urządzeń korzystający z tej opcji powinni dokładnie sprawdzić przechowywane dane, aby upewnić się, że nie zawierają one żadnych danych osobowych.

Podczas pracy w tym trybie dostępne są następujące interfejsy API systemu, umożliwiające w razie potrzeby jawne zarządzanie kontekstem wspieranym przez pamięć CE, co jest odpowiednikiem ich odpowiedników z funkcją 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 dwa klucze: klucz DE i klucz CE. Użytkownik 0 musi najpierw zalogować się do urządzenia, ponieważ jest to użytkownik specjalny. Dotyczy to zastosowań związanych z administracją urządzeniem .

Aplikacje obsługujące kryptografię współdziałają z użytkownikami w następujący sposób: INTERACT_ACROSS_USERS i INTERACT_ACROSS_USERS_FULL pozwalają aplikacji działać na wszystkich użytkownikach urządzenia. Jednak te aplikacje będą mogły uzyskać dostęp tylko do katalogów zaszyfrowanych CE dla użytkowników, którzy są już odblokowani.

Aplikacja może swobodnie współdziałać na obszarach DE, ale jeden odblokowany użytkownik nie oznacza, że ​​wszyscy użytkownicy na urządzeniu są odblokowani. Aplikacja powinna sprawdzić ten status przed próbą uzyskania dostępu do tych obszarów.

Każdy identyfikator użytkownika profilu służbowego otrzymuje również dwa klucze: DE i CE. Kiedy wyzwanie pracy zostanie spełnione, użytkownik profilu zostanie odblokowany, a Keymaster (w TEE) może udostępnić klucz TEE profilu.

Obsługa aktualizacji

Partycja odzyskiwania nie może uzyskać dostępu do chronionej przez DE pamięci na partycji danych użytkownika. Zdecydowanie zaleca się, aby urządzenia wdrażające FBE obsługiwały OTA przy użyciu aktualizacji systemu A/B . Ponieważ OTA można zastosować podczas normalnej pracy, nie ma potrzeby odzyskiwania, aby uzyskać dostęp do danych na zaszyfrowanym dysku.

W przypadku korzystania ze starszego rozwiązania OTA, które wymaga odzyskiwania w celu uzyskania dostępu do pliku OTA na partycji userdata :

  1. Utwórz katalog najwyższego poziomu (na przykład misc_ne ) na partycji userdata .
  2. Skonfiguruj ten katalog najwyższego poziomu tak, aby był niezaszyfrowany (zobacz Wykluczanie katalogów ).
  3. Utwórz katalog w katalogu najwyższego poziomu do przechowywania pakietów OTA.
  4. 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 powinna mieć dostępu do tego katalogu.

Walidacja

Aby upewnić się, że zaimplementowana wersja funkcji działa zgodnie z oczekiwaniami, najpierw uruchom wiele testów szyfrowania CTS, takich jak DirectBootHostTest i EncryptionTest .

Jeśli na urządzeniu działa Android 11 lub nowszy, uruchom również vts_kernel_encryption_test :

atest vts_kernel_encryption_test

Lub:

vts-tradefed run vts -m vts_kernel_encryption_test

Ponadto producenci urządzeń mogą przeprowadzać następujące testy ręczne. Na urządzeniu z włączoną funkcją FBE:

  • Sprawdź, czy istnieje ro.crypto.state
    • Upewnij się, że ro.crypto.state jest zaszyfrowany
  • Sprawdź, czy istnieje ro.crypto.type
    • Upewnij się, ro.crypto.type jest ustawione na file

Dodatkowo testerzy mogą sprawdzić, czy pamięć CE jest zablokowana, zanim urządzenie zostanie odblokowane po raz pierwszy od uruchomienia. Aby to zrobić, użyj userdebug lub kompilacji eng , ustaw PIN, wzór lub hasło dla głównego użytkownika i zrestartuj urządzenie. Przed odblokowaniem urządzenia uruchom następujące polecenie, aby sprawdzić pamięć CE głównego użytkownika. Jeśli urządzenie korzysta z trybu użytkownika systemu bezgłowego (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 (większość urządzeń innych niż samochodowe) głównym użytkownikiem jest użytkownik 0, więc uruchom:

adb root; adb shell ls /data/user/0

Sprawdź, czy wymienione nazwy plików są zakodowane w formacie Base64, co oznacza, że ​​nazwy plików są zaszyfrowane i 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.

Zachęcamy także producentów urządzeń do rozważenia przeprowadzenia testów fscrypt dla systemu Linux na swoich urządzeniach lub jądrach. Testy te są częścią zestawu testów systemu plików xfstests. Jednak te testy nadrzędne nie są oficjalnie obsługiwane przez system Android.

Szczegóły implementacji AOSP

Ta sekcja zawiera szczegółowe informacje na temat implementacji AOSP i opisuje sposób działania szyfrowania opartego na plikach. Producenci urządzeń nie powinni wprowadzać tutaj żadnych zmian, aby móc korzystać z FBE i Direct Boot na swoich urządzeniach.

szyfrowanie fscrypt

Implementacja AOSP wykorzystuje szyfrowanie „fscrypt” (obsługiwane przez ext4 i f2fs) w jądrze i zwykle jest skonfigurowana tak, aby:

  • Szyfruj zawartość pliku za pomocą AES-256 w trybie XTS
  • Szyfruj nazwy plików za pomocą AES-256 w trybie CBC-CTS

Obsługiwane jest również szyfrowanie Adiantum . Gdy włączone jest szyfrowanie Adiantum, zarówno zawartość plików, jak i nazwy plików są szyfrowane za pomocą Adiantum.

fscrypt obsługuje dwie wersje zasad szyfrowania: wersję 1 i wersję 2. Wersja 1 jest przestarzała, a wymagania CDD dla urządzeń uruchamianych z systemem Android 11 i nowszym są kompatybilne tylko z wersją 2. Zasady szyfrowania w wersji 2 wykorzystują HKDF-SHA512 do uzyskania rzeczywistych klucze szyfrujące z kluczy dostarczonych przez przestrzeń użytkownika.

Więcej informacji na temat fscrypt można znaleźć w dokumentacji jądra .

Klasy przechowywania

Poniższa tabela zawiera bardziej szczegółową listę kluczy FBE i katalogów, które chronią:

Klasa przechowywania Opis Katalogi
Nieszyfrowane Katalogi w /data , które nie mogą lub nie muszą być chronione przez FBE. Na urządzeniach korzystających z szyfrowania metadanych katalogi te nie są tak naprawdę niezaszyfrowane, ale raczej są chronione kluczem szyfrowania metadanych, który jest odpowiednikiem Systemu DE.
  • /data/apex , z wyłączeniem /data/apex/decompressed i /data/apex/ota_reserved , które są systemowe DE
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Wszystkie katalogi, których podkatalogi używają różnych kluczy FBE. Na przykład, ponieważ każdy katalog /data/user/${user_id} używa klucza przypisanego do użytkownika, /data/user sam nie używa żadnego klucza.
System DE Dane zaszyfrowane na urządzeniu, niepowiązane z konkretnym użytkownikiem
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Wszystkie inne podkatalogi /data , o których ta tabela nie wspomina jako posiadające inną klasę
Na rozruch Tymczasowe pliki systemowe, które nie muszą przetrwać ponownego uruchomienia /data/per_boot
Użytkownik CE (wewnętrzny) Dane zaszyfrowane poświadczeniami poszczególnych użytkowników w pamięci wewnętrznej
  • /data/data (alias /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
Użytkownik DE (wewnętrzny) Dane szyfrowane na urządzeniu użytkownika w pamięci wewnętrznej
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Użytkownik CE (do przyjęcia) Dane zaszyfrowane poświadczeniami poszczególnych użytkowników w dostępnej pamięci masowej
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
Użytkownik DE (do przyjęcia) Dane zaszyfrowane na urządzeniu każdego użytkownika w dostępnej pamięci
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Przechowywanie i ochrona kluczy

Wszystkie klucze FBE są zarządzane przez vold i są przechowywane w postaci zaszyfrowanej na dysku, z wyjątkiem klucza rozruchowego, który w ogóle nie jest przechowywany. W poniższej tabeli wymieniono lokalizacje, w których przechowywane są różne klucze FBE:

Typ klucza Kluczowa lokalizacja Klasa przechowywania kluczowej lokalizacji
Klucz systemowy DE /data/unencrypted Nieszyfrowane
Klucze CE użytkownika (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 CE użytkownika (dostosowane). /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Użytkownik CE (wewnętrzny)
Klucze użytkownika DE (dostosowane). /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Użytkownik DE (wewnętrzny)

Jak pokazano w powyższej tabeli, większość kluczy FBE jest przechowywana w katalogach zaszyfrowanych innym kluczem FBE. Kluczy nie można odblokować, dopóki nie zostanie odblokowana 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ą AES-256-GCM przy użyciu własnego klucza magazynu kluczy, który nie jest ujawniany poza TEE. Zapewnia to, że kluczy FBE nie można odblokować, dopóki nie zostanie uruchomiony zaufany system operacyjny, zgodnie z wymogami Verified Boot . W kluczu Keystore wymagana jest również odporność na wycofywanie , co pozwala na bezpieczne usuwanie kluczy FBE na urządzeniach, na których Keymaster obsługuje odporność na wycofywanie. Jako najlepsze rozwiązanie awaryjne, gdy nie jest dostępna odporność na wycofywanie zmian, skrót SHA-512 składający się z 16384 losowych bajtów przechowywanych w pliku secdiscardable przechowywanym obok klucza jest używany jako znacznik identyfikacyjny aplikacji klucza magazynu kluczy. Aby odzyskać klucz FBE, należy odzyskać wszystkie te bajty.

Klucze CE do pamięci wewnętrznej otrzymują silniejszy poziom ochrony, który gwarantuje, że nie można ich odblokować bez znajomości współczynnika wiedzy użytkownika na ekranie blokady (LSKF) (PIN, wzór lub hasło), bezpiecznego tokena resetowania hasła lub obu danych po stronie klienta i klucze po stronie serwera dla operacji wznowienia po ponownym uruchomieniu . Tokeny resetowania hasła można tworzyć tylko w przypadku profili do pracy i urządzeń w pełni zarządzanych .

Aby to osiągnąć, vold szyfruje każdy klucz CE do przechowywania wewnętrznego przy użyciu klucza AES-256-GCM pochodzącego z syntetycznego hasła użytkownika. Hasło syntetyczne to niezmienny sekret kryptograficzny o wysokiej entropii, generowany losowo dla każdego użytkownika. LockSettingsService w system_server zarządza hasłem syntetycznym i sposobami jego ochrony.

Aby chronić hasło syntetyczne za pomocą LSKF, LockSettingsService najpierw rozciąga LSKF, przepuszczając je przez scrypt , ustawiając czas na około 25 ms i użycie pamięci na poziomie około 2 MiB. Ponieważ LSKF są zwykle krótkie, ten krok zwykle nie zapewnia dużego bezpieczeństwa. Główną warstwą zabezpieczeń jest element Secure Element (SE) lub ograniczenie szybkości wymuszane przez TEE, opisane poniżej.

Jeśli urządzenie ma bezpieczny element (SE), LockSettingsService odwzorowuje rozciągnięty LSKF na losowy sekret o wysokiej entropii przechowywany w SE przy użyciu Weaver HAL . Następnie LockSettingsService dwukrotnie szyfruje hasło syntetyczne: najpierw kluczem programowym pochodzącym z rozciągniętego klucza LSKF i klucza tajnego Weaver, a następnie kluczem magazynu kluczy niepowiązanym z autoryzacją. Zapewnia to wymuszone przez SE ograniczanie szybkości domysłów LSKF.

Jeśli urządzenie nie ma SE, LockSettingsService zamiast tego używa rozciągniętego LSKF jako hasła strażnika . Następnie LockSettingsService dwukrotnie szyfruje hasło syntetyczne: najpierw kluczem programowym pochodzącym z rozciągniętego LSKF i skrótu pliku, który można usunąć, a następnie kluczem magazynu kluczy powiązanym z rejestracją Gatekeeper. Zapewnia to wymuszone przez TEE ograniczanie szybkości domysłów LSKF.

Po zmianie LSKF LockSettingsService usuwa wszystkie informacje związane z powiązaniem hasła syntetycznego ze starym LSKF. Na urządzeniach obsługujących klucze Weaver lub klucze Keystore odporne na wycofywanie gwarantuje to bezpieczne usunięcie starego powiązania. Z tego powodu opisane tutaj zabezpieczenia mają zastosowanie nawet wtedy, gdy użytkownik nie posiada LSKF.