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 odblokować niezależnie. Te klucze są używane do szyfrowania zarówno zawartości plików, jak i ich nazw. W przypadku FBE inne informacje, takie jak układy katalogów, rozmiary plików, uprawnienia i czas utworzenia/modyfikacji, nie są szyfrowane. Te informacje są określane jako metadane systemu plików.
Android 9 wprowadził obsługę szyfrowania metadanych. W przypadku szyfrowania metadanych jeden klucz obecny podczas uruchamiania szyfruje wszystkie treści, które nie są szyfrowane przez FBE. Klucz jest chroniony przez Keymaster, który z kolei jest chroniony przez weryfikowany rozruch.
Szyfrowanie metadanych jest zawsze włączone w przechowywaniu dostosowywanym, gdy włączona jest funkcja FBE. Szyfrowanie metadanych można też włączyć w pamięci wewnętrznej. Na urządzeniach z Androidem 11 lub nowszym musi być włączone szyfrowanie metadanych w pamięci wewnętrznej.
Implementacja w pamięci wewnętrznej
Szyfrowanie metadanych możesz skonfigurować 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 formatowania partycji danych. Dlatego ta funkcja jest dostępna tylko na nowych urządzeniach. Nie można jej zmienić za pomocą aktualizacji OTA.
Szyfrowanie metadanych wymaga włączenia w jądrze modułu dm-default-key
. W Androidzie 11 i nowszych dm-default-key
jest obsługiwana przez wspólne jądra Androida w wersji 4.14 lub nowszej. Ta wersja dm-default-key
korzysta z ramy szyfrowania blk-crypto, która jest niezależna od sprzętu i producenta.
Aby włączyć funkcję dm-default-key
, użyj:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
korzysta z interfejsowego sprzętu do szyfrowania (sprzęt, który szyfruje/odszyfrowuje dane podczas ich przesyłania do lub z urządzenia do przechowywania danych), gdy jest dostępny. Jeśli nie używasz sprzętowego szyfrowania w transmisji, musisz też włączyć alternatywne szyfrowanie za pomocą interfejsu API szyfrowania jądra:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Jeśli nie używasz sprzętowego szyfrowania w przepływie danych, włącz wszystkie dostępne przyspieszenia oparte na procesorze zgodnie z zaleceniami podanymi w dokumentacji FBE.
W Androidzie 10 i starszych dm-default-key
nie było obsługiwane przez wspólne jądro Androida. Dlatego implementacja dm-default-key
zależała od dostawców.
Konfigurowanie systemu plików metadanych
Ponieważ nic na partycji userdata nie może być odczytywane, dopóki nie pojawi się klucz szyfrowania metadanych, tabela partycji musi mieć osobną partycję o nazwie „partycja metadanych” na potrzeby przechowywania blobów klucza głównego, 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 i jest montowany w /metadata
, w tym flagę formattable
, aby zapewnić sformatowanie podczas uruchamiania. System plików f2fs nie działa na mniejszych partycjach. Zalecamy użycie systemu plików ext4. Przykład:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Aby mieć pewność, że punkt zamontowania /metadata
istnieje, dodaj ten wiersz do pliku BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Zmiany w sekwencji inicjalizacji
Gdy używane jest szyfrowanie metadanych, vold
musi być uruchomiony przed zamontowaniem /data
. Aby zapewnić, że zostanie ona uruchomiona odpowiednio wcześnie, dodaj do pliku init.hardware.rc
ten wers:
# We need vold early for metadata encryption on early-fs start vold
Keymaster musi być uruchomiony i gotowy, zanim init spróbuje zamontować /data
.
Plik init.hardware.rc
powinien już zawierać instrukcję mount_all
, która powoduje zamontowanie /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 w rekordzie 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ślnym 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, które nie mają akceleracji AES, szyfrowanie Adiantum można włączyć, ustawiając wartość
metadata_encryption=adiantum
. - Na urządzeniach obsługujących klucze zaszyfrowane na poziomie sprzętu klucz szyfrowania metadanych można zaszyfrować na poziomie sprzętu, ustawiając wartość
metadata_encryption=aes-256-xts:wrappedkey_v0
(lub równoważniemetadata_encryption=:wrappedkey_v0
, ponieważaes-256-xts
jest domyślnym algorytmem).
Ponieważ interfejs jądra dla dm-default-key
zmienił się w Androidzie 11, musisz też ustawić prawidłową wartość dla PRODUCT_SHIPPING_API_LEVEL
w device.mk
. Jeśli na przykład urządzenie jest uruchamiane z Androidem 11 (poziom API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz też ustawić tę właściwość systemu, aby wymusić użycie nowego interfejsu dm-default-key
API 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, wykonaj opisane poniżej testy. Zwróć też uwagę na częste problemy opisane poniżej.
Testy
Najpierw uruchom to polecenie, aby sprawdzić, czy szyfrowanie metadanych jest włączone w pamięci wewnętrznej:
adb root
adb shell dmctl table userdata
Dane wyjściowe powinny wyglądać mniej więcej tak:
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 domyślne ustawienia szyfrowania zostały zastąpione przez ustawienie opcji metadata_encryption
w ustawieniach fstab
urządzenia, dane wyjściowe będą się nieco różnić od podanych powyżej. Jeśli na przykład masz włączone szyfrowanie Adiantum, trzecie pole to xchacha12,aes-adiantum-plain64
, a nie 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 zaszyfrowaną metadanymi partycję /data
, init
uruchamia narzędzie vdc. Narzędzie vdc
łączy się z vold
przez binder
, aby skonfigurować urządzenie z zaszyfrowanymi metadanymi i zamontować partycję. Podczas trwania tego wywołania init
jest zablokowany, a próby odczytu lub ustawienia właściwości init
są blokowane, dopóki nie zakończy się mount_all
.
Jeśli na tym etapie jakakolwiek część pracy vold
jest bezpośrednio lub pośrednio zablokowana w czytaniu lub ustawianiu właściwości, dochodzi do blokady. Ważne jest, aby vold
mogło odczytać klucze, współpracować z Keymaster i zamontować katalog danych bez dalszej interakcji z init
.
Jeśli Keymaster nie jest w pełni uruchomiony, gdy mount_all
jest uruchamiany, nie odpowiada na vold
, dopóki nie odczyta pewnych właściwości z init
, co powoduje dokładnie opisany wyżej impas. Umieszczenie funkcji exec_start wait_for_keymaster
przed odpowiednim wywołaniem funkcji mount_all
zapewnia, że Keymaster jest w pełni uruchomiony z wyprzedzeniem, co pozwala uniknąć tego rodzaju blokady.
Konfiguracja pamięci dostosowywanej
Od Androida 9 w przypadku włączonego FBE zawsze włączana jest forma szyfrowania metadanych w adoptowalnej pamięci, nawet jeśli szyfrowanie metadanych nie jest włączone w pamięci wewnętrznej.
W AOSP istnieją 2 implementacje szyfrowania metadanych w przystosowywalnej pamięci masowej: przestarzała oparta na dm-crypt
i nowsza oparta na dm-default-key
. Aby mieć pewność, że dla Twojego urządzenia wybrano prawidłową implementację, sprawdź, czy w polu PRODUCT_SHIPPING_API_LEVEL
ustawiona jest prawidłowa wartość device.mk
. Jeśli na przykład urządzenie uruchamia się z Androidem 11 (poziom API 30), device.mk
powinien zawierać:
PRODUCT_SHIPPING_API_LEVEL := 30
Możesz też ustawić te właściwości systemowe, aby wymusić użycie nowej metody szyfrowania metadanych woluminu (i nowej domyślnej wersji zasad FBE) niezależnie od poziomu interfejsu Shipping API:
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
Bieżąca metoda
Na urządzeniach z Androidem 11 lub nowszym szyfrowanie metadanych na adoptowanej pamięci używa modułu jądra dm-default-key
, tak jak w przypadku pamięci wewnętrznej. Aby dowiedzieć się, które opcje konfiguracji jądra należy włączyć, zapoznaj się z wymaganiami wstępnymi powyżej. Pamiętaj, że sprzęt do szyfrowania wbudowany w pamięć wewnętrzną urządzenia może być niedostępny w przypadku adoptowanej pamięci, dlatego może być wymagana 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 szyfrowania. Algorytm można zastąpić, ustawiając właściwość systemu ro.crypto.volume.metadata.encryption
. Wartość tej właściwości ma tę samą składnię co opcja metadata_encryption
fstab opisana powyżej. Na przykład na urządzeniach, które nie mają akceleracji AES, szyfrowanie Adiantum można włączyć, ustawiając wartość ro.crypto.volume.metadata.encryption=adiantum
.
Starsza metoda
Na urządzeniach z Androidem 10 lub starszym szyfrowanie metadanych na adoptowanym miejscu na dane używa modułu 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 szyfrowania FBE i raz kluczem szyfrowania metadanych. Podwójne szyfrowanie zmniejsza wydajność i nie jest wymagane do osiągnięcia celów bezpieczeństwa związanych z szyfrowaniem metadanych, ponieważ Android zapewnia, że klucze FBE są co najmniej tak trudne do skompromitowania jak klucz szyfrujący metadane. Dostawcy mogą dostosować jądro, aby uniknąć podwójnego szyfrowania, w szczególności poprzez 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 elementy 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 szyfrowania. Można je zastąpić, ustawiając te właściwości systemu (które są też używane do szyfrowania całego dysku):
ro.crypto.fde_algorithm
wybiera algorytm szyfrowania metadanych. Dostępne opcje toaes-128-cbc
iadiantum
. Adiantum może być używane 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.