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. Klucze te służą do szyfrowania zarówno zawartości plików, jak i nazw plików. Kiedy używany jest FBE, inne informacje, takie jak układ katalogów, rozmiary plików, uprawnienia i czas tworzenia/modyfikacji, nie są szyfrowane. Łącznie te inne informacje nazywane są metadanymi systemu plików.
W Androidzie 9 wprowadzono obsługę szyfrowania metadanych. Dzięki szyfrowaniu metadanych pojedynczy klucz obecny podczas uruchamiania szyfruje całą zawartość, która nie jest szyfrowana przez FBE. Klucz ten 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 także włączyć w pamięci wewnętrznej. Urządzenia 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ę inicjującą i włączając szyfrowanie metadanych w pliku fstab urządzenia.
Warunki 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ń; nie jest to 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 platformę szyfrowania niezależną od sprzętu i dostawcy 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 interfejsu API kryptografii jądra:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Jeśli nie używasz wbudowanego sprzętu szyfrującego, powinieneś także włączyć dostępne przyspieszenie oparte na procesorze, zgodnie z zaleceniami w dokumentacji FBE .
W Androidzie 10 i starszych dm-default-key
nie był obsługiwany przez wspólne jądro Androida. Dlatego wdrożenie dm-default-key
należało do dostawców.
Skonfiguruj system plików metadanych
Ponieważ nic z partycji danych użytkownika nie może zostać odczytane, dopóki nie będzie klucza szyfrowania metadanych, tabela partycji musi wydzielić osobną partycję zwaną „partycją metadanych” do przechowywania obiektów BLOB klucza głównego chroniących 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
, łącznie z flagą formattable
, aby zapewnić sformatowanie go podczas rozruchu. 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 początkowej
Gdy używane jest szyfrowanie metadanych, przed zamontowaniem /data
należy uruchomić polecenie vold
. Aby mieć pewność, że zostanie uruchomiony wystarczająco wcześnie, dodaj następującą sekcję do pliku init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster musi być uruchomiony i gotowy przed podjęciem prób zamontowania /data
.
init.hardware.rc
powinien już zawierać instrukcję mount_all
, która montuje sam /data
w sekcji on late-fs
. Przed tą linią dodaj dyrektywę uruchamiającą 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ć 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ślnie algorytm szyfrowania metadanych w pamięci wewnętrznej to AES-256-XTS. Można to obejść ustawiając opcję metadata_encryption
, również w kolumnie fs_mgr_flags :
- Na urządzeniach pozbawionych 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 dla dm-default-key
zmienił się w Androidzie 11, musisz także 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 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, wykonaj testy opisane poniżej. Należy także pamiętać o typowych problemach opisanych poniżej.
Testy
Zacznij od uruchomienia następującego polecenia, aby sprawdzić, czy w pamięci wewnętrznej jest włączone szyfrowanie metadanych:
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ą nieznacznie różnić się 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 metody mount_all
, która montuje partycję /data
zaszyfrowaną metadanymi, init
wykonuje narzędzie vdc. Narzędzie vdc łączy się z vold
over binder
w celu skonfigurowania urządzenia zaszyfrowanego metadanymi i zamontowania partycji. Na czas trwania tego wywołania init
jest blokowany, a próby odczytania lub ustawienia właściwości init
będą blokowane do czasu zakończenia mount_all
. Jeśli na tym etapie jakakolwiek część pracy vold
zostanie bezpośrednio lub pośrednio zablokowana podczas odczytywania lub ustawiania właściwości, nastąpi zakleszczenie. Ważne jest, aby upewnić się, że vold
może dokończyć pracę polegającą na czytaniu kluczy, interakcji z Keymasterem i montowaniu katalogu danych bez dalszej interakcji z init
.
Jeśli Keymaster nie zostanie w pełni uruchomiony podczas działania 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, gwarantuje, że Keymaster będzie w pełni działać z wyprzedzeniem, co pozwoli uniknąć tego impasu.
Konfiguracja dostępnej pamięci masowej
Od wersji Androida 9 forma szyfrowania metadanych jest zawsze włączona w dostępnej 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 dostępnej pamięci masowej: przestarzała oparta na dm-crypt
i nowsza oparta na dm-default-key
. Aby mieć pewność, że dla Twojego urządzenia została wybrana prawidłowa implementacja, upewnij się, że ustawiłeś prawidłową wartość PRODUCT_SHIPPING_API_LEVEL
w device.mk
. Na przykład, jeśli Twoje urządzenie uruchamia się z systemem Android 11 (poziom API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz także ustawić następujące właściwości systemu, aby wymusić użycie nowej metody szyfrowania metadanych woluminów (i nowej domyślnej wersji zasad FBE) niezależnie od poziomu 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
Aktualna metoda
Na urządzeniach z systemem Android 11 lub nowszym szyfrowanie metadanych w dostępnej pamięci masowej wykorzystuje moduł jądra dm-default-key
, podobnie jak w przypadku pamięci wewnętrznej. Zobacz wymagania wstępne powyżej, aby dowiedzieć się, które opcje konfiguracji jądra należy włączyć. Należy pamiętać, że wbudowany sprzęt szyfrujący działający w wewnętrznej pamięci urządzenia może być niedostępny w dostępnej pamięci masowej i dlatego może być wymagane ustawienie CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
Domyślnie metoda szyfrowania metadanych woluminu dm-default-key
wykorzystuje algorytm szyfrowania AES-256-XTS z sektorami kryptograficznymi o wielkości 4096 bajtów. 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
fstab. Na przykład na urządzeniach pozbawionych akceleracji AES szyfrowanie Adiantum można włączyć, ustawiając ro.crypto.volume.metadata.encryption=adiantum
.
Metoda starsza
Na urządzeniach z systemem Android 10 lub starszym szyfrowanie metadanych w dostępnej pamięci wykorzystuje moduł jądra dm-crypt
a nie dm-default-key
:
CONFIG_DM_CRYPT=y
W przeciwieństwie do metody dm-default-key
, metoda dm-crypt
powoduje, że zawartość pliku jest szyfrowana dwukrotnie: 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ą dostosować jądro, aby uniknąć podwójnego szyfrowania, w szczególności poprzez wdrożenie allow_encrypt_override
, którą 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 sektorami kryptograficznymi ESSIV i 512-bajtowymi. Można to obejść, 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
. Z Adiantum można korzystać jedynie wtedy, gdy urządzenie nie posiada akceleracji AES. -
ro.crypto.fde_sector_size
wybiera rozmiar sektora kryptograficznego. Dostępne wartości to 512, 1024, 2048 i 4096. W przypadku szyfrowania Adiantum użyj wartości 4096.