Szyfrowanie oparte na plikach

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

Z tego artykułu dowiesz się, jak włączyć szyfrowanie oparte na plikach na nowych urządzeniach i jak aplikacje systemowe mogą korzystać z interfejsów Direct Boot API, aby zapewnić użytkownikom jak najlepsze i najbezpieczniejsze wrażenia.

Wszystkie urządzenia z Androidem 10 lub nowszym muszą korzystać z szyfrowania opartego na plikach.

Bezpośredni rozruch

Szyfrowanie oparte na plikach umożliwia korzystanie z nowej funkcji wprowadzonej w Androidzie 7.0 o nazwie bezpośrednie uruchamianie. Bezpośrednie uruchamianie umożliwia uruchamianie zaszyfrowanych urządzeń 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, zanim można było uzyskać dostęp do jakichkolwiek danych, co uniemożliwiało telefonowi wykonywanie wszystkich operacji z wyjątkiem najbardziej podstawowych. Na przykład alarmy nie działały, usługi ułatwień dostępu były niedostępne, a telefony nie mogły odbierać połączeń, tylko wykonywać podstawowe połączenia alarmowe.

Wprowadzenie szyfrowania opartego na plikach (FBE) i nowych interfejsów API, które informują aplikacje o szyfrowaniu, umożliwia im działanie w ograniczonym kontekście. Może się to zdarzyć, zanim użytkownicy podadzą swoje dane logowania, przy jednoczesnej ochronie prywatnych informacji o użytkownikach.

Na urządzeniu z szyfrowaniem opartym na plikach każdy użytkownik ma 2 lokalizacje pamięci dostępne dla aplikacji:

  • pamięć Credential Encrypted (CE), która jest domyślną lokalizacją przechowywania i jest dostępna tylko po odblokowaniu urządzenia przez użytkownika;
  • pamięć zaszyfrowana na urządzeniu (DE), która jest 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ż umożliwiają ochronę więcej niż jednego użytkownika naraz, a szyfrowanie nie jest już oparte wyłącznie na haśle używanym podczas uruchamiania.

Interfejs Direct Boot API umożliwia aplikacjom obsługującym szyfrowanie dostęp do każdego z tych obszarów. W cyklu życia aplikacji wprowadzono zmiany, aby uwzględnić potrzebę powiadamiania aplikacji, gdy pamięć CE użytkownika jest odblokowywana w odpowiedzi na pierwsze wprowadzenie danych logowania na ekranie blokady lub w przypadku profilu służbowego, gdy użytkownik przejdzie weryfikację służbową. 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 opartego na plikach w systemach plików Ext4 i F2FS jest dostępna w ramach Projektu Android Open Source (AOSP) i wymaga tylko włączenia na urządzeniach spełniających wymagania. Producenci, którzy zdecydują się na korzystanie z FBE, mogą szukać sposobów na optymalizację tej funkcji w zależności od używanego układu SOC.

Wszystkie niezbędne pakiety w AOSP zostały zaktualizowane, aby obsługiwać bezpośrednie uruchamianie. Jeśli jednak producenci urządzeń używają dostosowanych wersji tych aplikacji, chcą mieć pewność, że pakiety obsługujące bezpośrednie uruchamianie zapewniają co najmniej te usługi:

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

Przykłady i źródło

Android udostępnia referencyjną implementację szyfrowania opartego na plikach, w której vold (system/vold) zapewnia funkcje zarządzania urządzeniami pamięci masowej i woluminami na Androidzie. Dodanie FBE zapewnia usłudze vold kilka nowych poleceń, które obsługują zarządzanie kluczami CE i DE wielu użytkowników. Oprócz podstawowych zmian związanych z korzystaniem z możliwości szyfrowania w jądrze opartych na plikach zmodyfikowano wiele pakietów systemowych, w tym ekran blokady i interfejs systemowy, aby obsługiwały funkcje szyfrowania opartego na plikach i bezpośredniego rozruchu. Należą do nich:

  • Aplikacja Telefon (packages/apps/Dialer)
  • Zegar biurkowy (packages/apps/DeskClock)
  • LatinIME (packages/inputmethods/LatinIME)*
  • Aplikacja Ustawienia (packages/apps/Settings)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* Aplikacje systemowe, które używają defaultToDeviceProtectedStorageatrybutu manifestu

Więcej przykładów aplikacji i usług, które obsługują szyfrowanie, znajdziesz, uruchamiając polecenie mangrep directBootAware w katalogu frameworks lub packages w drzewie źródłowym AOSP.

