Android 7.0 i nowsze wersje obsługują szyfrowanie oparte na plikach (FBE). FBE umożliwia szyfrowanie różnych plików za pomocą różnych kluczy, które można odblokowywać niezależnie od siebie. Te klucze służą do szyfrowania zarówno zawartości, jak i nazw plików. W przypadku korzystania z FBE inne informacje, takie jak układy katalogów, rozmiary plików, uprawnienia oraz czasy utworzenia i modyfikacji, nie są szyfrowane. Te inne informacje są łącznie nazywane metadanymi systemu plików.
Android 9 wprowadził obsługę szyfrowania metadanych. W przypadku szyfrowania metadanych pojedynczy klucz dostępny w momencie uruchamiania szyfruje wszystkie treści, które nie są szyfrowane przez FBE. Ten klucz jest chroniony przez KeyMint (wcześniej Keymaster), który z kolei jest chroniony przez weryfikację rozruchu.
Szyfrowanie metadanych jest zawsze włączone w przypadku pamięci przenośnej, gdy włączone jest szyfrowanie na poziomie plików. Szyfrowanie metadanych można też włączyć w przypadku pamięci wewnętrznej. Urządzenia z Androidem 11 lub nowszym muszą mieć włączone szyfrowanie metadanych w pamięci wewnętrznej.
Implementacja w pamięci wewnętrznej
Szyfrowanie metadanych na pamięci wewnętrznej nowych urządzeń możesz skonfigurować, ustawiając metadata
system plików, zmieniając sekwencję inicjowania i włączając szyfrowanie metadanych w pliku fstab urządzenia.
Wymagania wstępne
Szyfrowanie metadanych można skonfigurować tylko podczas pierwszego formatowania partycji danych. W związku z tym ta funkcja jest dostępna tylko na nowych urządzeniach. Nie powinna być zmieniana w ramach aktualizacji OTA.
Szyfrowanie metadanych wymaga włączenia modułu dm-default-key
w jądrze. W Androidzie 11 i nowszych wersjachdm-default-key
jest obsługiwany przez wspólne jądra Androida w wersji 4.14 i nowszych. Ta wersja dm-default-key
korzysta z niezależnej od sprzętu i dostawcy platformy szyfrowania o nazwie blk-crypto.
Aby włączyć dm-default-key
, użyj tego polecenia:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
korzysta z wbudowanego sprzętu do szyfrowania (sprzętu, który szyfruje i odszyfrowuje dane podczas przesyłania do i z urządzenia pamięci masowej), gdy jest on dostępny. Jeśli nie używasz sprzętu do szyfrowania wbudowanego, musisz też włączyć powrót do interfejsu API kryptografii jądra:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Jeśli nie używasz sprzętu do szyfrowania wbudowanego, włącz też wszelkie dostępne przyspieszenie oparte na procesorze zgodnie z zaleceniami w dokumentacji FBE.
W Androidzie 10 i starszych wersjach dm-default-key
nie było obsługiwane przez wspólne jądro Androida. Dlatego to dostawcy musieli wdrożyć dm-default-key
.
Konfigurowanie systemu plików metadanych
Ponieważ niczego w partycji userdata nie można odczytać, dopóki nie będzie dostępny klucz szyfrowania metadanych, w tabeli partycji musi być wydzielona osobna partycja o nazwie metadata partition (partycja metadanych) do przechowywania obiektów blob KeyMint, które chronią ten klucz. Partycja metadanych powinna mieć rozmiar 16 MB.
fstab.hardware
musi zawierać wpis dotyczący systemu plików metadanych
znajdującego się na tej partycji, który montuje go w /metadata
, w tym
flagę formattable
, aby zapewnić jego sformatowanie podczas uruchamiania. System plików f2fs nie działa na mniejszych partycjach. Zalecamy używanie systemu ext4. Na przykład:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Aby upewnić się, że punkt podłączania /metadata
istnieje, dodaj ten wiersz do BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Zmiany w sekwencji inicjowania
Jeśli używane jest szyfrowanie metadanych, vold
musi być uruchomiony przed zamontowaniem /data
. Aby mieć pewność, że zostanie on uruchomiony wystarczająco wcześnie, dodaj do pliku init.hardware.rc
ten fragment:
# We need vold early for metadata encryption on early-fs start vold
Przed próbą zamontowania /data
przez proces inicjowania usługa KeyMint musi być uruchomiona i gotowa do działania.
Plik init.hardware.rc
powinien już zawierać instrukcję mount_all
, która montuje samą instrukcję /data
w sekcji on
late-fs
. Przed tym wierszem dodaj dyrektywę wykonania usługi:wait_for_keymaster
on late-fs … # Wait for Keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
Włącz szyfrowanie metadanych
Na koniec dodaj keydirectory=/metadata/vold/metadata_encryption
do kolumny fs_mgr_flags w przypadku wpisu fstab
dla userdata
. Pełna linia fstab może wyglądać na przykład tak:
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
Domyślnie algorytmem szyfrowania metadanych w pamięci wewnętrznej jest AES-256-XTS. Możesz to zmienić, ustawiając opcję metadata_encryption
w kolumnie fs_mgr_flags:
- Na urządzeniach bez akceleracji AES można włączyć szyfrowanie Adiantum, ustawiając wartość
metadata_encryption=adiantum
. - Na urządzeniach, które obsługują klucze chronione sprzętowo, klucz szyfrowania metadanych można chronić sprzętowo, ustawiając
metadata_encryption=aes-256-xts:wrappedkey_v0
(lub równoważniemetadata_encryption=:wrappedkey_v0
, ponieważaes-256-xts
jest algorytmem domyślnym).
Interfejs jądra do dm-default-key
zmienił się w Androidzie 11, dlatego musisz też zadbać o to, aby w device.mk
ustawić prawidłową wartość PRODUCT_SHIPPING_API_LEVEL
. Jeśli na przykład urządzenie jest dostarczane z Androidem 11 (poziom API 30), element device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz też ustawić tę właściwość systemu, aby wymusić użycie nowego interfejsu APIdm-default-key
niezależnie od poziomu interfejsu Shipping API:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Weryfikacja
Aby sprawdzić, czy szyfrowanie metadanych jest włączone i działa prawidłowo, przeprowadź testy opisane poniżej. Zwróć też uwagę na częste problemy opisane poniżej.
Testy
Zacznij od uruchomienia tego polecenia, aby sprawdzić, czy szyfrowanie metadanych jest włączone w pamięci wewnętrznej:
adb root
adb shell dmctl table userdata
Dane wyjściowe powinny być podobne do tych:
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
Jeśli zastąpisz domyślne ustawienia szyfrowania, ustawiając opcję
metadata_encryption
w fstab
urządzenia, dane wyjściowe będą się nieco różnić od powyższych. Jeśli na przykład włączysz szyfrowanie Adiantum, trzecie pole będzie miało wartość xchacha12,aes-adiantum-plain64
zamiast aes-xts-plain64
.
Następnie uruchom vts_kernel_encryption_test, aby sprawdzić poprawność szyfrowania metadanych i FBE:
atest vts_kernel_encryption_test
lub:
vts-tradefed run vts -m vts_kernel_encryption_test
Typowe problemy
Podczas wywołania mount_all
, które montuje partycję zaszyfrowaną metadanymi/data
, init
wykonuje narzędzie vdc. Narzędzie vdc łączy się z vold
przez binder
, aby skonfigurować urządzenie z zaszyfrowanymi metadanymi i zamontować partycję. Podczas tego połączenia init
jest zablokowany, a próby odczytu lub ustawienia właściwości init
są blokowane do czasu zakończenia działania mount_all
.
Jeśli na tym etapie jakakolwiek część pracy vold
jest bezpośrednio lub pośrednio blokowana podczas odczytywania lub ustawiania właściwości, dochodzi do zakleszczenia. Ważne jest, aby vold
mogła dokończyć odczytywanie kluczy, interakcję z KeyMint i montowanie katalogu danych bez dalszej interakcji z init
.
Jeśli KeyMint nie jest w pełni uruchomiony, gdy działa mount_all
, nie odpowiada na vold
, dopóki nie odczyta określonych właściwości z init
, co powoduje opisany powyżej impas. Umieszczenie
exec_start wait_for_keymaster
nad odpowiednim
mount_all
wywołaniem zgodnie z ustawieniami zapewnia, że KeyMint działa w pełni
z wyprzedzeniem, co pozwala uniknąć tego zakleszczenia.
Konfiguracja pamięci dostosowywanej
Od Androida 9 forma szyfrowania metadanych jest zawsze włączona w przypadku pamięci adaptacyjnej, gdy włączone jest szyfrowanie oparte na plikach, nawet jeśli szyfrowanie metadanych nie jest włączone w przypadku pamięci wewnętrznej.
W AOSP istnieją 2 implementacje szyfrowania metadanych na pamięci przenośnej: starsza oparta na dm-crypt
i nowsza oparta na dm-default-key
. Aby mieć pewność, że na urządzeniu wybrano prawidłową implementację, sprawdź, czy w device.mk
ustawiono prawidłową wartość parametru PRODUCT_SHIPPING_API_LEVEL
. Jeśli na przykład urządzenie jest dostarczane z Androidem 11 (poziom API 30), plik device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz też ustawić te właściwości systemu, aby wymusić użycie nowej metody szyfrowania metadanych woluminu (i nowej domyślnej wersji zasad FBE) niezależnie od poziomu interfejsu API dostawy:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
Obecna metoda
Na urządzeniach z Androidem 11 lub nowszym szyfrowanie metadanych na pamięci przenośnej wykorzystuje dm-default-key
moduł jądra, tak samo jak w przypadku pamięci wewnętrznej. Wymagania wstępne dotyczące opcji konfiguracji jądra, które należy włączyć, znajdziesz powyżej. Pamiętaj, że sprzęt do szyfrowania wbudowanego, który działa w pamięci wewnętrznej urządzenia, może być niedostępny w przypadku pamięci adaptacyjnej, a tym samym może być wymagane CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
Domyślnie dm-default-key
metoda szyfrowania metadanych woluminu
używa algorytmu szyfrowania AES-256-XTS z 4096-bajtowymi sektorami kryptograficznymi. Algorytm można zastąpić, ustawiając właściwość systemową ro.crypto.volume.metadata.encryption
. Wartość tej właściwości ma taką samą składnię jak opisana powyżej opcja metadata_encryption
. Na przykład na urządzeniach, które nie mają akceleracji AES, szyfrowanie Adiantum można włączyć, ustawiając ro.crypto.volume.metadata.encryption=adiantum
.
Starsza metoda
Na urządzeniach z Androidem 10 i starszymi wersjami szyfrowanie metadanych na pamięci przenośnej odbywa się za pomocą dm-crypt
zamiast dm-default-key
:
CONFIG_DM_CRYPT=y
W przeciwieństwie do metody dm-default-key
metoda dm-crypt
powoduje dwukrotne zaszyfrowanie zawartości pliku: raz za pomocą klucza FBE, a raz za pomocą klucza szyfrowania metadanych. Podwójne szyfrowanie obniża wydajność i nie jest wymagane do osiągnięcia celów związanych z bezpieczeństwem szyfrowania metadanych, ponieważ Android zapewnia, że klucze FBE są co najmniej tak samo trudne do złamania jak klucz szyfrujący metadane. Producenci mogą dostosować jądro, aby uniknąć podwójnego szyfrowania, w szczególności przez wdrożenie opcji allow_encrypt_override
, którą Android przekazuje do dm-crypt
, gdy właściwość systemowa ro.crypto.allow_encrypt_override
ma wartość true
.
Te dostosowania nie są obsługiwane przez wspólne jądro Androida.
Domyślnie metoda szyfrowania metadanych woluminu dm-crypt
używa algorytmu szyfrowania AES-128-CBC z ESSIV i 512-bajtowymi sektorami kryptograficznymi. Można to zastąpić, ustawiając te właściwości systemu (które są też używane w przypadku pełnego szyfrowania dysku):
ro.crypto.fde_algorithm
wybiera algorytm szyfrowania metadanych. Możesz wybraćaes-128-cbc
lubadiantum
. Adiantum można używać tylko wtedy, gdy urządzenie nie ma akceleracji AES.ro.crypto.fde_sector_size
wybiera rozmiar sektora kryptowalut. Dostępne opcje to 512, 1024, 2048 i 4096. W przypadku szyfrowania Adiantum użyj wartości 4096.