Android 7.0 i nowszy obsługuje szyfrowanie oparte na plikach (FBE). FBE umożliwia szyfrowanie różnych plików za pomocą różnych kluczy, które można odblokować niezależnie. Te klucze są używane do szyfrowania zarówno zawartości plików, jak i nazw plików. Podczas korzystania z FBE inne informacje, takie jak układ katalogów, rozmiary plików, uprawnienia i czasy tworzenia/modyfikacji, nie są szyfrowane. Łącznie te inne informacje są znane jako metadane systemu plików.
Android 9 wprowadził obsługę szyfrowania metadanych. Dzięki szyfrowaniu metadanych pojedynczy klucz obecny w czasie rozruchu szyfruje zawartość, która nie jest szyfrowana przez FBE. Ten klucz jest chroniony przez Keymaster, który z kolei jest chroniony przez zweryfikowany rozruch.
Szyfrowanie metadanych jest zawsze włączone w dostępnej pamięci masowej , gdy włączona jest funkcja FBE. Szyfrowanie metadanych można również włączyć w pamięci wewnętrznej. Urządzenia uruchomione z systemem Android 11 lub nowszym muszą mieć włączone szyfrowanie metadanych w pamięci wewnętrznej.
Wdrożenie na pamięci wewnętrznej
Możesz skonfigurować szyfrowanie metadanych w pamięci wewnętrznej nowych urządzeń, konfigurując system plików metadata
, zmieniając kolejność init i włączając szyfrowanie metadanych w pliku fstab urządzenia.
Warunki wstępne
Szyfrowanie metadanych można skonfigurować tylko podczas pierwszego sformatowania partycji danych. W rezultacie ta funkcja jest dostępna tylko dla nowych urządzeń; to nie jest coś, co OTA powinna zmienić.
Szyfrowanie metadanych wymaga włączenia modułu dm-default-key
w jądrze. W systemie Android 11 i nowszych dm-default-key
jest obsługiwany przez wspólne jądra systemu Android w wersji 4.14 i nowszych. Ta wersja dm-default-key
korzysta z niezależnej od sprzętu i dostawcy struktury szyfrowania o nazwie blk-crypto .
Aby włączyć dm-default-key
, użyj:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
używa wbudowanego sprzętu szyfrującego (sprzętu, który szyfruje/odszyfrowuje dane w drodze do/z urządzenia pamięci masowej), jeśli jest dostępny. Jeśli nie będziesz używać wbudowanego sprzętu szyfrującego, konieczne jest również włączenie awaryjnego API kryptograficznego jądra:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Jeśli nie używasz wbudowanego sprzętu szyfrującego, powinieneś również włączyć wszelkie dostępne przyspieszenie oparte na procesorze, zgodnie z zaleceniami w dokumentacji FBE .
W systemie Android 10 i starszych, dm-default-key
nie był obsługiwany przez wspólne jądro systemu Android. Dlatego do dostawców należało zaimplementowanie dm-default-key
.
Skonfiguruj system plików metadanych
Ponieważ nic z partycji danych użytkownika nie może być odczytane, dopóki klucz szyfrowania metadanych nie jest obecny, tabela partycji musi odłożyć oddzielną partycję o nazwie „partycja metadanych” do przechowywania obiektów blob keymastera, które chronią ten klucz. Partycja metadanych powinna mieć rozmiar 16 MB.
fstab.hardware
musi zawierać wpis dotyczący systemu plików metadanych, który znajduje się na tej partycji, montując go w /metadata
, w tym flagę formattable
, aby zapewnić sformatowanie podczas uruchamiania. System plików f2fs nie działa na mniejszych partycjach; zalecamy zamiast tego użycie ext4. Na przykład:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Aby upewnić się, że punkt montowania /metadata
istnieje, dodaj następujący wiersz do BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Zmiany w sekwencji początkowej
Gdy używane jest szyfrowanie metadanych, vold
musi być uruchomiony przed zamontowaniem /data
. Aby upewnić się, że zostanie uruchomiony odpowiednio wcześnie, dodaj następującą sekcję do init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster musi być uruchomiony i gotowy, zanim init spróbuje zamontować /data
.
init.hardware.rc
powinien już zawierać instrukcję mount_all
, która montuje sam /data
w on late-fs
. Przed tym wierszem dodaj dyrektywę, aby wykonać usługę 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łączanie szyfrowania metadanych
Na koniec dodaj keydirectory=/metadata/vold/metadata_encryption
do kolumny fs_mgr_flags wpisu fstab
dla userdata
. Na przykład pełna linia fstab może wyglądać 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 algorytm szyfrowania metadanych w pamięci wewnętrznej to AES-256-XTS. Można to zmienić, ustawiając opcję metadata_encryption
, również w kolumnie fs_mgr_flags :
- Na urządzeniach, które nie mają akceleracji AES, szyfrowanie Adiantum można włączyć, ustawiając
metadata_encryption=adiantum
. - Na urządzeniach obsługujących klucze opakowane sprzętowo klucz szyfrowania metadanych można opakować 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).
Ponieważ interfejs jądra na dm-default-key
zmienił się w Androidzie 11, musisz również upewnić się, że ustawiłeś poprawną wartość dla PRODUCT_SHIPPING_API_LEVEL
w device.mk
. Na przykład, jeśli Twoje urządzenie uruchamia się z systemem Android 11 (poziom interfejsu API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz również ustawić następującą właściwość systemową, aby wymusić użycie nowego interfejsu API dm-default-key
niezależnie od poziomu interfejsu API wysyłki:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Walidacja
Aby sprawdzić, czy szyfrowanie metadanych jest włączone i działa poprawnie, uruchom testy opisane poniżej. Pamiętaj też o typowych problemach opisanych poniżej.
Testy
Zacznij od uruchomienia następującego polecenia, aby sprawdzić, czy szyfrowanie metadanych jest włączone w pamięci wewnętrznej:
adb root
adb shell dmctl table userdata
Wynik powinien być podobny do:
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ę nieznacznie różnić od powyższych. Na przykład, jeśli włączyłeś szyfrowanie Adiantum , trzecim polem będzie xchacha12,aes-adiantum-plain64
zamiast aes-xts-plain64
.
Następnie uruchom vts_kernel_encryption_test , aby zweryfikować poprawność szyfrowania metadanych i FBE:
atest vts_kernel_encryption_test
lub:
vts-tradefed run vts -m vts_kernel_encryption_test
Powszechne problemy
Podczas wywołania mount_all
, które montuje partycję /data
zaszyfrowaną metadanymi, init
wykonuje narzędzie vdc. Narzędzie vdc łączy się z vold
over binder
, aby skonfigurować urządzenie zaszyfrowane metadanymi i zamontować partycję. Na czas tego wywołania init
jest blokowany, a próby odczytu lub ustawienia właściwości init
będą blokowane do momentu zakończenia mount_all
. Jeśli na tym etapie jakakolwiek część pracy vold
zostanie bezpośrednio lub pośrednio zablokowana podczas odczytu lub ustawienia właściwości, nastąpi zakleszczenie. Ważne jest, aby upewnić się, że vold
może dokończyć odczytywanie kluczy, interakcję z Keymasterem i montowanie katalogu danych bez dalszej interakcji z init
.
Jeśli Keymaster nie zostanie w pełni uruchomiony po uruchomieniu mount_all
, nie zareaguje na vold
, dopóki nie odczyta pewnych właściwości z init
, co skutkuje dokładnie opisanym zakleszczeniem. Umieszczenie exec_start wait_for_keymaster
nad odpowiednim wywołaniem mount_all
, zgodnie z opisem, zapewnia, że Keymaster jest w pełni uruchomiony z wyprzedzeniem, co pozwala uniknąć tego zakleszczenia.
Konfiguracja na możliwej do przyjęcia pamięci
Od Androida 9 forma szyfrowania metadanych jest zawsze włączona w przystosowanej pamięci masowej , gdy włączona jest funkcja FBE, nawet jeśli szyfrowanie metadanych nie jest włączone w pamięci wewnętrznej.
W AOSP istnieją dwie implementacje szyfrowania metadanych w zaadaptowanej pamięci: przestarzała oparta na dm-crypt
i nowsza oparta na dm-default-key
. Aby upewnić się, że została wybrana prawidłowa implementacja dla Twojego urządzenia, upewnij się, że w device.mk
ustawiono poprawną wartość parametru PRODUCT_SHIPPING_API_LEVEL
. Na przykład, jeśli Twoje urządzenie uruchamia się z systemem Android 11 (poziom interfejsu API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz również ustawić następujące właściwości systemu, aby wymusić użycie nowej metody szyfrowania metadanych woluminu (i nowej domyślnej wersji polityki FBE) niezależnie od poziomu interfejsu API wysyłki:
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 uruchamianych z systemem Android 11 lub nowszym szyfrowanie metadanych w przystosowanej pamięci masowej wykorzystuje moduł jądra dm-default-key
, podobnie jak w pamięci wewnętrznej. Zobacz wymagania wstępne powyżej, które opcje konfiguracji jądra włączyć. Należy zauważyć, że sprzęt do szyfrowania inline, który działa w pamięci wewnętrznej urządzenia, może być niedostępny w pamięci możliwej do zaadoptowania, dlatego może być wymagane CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
Domyślnie metoda szyfrowania metadanych woluminu dm-default-key
używa algorytmu szyfrowania AES-256-XTS z 4096-bajtowymi sektorami kryptograficznymi. Algorytm można nadpisać, 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 fstab 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
.
Wcześniejsza metoda
Na urządzeniach uruchamianych z systemem Android 10 lub starszym szyfrowanie metadanych w przystosowanej pamięci masowej używa modułu jądra 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 i raz za pomocą klucza szyfrowania metadanych. To podwójne szyfrowanie zmniejsza wydajność i nie jest wymagane do osiągnięcia celów bezpieczeństwa szyfrowania metadanych, ponieważ Android zapewnia, że klucze FBE są co najmniej tak samo trudne do złamania, jak klucz szyfrowania metadanych. Dostawcy mogą wprowadzać dostosowania jądra, aby uniknąć podwójnego szyfrowania, w szczególności przez zaimplementowanie opcji allow_encrypt_override
, którą system Android przekaże do dm-crypt
, gdy właściwość systemowa ro.crypto.allow_encrypt_override
jest ustawiona na true
. Te dostosowania nie są obsługiwane przez wspólne jądro systemu Android.
Domyślnie metoda szyfrowania metadanych woluminu dm-crypt
wykorzystuje algorytm szyfrowania AES-128-CBC z ESSIV i 512-bajtowymi sektorami kryptograficznymi. Można to zmienić, ustawiając następujące właściwości systemu (które są również używane w FDE):
-
ro.crypto.fde_algorithm
wybiera algorytm szyfrowania metadanych. Do wyboru sąaes-128-cbc
iadiantum
. Adiantum można używać tylko wtedy, gdy urządzenie nie ma akceleracji AES. -
ro.crypto.fde_sector_size
wybiera rozmiar sektora kryptograficznego. Dostępne opcje to 512, 1024, 2048 i 4096. W przypadku szyfrowania Adiantum użyj 4096.