Zależności

Aby bezpiecznie korzystać z implementacji FBE w AOSP, urządzenie musi spełniać te wymagania:

  • Obsługa jądra w przypadku szyfrowania Ext4 lub F2FS.
  • KeyMint (lub Keymaster w wersji 1.0 lub nowszej) Obsługa Nie obsługujemy Keymastera 0.3, ponieważ nie zapewnia on niezbędnych funkcji ani wystarczającej ochrony kluczy szyfrowania.
  • KeyMint/Keymaster i Gatekeeper muszą być wdrożone w zaufanym środowisku wykonawczym (TEE), aby chronić klucze DE. Dzięki temu nieautoryzowany system operacyjny (niestandardowy system operacyjny wgrany na urządzenie) nie może po prostu zażądać kluczy DE.
  • Sprzętowy korzeń zaufaniaweryfikacja podczas uruchamiania powiązane z inicjalizacją KeyMint są wymagane, aby klucze DE nie były dostępne dla nieautoryzowanego systemu operacyjnego.

Implementacja

Przede wszystkim aplikacje takie jak budziki, telefony i funkcje ułatwień dostępu powinny być zgodne z atrybutem android:directBootAware zgodnie z dokumentacją dla programistów dotyczącą bezpośredniego uruchamiania.

Obsługa jądra

Obsługa szyfrowania Ext4 i F2FS w jądrze jest dostępna w wersji 3.18 i nowszych wspólnych jąder Androida. Aby włączyć tę funkcję w jądrze w wersji 5.1 lub nowszej, użyj tego polecenia:

CONFIG_FS_ENCRYPTION=y

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

Jeśli urządzenie obsługuje pamięć adaptacyjną lub korzysta z szyfrowania metadanych w pamięci wewnętrznej, włącz też opcje konfiguracji jądra wymagane do szyfrowania metadanych zgodnie z opisem w dokumentacji szyfrowania metadanych.

Oprócz obsługi szyfrowania Ext4 lub F2FS producenci urządzeń powinni też włączyć akcelerację kryptograficzną, aby przyspieszyć szyfrowanie oparte na plikach i poprawić komfort użytkowania. Na przykład na urządzeniach z architekturą ARM64 akcelerację ARMv8 CE (Cryptography Extensions) można włączyć, 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 zmniejszyć zużycie energii, producenci urządzeń mogą też wdrożyć sprzęt do szyfrowania wbudowanego, który szyfruje i odszyfrowuje dane podczas przesyłania do i z urządzenia pamięci masowej. Wspólne jądra Androida (wersja 4.14 i nowsze) zawierają platformę, która umożliwia korzystanie z szyfrowania wbudowanego, gdy dostępne jest wsparcie sprzętowe i sterowniki dostawcy. Ramkę szyfrowania 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 szyfrowania FBE na urządzeniu wymaga włączenia go na pamięci wewnętrznej (userdata). Spowoduje to również automatyczne włączenie szyfrowania FBE na pamięci przenośnej. W razie potrzeby format szyfrowania na pamięci przenośnej można jednak zastąpić.

Pamięć wewnętrzna

