Android 7.0 i nowsze obsługują 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żą do szyfrowania zarówno zawartości, jak i nazw plików. Gdy używany jest FBE, inne informacje, takie jak układy 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 podczas uruchamiania systemu szyfruje zawartość, która nie została zaszyfrowana przez FBE. Ten klucz jest chroniony przez Keymaster, który z kolei jest chroniony przez zweryfikowany rozruch.
Szyfrowanie metadanych jest zawsze włączone w przypadku adaptowalnej pamięci masowej , gdy włączone jest 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.
Implementacja w 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 sekwencję init 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 rezultacie ta funkcja jest dostępna tylko dla nowych urządzeń; to nie jest coś, co OTA powinno zmienić.
Szyfrowanie metadanych wymaga włączenia modułu dm-default-key
w jądrze. W Androidzie 11 i nowszych dm-default-key
jest obsługiwany przez popularne jądra Androida w wersji 4.14 i nowszych. Ta wersja dm-default-key
wykorzystuje niezależną od sprzętu i producenta strukturę 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ęt, 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ć sprzętu do szyfrowania wbudowanego, konieczne jest również włączenie awaryjnego interfejsu API kryptografii jądra:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Jeśli nie korzystasz ze sprzętu do szyfrowania wbudowanego, należy również włączyć dostępne przyspieszenie oparte na procesorze, zgodnie z zaleceniami w dokumentacji FBE .
W Androidzie 10 i niższych dm-default-key
nie był obsługiwany przez wspólne jądro Androida. Dlatego do dostawców należało wdrożenie dm-default-key
.
Skonfiguruj system plików metadanych
Ponieważ niczego w partycji danych użytkownika nie można odczytać, dopóki nie będzie obecny klucz szyfrowania metadanych, tablica partycji musi odłożyć oddzielną partycję zwaną „partycją metadanych” do przechowywania obiektów BLOB wzorca klucza, które chronią ten klucz. Partycja metadanych powinna mieć rozmiar 16 MB.
fstab.hardware
musi zawierać wpis dla systemu plików metadanych, który znajduje się na tej partycji, montując go w /metadata
, w tym flagę formattable
, aby upewnić się, że jest sformatowany podczas uruchamiania. System plików f2fs nie działa na mniejszych partycjach; zamiast tego zalecamy 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 podłączenia /metadata
istnieje, dodaj następujący wiersz do BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Zmiany w sekwencji init
Gdy używane jest szyfrowanie metadanych, vold
musi być uruchomione przed zamontowaniem /data
. Aby upewnić się, że zostanie uruchomiony wystarczająco 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 sekcji on late-fs
. Przed tym wierszem dodaj dyrektywę do 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łą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ć następująco:
/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ślnym algorytmem szyfrowania metadanych w pamięci wewnętrznej jest AES-256-XTS. Można to zmienić, ustawiając opcję metadata_encryption
, również w kolumnie fs_mgr_flags :
- Na urządzeniach bez 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ż domyślnym algorytmem jestaes-256-xts
).
Ponieważ interfejs jądra do 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 jest uruchamiane z systemem Android 11 (poziom API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz także 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. Należy również pamiętać 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
Dane wyjściowe powinny być podobne 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 , trzecie pole będzie miało postać 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 z szyfrowaniem metadanych i zamontować partycję. Na czas trwania tego wywołania init
jest blokowany, a próby odczytania 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 przy czytaniu lub ustawianiu właściwości, nastąpi zakleszczenie. Ważne jest, aby vold
mógł ukończyć odczytywanie kluczy, interakcję z Keymaster i montowanie katalogu danych bez dalszej interakcji z init
.
Jeśli Keymaster nie jest w pełni uruchomiony podczas uruchamiania mount_all
, nie odpowie na vold
, dopóki nie odczyta pewnych właściwości z init
, co spowoduje dokładnie opisany impas. Umieszczenie exec_start wait_for_keymaster
nad odpowiednim wywołaniem mount_all
, jak określono, zapewnia, że Keymaster jest w pełni uruchomiony z wyprzedzeniem, a tym samym pozwala uniknąć impasu.
Konfiguracja na adaptowalnej pamięci masowej
Od wersji Androida 9 forma szyfrowania metadanych jest zawsze włączona w przypadku adaptowalnej pamięci masowej , gdy włączone jest FBE, nawet jeśli szyfrowanie metadanych nie jest włączone w pamięci wewnętrznej.
W AOSP istnieją dwie implementacje szyfrowania metadanych w pamięci masowej: przestarzała oparta na dm-crypt
i nowsza oparta na dm-default-key
. Aby upewnić się, że wybrano poprawną implementację dla Twojego urządzenia, upewnij się, że ustawiłeś prawidłową wartość dla PRODUCT_SHIPPING_API_LEVEL
w device.mk
. Na przykład, jeśli Twoje urządzenie jest uruchamiane z systemem Android 11 (poziom API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Można również ustawić następujące właściwości systemu, aby wymusić użycie nowej metody szyfrowania metadanych woluminu (oraz nowej domyślnej wersji zasad 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 adaptowalnej pamięci masowej wykorzystuje moduł jądra dm-default-key
, podobnie jak w przypadku pamięci wewnętrznej. Zobacz powyższe wymagania wstępne , aby dowiedzieć się, które opcje konfiguracji jądra włączyć. Należy pamiętać, że sprzęt do szyfrowania wbudowanego, który działa w pamięci wewnętrznej urządzenia, może być niedostępny w pamięci adaptacyjnej, dlatego może być wymagany CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
Domyślnie metoda szyfrowania metadanych woluminu dm-default-key
wykorzystuje algorytm szyfrowania AES-256-XTS z 4096-bajtowymi sektorami kryptograficznymi. Algorytm można przesłonić, 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 bez akceleracji AES szyfrowanie Adiantum można włączyć, ustawiając ro.crypto.volume.metadata.encryption=adiantum
.
Starsza metoda
Na urządzeniach uruchamianych z Androidem 10 lub starszym szyfrowanie metadanych w możliwej do adaptacji pamięci masowej wykorzystuje moduł 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 kluczem FBE i raz kluczem szyfrowania metadanych. To podwójne szyfrowanie zmniejsza wydajność i nie jest wymagane do osiągnięcia celów bezpieczeństwa szyfrowania metadanych, ponieważ system Android gwarantuje, że klucze FBE są co najmniej tak samo trudne do złamania, jak klucz szyfrowania metadanych. Dostawcy mogą dostosowywać jądro, aby uniknąć podwójnego szyfrowania, w szczególności poprzez implementację opcji allow_encrypt_override
, którą system Android przekaże 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 sektorami kryptograficznymi ESSIV i 512-bajtowymi. Można to zmienić, ustawiając następujące właściwości systemowe (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że być używane tylko wtedy, gdy urządzenie nie posiada akceleracji AES. -
ro.crypto.fde_sector_size
wybiera rozmiar sektora kryptograficznego. Do wyboru są 512, 1024, 2048 i 4096. Do szyfrowania Adiantum użyj 4096.