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 odblokowywać niezależnie od siebie.

W tym artykule opisujemy, 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 mogły działać, 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 to nastąpić, zanim użytkownicy podadzą swoje dane logowania, przy jednoczesnej ochronie prywatnych informacji o użytkownikach.

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

  • Pamięć zaszyfrowana za pomocą danych logowania (CE), która jest domyślną lokalizacją przechowywania danych 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ęć chroniona za pomocą klucza CE użytkownika zostanie odblokowana w odpowiedzi na pierwsze podanie danych logowania na ekranie blokady lub w przypadku profilu służbowego, gdy użytkownik odpowie na wyzwanie służbowe. 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 wystarczy ją włączyć na urządzeniach spełniających wymagania. Producenci, którzy zdecydują się na korzystanie z FBE, mogą optymalizować tę funkcję 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 co najmniej pakiety obsługujące bezpośrednie uruchamianie zapewniają 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 możliwościami szyfrowania w jądrze systemu opartymi 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. Są to między innymi:

  • Aplikacja Telefon AOSP (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 1.0 lub nowszy) 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ć 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ętowe źródło zaufaniaweryfikacja podczas uruchamiania powiązane z inicjowaniem KeyMint są wymagane, aby zapewnić, że klucze DE nie są 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 deweloperów dotyczącą bezpośredniego uruchamiania.

Obsługa jądra

Obsługa szyfrowania Ext4 i F2FS w jądrach wspólnych Androida jest dostępna w wersji 3.18 i nowszych. 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ż rozważyć wdrożenie sprzętowego szyfrowania wbudowanego, które 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, jeśli 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 opartej na 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 opartego na plikach na urządzeniu wymaga włączenia go w pamięci wewnętrznej (userdata). Spowoduje to również automatyczne włączenie szyfrowania opartego na plikach w pamięci dostosowywanej. W razie potrzeby format szyfrowania w pamięci dostosowywanej 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, 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 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 (co jest określane przez 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 go 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 znaku 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 obsługujących klucze szyfrowania w formacie inline z szyfrowaniem sprzętowym klucze FBE można zabezpieczyć szyfrowaniem sprzętowym, dodając flagę wrappedkey lub wrappedkey_v0. wrappedkey to nowoczesna wersja; wrappedkey_v0 należy używać tylko na urządzeniach, które nie obsługują wrappedkey lub zostały już uruchomione z wrappedkey_v0. Więcej informacji znajdziesz w artykule Włączanie kluczy opakowanych.
    • 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 w przypadku urządzeń z instrukcjami przyspieszonej kryptografii. 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ż kod 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ć jednocześnie FBE i pamięci dostosowywanej.

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 dostosowywanej, ustawiając właściwości w pliku PRODUCT_PROPERTY_OVERRIDES.

Na urządzeniach wprowadzonych 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 dostosowywanej. 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 dostosowywanej. Zapoznaj się z dokumentacją dotyczącą szyfrowania metadanych.

Na urządzeniach wprowadzonych 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 oddzielonego dwukropkiem w ro.crypto.volume.options.
  • ro.crypto.volume.filenames_mode wybiera tryb szyfrowania nazw plików. Jest to odpowiednik drugiego pola oddzielonego dwukropkiem w ro.crypto.volume.options, z tym wyjątkiem, że domyślna wartość na urządzeniach z Androidem 10 lub starszym to aes-256-heh. Na większości urządzeń trzeba to wyraźnie zastąpić wartością aes-256-cts.
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size wybierz format szyfrowania metadanych na pamięci dostosowywanej. 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 uruchamiania, 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 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 parametru <action> są opisane w pliku README dotyczącym języka inicjowania Androida.

W Androidzie 10 działania związane z szyfrowaniem init 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 uruchamiania

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 aplikacji obsługują szyfrowanie.

Atrybut defaultToDeviceProtectedStorage przekierowuje domyślną lokalizację zapisu aplikacji na DE zamiast na 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 wielu użytkowników 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 kontach wszystkich użytkowników urządzenia. Aplikacje te mogą jednak uzyskiwać dostęp tylko do katalogów zaszyfrowanych za pomocą szyfrowania 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 sprawdzać 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 procesy lub aplikacje otrzymujące aktualizacje OTA powinny mieć możliwość odczytywania i zapisywania danych w tym katalogu. Żadna inna aplikacja ani proces nie powinny mieć dostępu do tego katalogu.

Weryfikacja

Aby mieć pewność, że wdrożona wersja funkcji działa zgodnie z oczekiwaniami, najpierw uruchom 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 interfejsu graficznego (większość urządzeń Automotive), 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, co oznacza, że 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ą zestawu testów systemu plików xfstests. Te testy nie są jednak oficjalnie obsługiwane przez Androida.

Szczegóły implementacji AOSP

W tej sekcji znajdziesz szczegółowe informacje o implementacji AOSP i działaniu szyfrowania opartego 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 pełni 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/${user_id} używa klucza na użytkownika, /data/usersam 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 są 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 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}
User CE (adoptable) Dane zaszyfrowane za pomocą danych logowania poszczególnych użytkowników na 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}
User DE (adoptable) Dane zaszyfrowane na urządzeniu dla każdego użytkownika na pamięci dostosowywanej
  • /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 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 masowej 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 za pomocą algorytmu 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. Odporność na przywracanie jest też wymagana w przypadku klucza Keystore, co 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 rezerwowa metoda o najwyższej skuteczności używany 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), tokena bezpiecznego resetowania kodu dostępu 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żbowychurządzeń w pełni zarządzanych.

W tym celu voldszyfruje każdy klucz CE do pamięci wewnętrznej 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 wykorzystania pamięci.LockSettingsService Ponieważ klucze LSKF są zwykle krótkie, ten krok nie zapewnia zwykle dużego bezpieczeństwa. Główną warstwą zabezpieczeń jest Secure Element (SE) lub ograniczenie szybkości wymuszone przez TEE opisane poniżej.

Jeśli urządzenie implementuje Weaver HAL, to LockSettingsService mapuje rozciągnięty klucz LSKF na losowy klucz tajny o wysokiej entropii przechowywany w SE lub TEE za pomocą Weavera. 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 magazynu kluczy niezwiązanego z uwierzytelnianiem. Zapewnia to ograniczenie liczby prób odgadnięcia LSKF wymuszane przez SE lub TEE.

Jeśli urządzenie nie implementuje Weavera, zamiast tego LockSettingsService używa rozciągniętego klucza LSKF jako hasła Gatekeeper. LockSettingsService następnie szyfruje hasło syntetyczne 2 razy: najpierw za pomocą klucza programowego pochodzącego z rozszerzonego klucza LSKF i wartości skrótu pliku secdiscardable, 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 środowisko 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 klucza LSKF.