FBE jest włączane przez dodanie opcji fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] do kolumny fs_mgr_flags w wierszu fstab dla userdata. Ta opcja określa format szyfrowania na wewnętrznej pamięci masowej. Zawiera maksymalnie 3 parametry oddzielone dwukropkami:

  • 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 lub adiantum. Od Androida 11 można też pozostawić to pole puste, aby określić algorytm domyślny, czyli aes-256-xts.
  • Parametr filenames_encryption_mode określa algorytm kryptograficzny 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 podasz tu żadnej wartości, zostanie użyta wartość domyślna aes-256-cts, jeśli contents_encryption_mode to aes-256-xts, lub adiantum, jeśli contents_encryption_mode to adiantum.
  • Parametr flags, który jest nowością w Androidzie 11, to lista flag rozdzielonych znakiem +. Obsługiwane są te flagi:
    • Flaga v1 wybiera zasady szyfrowania w wersji 1, a flaga v2 wybiera zasady szyfrowania w wersji 2. Wersja 2 zasady szyfrowania korzystają z bezpieczniejszej i bardziej elastycznej funkcji derywacji klucza. Domyślnie jest to v2, jeśli urządzenie zostało wprowadzone na rynek z Androidem 11 lub nowszym (określa to ro.product.first_api_level), lub v1, jeśli urządzenie zostało wprowadzone na rynek z Androidem 10 lub starszym.
    • Flaga inlinecrypt_optimized wybiera format szyfrowania zoptymalizowany pod kątem sprzętu do szyfrowania wbudowanego, który nie obsługuje wydajnie dużej liczby kluczy. W tym celu generuje tylko jeden klucz szyfrowania zawartości pliku na klucz CE lub DE, a nie jeden na plik. Generowanie wektorów inicjujących jest odpowiednio dostosowywane.
    • Flaga emmc_optimized jest podobna do inlinecrypt_optimized, ale wybiera też metodę generowania wektora inicjującego, która ogranicza wektory inicjujące do 32 bitów. Tej flagi należy używać tylko w przypadku sprzętu do szyfrowania wbudowanego, który jest zgodny ze specyfikacją JEDEC eMMC w wersji 5.2 i dlatego obsługuje tylko 32-bitowe wektory inicjujące. W przypadku innego sprzętu do szyfrowania wbudowanego użyj inlinecrypt_optimized. Tego flagi nie należy nigdy używać w przypadku pamięci opartej na UFS. Specyfikacja UFS dopuszcza używanie 64-bitowych wektorów inicjujących.
    • Na urządzeniach, które obsługują klucze opakowane sprzętowo, flaga wrappedkey_v0 umożliwia używanie kluczy opakowanych sprzętowo na potrzeby szyfrowania opartego na plikach. Można jej używać tylko w połączeniu z opcją montowania inlinecrypt i flagą inlinecrypt_optimized lub emmc_optimized.
    • Flaga dusize_4k wymusza rozmiar jednostki danych szyfrowania na 4096 bajtów, nawet jeśli rozmiar bloku systemu plików nie wynosi 4096 bajtów. Rozmiar jednostki danych szyfrowania to ziarnistość szyfrowania zawartości pliku. Ta flaga jest dostępna od Androida 15. Tej flagi należy używać tylko do włączania sprzętu do szyfrowania wbudowanego, który 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 systemu plików f2fs.

Jeśli nie używasz sprzętu do szyfrowania wbudowanego, zalecane ustawienie dla większości urządzeń to fileencryption=aes-256-xts. Jeśli używasz sprzętu do szyfrowania wbudowanego, 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 akceleracji AES zamiast AES można użyć Adiantum, ustawiając fileencryption=adiantum.

Od Androida 14 preferowanym trybem szyfrowania nazw plików jest AES-HCTR2 na urządzeniach z instrukcjami przyspieszonego szyfrowania. Jednak tylko nowsze jądra Androida obsługują AES-HCTR2. W przyszłej wersji Androida ma się stać domyślnym trybem szyfrowania nazw plików. Jeśli 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ą znaku fileencryption=aes-256-xts:aes-256-hctr2.

Na urządzeniach, które zostały wprowadzone na rynek z Androidem 10 lub starszym, akceptowany jest też znak fileencryption=ice, który określa użycie trybu szyfrowania zawartości pliku FSCRYPT_MODE_PRIVATE. Ten tryb nie jest zaimplementowany w wersjach jądra Androida, ale może być zaimplementowany przez dostawców za pomocą niestandardowych poprawek jądra. Format na dysku wygenerowany w tym trybie był specyficzny dla dostawcy. Na urządzeniach z Androidem 11 lub nowszym ten tryb nie jest już dozwolony i zamiast niego należy używać standardowego formatu szyfrowania.

Domyślnie szyfrowanie zawartości plików odbywa się za pomocą interfejsu API kryptografii jądra systemu Linux. Jeśli zamiast tego chcesz używać sprzętu do szyfrowania wbudowanego, dodaj też opcję montowania inlinecrypt. Na przykład pełna linia może wyglądać tak:fstab

/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ć FBE i pamięci przenośnej jednocześnie.

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

Na urządzeniach, które zostały wprowadzone na rynek z Androidem 11 lub nowszym, używaj tych właściwości:

  • ro.crypto.volume.options (nowość w Androidzie 11) wybiera format szyfrowania FBE na pamięci wewnętrznej. Ma taką samą składnię jak argument opcji fileencryption fstab i używa tych samych wartości domyślnych. W sekcji fileencryption powyżej znajdziesz rekomendacje dotyczące tego, co należy tu wpisać.
  • ro.crypto.volume.metadata.encryption wybiera format szyfrowania metadanych na pamięci wewnętrznej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.

Na urządzeniach, które zostały wprowadzone na rynek 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 pola rozdzielonego dwukropkiem w ro.crypto.volume.options.
  • ro.crypto.volume.filenames_mode wybiera tryb szyfrowania nazw plików. Jest to odpowiednik drugiego pola rozdzielonego dwukropkiem w ro.crypto.volume.options, z tym wyjątkiem, że domyślna wartość na urządzeniach z Androidem 10 i starszymi wersjami to aes-256-heh. Na większości urządzeń trzeba to wyraźnie zmienić na aes-256-cts.
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size wybierz format szyfrowania metadanych na pamięci wewnętrznej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.

Integracja z KeyMint

HAL KeyMint powinien być uruchamiany w ramach klasy early_hal. Dzieje się tak, ponieważ FBE wymaga, aby KeyMint był gotowy do obsługi żądań w post-fs-datafazie rozruchu, czyli wtedy, gdy vold konfiguruje początkowe klucze.

Wykluczanie katalogów

init stosuje systemowy klucz DE do wszystkich katalogów najwyższego poziomu na dysku /data, z wyjątkiem katalogów, które muszą być nieszyfrowane, takich jak katalog zawierający sam systemowy klucz DE oraz katalogi zawierające katalogi CE lub DE użytkownika. Klucze szyfrowania są stosowane rekursywnie i nie można ich zastąpić w podkatalogach.

W Androidzie 11 i nowszych klucz, któryinit ma zastosowanie do katalogów, można kontrolować za pomocą argumentuencryption=<action> polecenia mkdir w skryptach inicjujących. Możliwe wartości <action> są opisane w pliku README języka inicjowania Androida.

W Androidzie 10 init działania związane z szyfrowaniem były na stałe zakodowane w tym miejscu:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

Na Androidzie 9 i starszych lokalizacja była następująca:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Możesz dodać wyjątki, aby zapobiec szyfrowaniu 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. Powinno to wykluczyć wszystkie niezaufane aplikacje.

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

Obsługa bezpośredniego rozruchu w aplikacjach systemowych

Dostosowywanie aplikacji do bezpośredniego rozruchu

Aby ułatwić szybką migrację aplikacji systemowych, wprowadziliś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 jest skrótem oznaczającym, że wszystkie komponenty w aplikacji są przystosowane do szyfrowania.

Atrybut defaultToDeviceProtectedStorage przekierowuje domyślną lokalizację zapisu aplikacji na pamięć DE zamiast na pamięć CE. Aplikacje systemowe korzystające z tego flagi muszą dokładnie sprawdzić wszystkie dane przechowywane w domyślnej lokalizacji i zmienić ścieżki danych wrażliwych, aby korzystać z pamięci CE. Producenci urządzeń korzystający z tej opcji powinni dokładnie sprawdzać przechowywane dane, aby upewnić się, że nie zawierają one danych osobowych.

W tym trybie dostępne są te interfejsy API systemu, które umożliwiają w razie potrzeby bezpośrednie zarządzanie kontekstem obsługiwanym przez pamięć CE. Są one odpowiednikami interfejsów API chronionych na urządzeniu.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Obsługa wielu użytkowników

Każdy użytkownik w środowisku wielodostępnym 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. Jest to istotne w przypadku korzystania z administrowania urządzeniami.

Aplikacje obsługujące kryptowaluty wchodzą w interakcje z użytkownikami w ten sposób:INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL umożliwiają aplikacji działanie na wszystkich kontach użytkowników na urządzeniu. Te aplikacje mogą jednak uzyskiwać dostęp tylko do katalogów zaszyfrowanych za pomocą CE w przypadku użytkowników, którzy są już odblokowani.

Aplikacja może swobodnie wchodzić w interakcje w obszarach DE, ale odblokowanie jednego użytkownika 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 otrzymuje też 2 klucze: DE i CE. Gdy wyzwanie służbowe zostanie spełnione, profil użytkownika zostanie odblokowany, a KeyMint (w TEE) może udostępnić klucz TEE profilu.

Obsługa aktualizacji

Partycja odzyskiwania nie ma dostępu do pamięci chronionej przez DE na partycji userdata. Urządzenia z szyfrowaniem opartym na plikach powinny obsługiwać aktualizacje OTA za pomocą aktualizacji systemu A/B. Aktualizację 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:

  1. Utwórz katalog najwyższego poziomu (np. misc_ne) w partycji userdata.
  2. Skonfiguruj ten katalog najwyższego poziomu jako niezaszyfrowany (patrz Wykluczanie katalogów).
  3. Utwórz w katalogu najwyższego poziomu katalog 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 powinny mieć dostępu do tego katalogu.

Weryfikacja

Aby upewnić się, że wdrożona wersja funkcji działa zgodnie z oczekiwaniami, najpierw przeprowadź wiele testów szyfrowania CTS, takich jak DirectBootHostTestEncryptionTest.

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

Dodatkowo producenci urządzeń mogą przeprowadzać te testy ręczne. Na urządzeniu z włączonym szyfrowaniem na poziomie plików:

  • Sprawdź, czy ro.crypto.state istnieje.
    • Sprawdź, czy ro.crypto.state jest zaszyfrowany
  • Sprawdź, czy ro.crypto.type istnieje.
    • Sprawdź, czy nagłówek ro.crypto.type jest ustawiony na file.

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

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

Sprawdź, czy wymienione nazwy plików są zakodowane w formacie Base64. Oznacza to, że nazwy plików są zaszyfrowane, a klucz do ich odszyfrowania nie jest jeszcze dostępny. Jeśli nazwy plików są wymienione w formie zwykłego tekstu, coś jest nie tak.

Zachęcamy też producentów urządzeń do przeprowadzania na nich lub na ich jądrach testów fscrypt w wersji upstream dla Linuksa. Te testy są częścią pakietu testów systemu plików xfstests. Te testy nie są jednak oficjalnie obsługiwane przez Androida.

Szczegóły implementacji AOSP

Ta sekcja zawiera szczegółowe informacje o implementacji AOSP i opisuje, jak działa szyfrowanie oparte na plikach. Producenci urządzeń nie powinni wprowadzać tu żadnych zmian, aby korzystać na swoich urządzeniach z szyfrowania opartego na plikach i bezpośredniego rozruchu.

szyfrowanie fscrypt,

Implementacja AOSP korzysta z szyfrowania „fscrypt” (obsługiwanego przez systemy plików ext4 i f2fs) w jądrze i jest zwykle skonfigurowana w ten sposób:

  • 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ą tego algorytmu.

fscrypt obsługuje 2 wersje zasad szyfrowania: wersję 1 i wersję 2. Wersja 1 jest wycofana, a wymagania CDD dotyczące 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 fscrypt znajdziesz w dokumentacji jądra.

Klasy pamięci

W tabeli poniżej znajdziesz szczegółowe informacje o kluczach FBE i katalogach, które chronią:

Klasa pamięci Opis Katalogi
Niezaszyfrowane Katalogi w /data, które nie mogą być lub nie muszą być chronione przez FBE. Na urządzeniach, które korzystają z szyfrowania metadanych, te katalogi nie są w rzeczywistości nieszyfrowane, ale są chronione przez klucz szyfrowania metadanych, który jest odpowiednikiem klucza DE systemu.
  • /data/apex, z wyłączeniem /data/apex/decompressed i /data/apex/ota_reserved, które są systemowymi 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 /data/user/${user_id}katalog/data/user używa klucza na użytkownika, /data/user nie używa żadnego klucza.
System DE Dane zaszyfrowane na urządzeniu, które nie są powiązane z konkretnym użytkownikiem
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Wszystkie pozostałe podkatalogi /data, które nie zostały wymienione w tej tabeli jako mające inną klasę
Po uruchomieniu tymczasowe pliki systemowe, które nie muszą przetrwać ponownego uruchomienia; /data/per_boot
Użytkownik CE (wewnętrzny) Dane zaszyfrowane za pomocą danych logowania 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 zaszyfrowane na urządzeniu i przechowywane w pamięci wewnętrznej dla każdego użytkownika
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Urządzenie użytkownika (możliwe do przeniesienia) Dane zaszyfrowane za pomocą danych logowania poszczególnych użytkowników w pamięci dostosowywanej
  • /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 (możliwość przeniesienia) Dane zaszyfrowane na urządzeniu dla każdego użytkownika na pamięci przenośnej
  • /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 przechowywane na dysku w postaci zaszyfrowanej, z wyjątkiem klucza używanego podczas uruchamiania, który nie jest w ogóle przechowywany. W tabeli poniżej znajdziesz lokalizacje, w których są przechowywane różne klucze FBE:

Typ klucza Lokalizacja klucza Klasa pamięci lokalizacji klucza
Klucz DE systemu /data/unencrypted Niezaszyfrowane
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 użytkownika CE (możliwe do przeniesienia) /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Użytkownik CE (wewnętrzny)
Klucze DE użytkownika (możliwe do przeniesienia) /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Użytkownik DE (wewnętrzny)

Jak widać w tabeli powyżej, 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, w której się znajdują.

vold stosuje też warstwę szyfrowania do wszystkich kluczy FBE. Każdy klucz oprócz kluczy CE do pamięci wewnętrznej jest szyfrowany algorytmem AES-256-GCM przy użyciu własnego klucza Keystore, który nie jest udostępniany poza TEE. Dzięki temu klucze FBE nie mogą zostać odblokowane, dopóki nie zostanie uruchomiony zaufany system operacyjny, co jest wymuszane przez weryfikację podczas uruchamiania. W przypadku klucza Keystore wymagana jest też odporność na przywracanie, która umożliwia bezpieczne usuwanie kluczy FBE na urządzeniach, na których KeyMint obsługuje odporność na przywracanie. W przypadku braku odporności na wycofanie jako najlepsze rozwiązanie awaryjne stosowany jest skrót SHA-512 16384 losowych bajtów przechowywanych w pliku secdiscardable zapisanym obok klucza. Jest on używany jako Tag::APPLICATION_ID klucza Keystore. Aby odzyskać klucz FBE, musisz odzyskać wszystkie te bajty.

Klucze CE do pamięci wewnętrznej są lepiej chronione, co zapewnia, że nie można ich odblokować bez znajomości czynnika wiedzy dotyczącego blokady ekranu (LSKF) (kodu PIN, wzoru lub hasła), bezpiecznego tokena resetowania hasła lub kluczy po stronie klienta i serwera w przypadku operacji wznawiania po ponownym uruchomieniu. Tokeny resetowania kodu dostępu można tworzyć tylko w przypadku profili służbowychw pełni zarządzanych urządzeń.

W tym celu voldszyfruje każdy klucz CE na potrzeby wewnętrznego przechowywania przy użyciu klucza AES-256-GCM pochodzącego z syntetycznego hasła użytkownika. Hasło syntetyczne to niezmienny, kryptograficzny klucz tajny o wysokiej entropii, który jest generowany losowo dla każdego użytkownika. LockSettingsServicesystem_server zarządza hasłem syntetycznym i sposobami jego ochrony.

Aby chronić hasło syntetyczne za pomocą LSKF, najpierw rozciąga LSKF, przekazując go przez scrypt, co zajmuje około 25 ms i wykorzystuje około 2 MiB pamięci.LockSettingsService LSKF są zwykle krótkie, więc ten krok nie zapewnia dużego bezpieczeństwa. Główną warstwą zabezpieczeń jest Secure Element (SE) lub ograniczenie liczby żądań wymuszane przez TEE, opisane poniżej.

Jeśli urządzenie ma element Secure Element (SE), LockSettingsServicemapuje rozciągnięty klucz LSKF na losowy sekret o wysokiej entropii przechowywany w elemencie SE za pomocą Weaver HAL. LockSettingsService następnie szyfruje hasło syntetyczne 2 razy: najpierw za pomocą klucza programowego pochodzącego z rozszerzonego klucza LSKF i tajnego klucza Weaver, a potem za pomocą klucza Keystore niezwiązanego z uwierzytelnianiem. Zapewnia to ograniczenie liczby prób odgadnięcia klucza LSKF wymuszane przez SE.

Jeśli urządzenie nie ma SE, zamiast tego LockSettingsService używa rozciągniętego klucza LSKF jako hasła Gatekeeper. LockSettingsService następnie szyfruje syntetyczne hasło 2 razy: najpierw za pomocą klucza programowego pochodzącego z rozszerzonego klucza LSKF i skrótu pliku, który można usunąć, a potem za pomocą klucza magazynu kluczy powiązanego z rejestracją w usłudze Gatekeeper. Zapewnia to ograniczenie liczby prób odgadnięcia klucza LSKF wymuszane przez TEE.

Gdy LSKF zostanie zmieniony, LockSettingsService usuwa wszystkie informacje powiązane z powiązaniem syntetycznego hasła ze starym LSKF. Na urządzeniach, które obsługują klucze Weaver lub klucze Keystore odporne na przywracanie, gwarantuje to bezpieczne usunięcie starego powiązania. Dlatego opisane tutaj zabezpieczenia są stosowane nawet wtedy, gdy użytkownik nie ma LSKF.