Android 7.0 и более поздних версий поддерживает шифрование на основе файлов (FBE). FBE позволяет шифровать разные файлы разными ключами, которые можно разблокировать независимо. Эти ключи используются для шифрования как содержимого файлов, так и имен файлов. При использовании FBE другая информация, такая как макеты каталогов, размеры файлов, разрешения и время создания/изменения, не шифруется. В совокупности эта другая информация известна как метаданные файловой системы.
В Android 9 появилась поддержка шифрования метаданных. При шифровании метаданных единственный ключ, присутствующий во время загрузки, шифрует любой контент, не зашифрованный FBE. Этот ключ защищен Keymaster, который, в свою очередь, защищен проверенной загрузкой.
Шифрование метаданных всегда включено в подключаемом хранилище , когда включен FBE. Шифрование метаданных также можно включить во внутренней памяти. На устройствах с Android 11 или более поздней версии должно быть включено шифрование метаданных во внутренней памяти.
Реализация во внутренней памяти
Вы можете настроить шифрование метаданных во внутренней памяти новых устройств, настроив файловую систему metadata
, изменив последовательность инициализации и включив шифрование метаданных в файле fstab устройства.
Предварительные условия
Шифрование метаданных можно настроить только при первом форматировании раздела данных. В результате эта функция доступна только для новых устройств; это не то, что OTA должно изменить.
Для шифрования метаданных необходимо, чтобы в вашем ядре был включен модуль dm-default-key
. В Android 11 и более поздних версиях dm-default-key
поддерживается общими ядрами Android версии 4.14 и более поздних. Эта версия dm-default-key
использует независимую от аппаратного обеспечения и поставщика платформу шифрования, называемую blk-crypto .
Чтобы включить dm-default-key
, используйте:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
использует встроенное оборудование шифрования (оборудование, которое шифрует/дешифрует данные, пока они находятся на пути к устройству хранения/от него), если оно доступно. Если вы не используете встроенное оборудование шифрования, также необходимо включить резервный вариант криптографического API ядра:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Если вы не используете встроенное оборудование шифрования, вам также следует включить любое доступное ускорение на базе ЦП, как рекомендовано в документации FBE .
В Android 10 и более ранних версиях dm-default-key
не поддерживался общим ядром Android. Поэтому поставщики должны были реализовать dm-default-key
.
Настройка файловой системы метаданных
Поскольку ничто в разделе пользовательских данных не может быть прочитано до тех пор, пока не будет присутствовать ключ шифрования метаданных, в таблице разделов должен быть выделен отдельный раздел, называемый «разделом метаданных», для хранения больших двоичных объектов мастера ключей, которые защищают этот ключ. Раздел метаданных должен иметь размер 16 МБ.
fstab.hardware
должен включать запись для файловой системы метаданных, которая находится в этом разделе, монтируя ее в /metadata
, включая флаг formattable
, чтобы гарантировать ее форматирование во время загрузки. Файловая система f2fs не работает на разделах меньшего размера; вместо этого мы рекомендуем использовать ext4. Например:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Чтобы убедиться, что точка монтирования /metadata
существует, добавьте следующую строку в BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Изменения в последовательности инициализации
Если используется шифрование метаданных, перед монтированием /data
должен быть запущен vold
. Чтобы гарантировать, что он запускается достаточно рано, добавьте следующий раздел в init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster должен быть запущен и готов, прежде чем init попытается смонтировать /data
.
init.hardware.rc
уже должен содержать инструкцию mount_all
, которая монтирует сам /data
в разделе on late-fs
. Перед этой строкой добавьте директиву для выполнения службы 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
Включить шифрование метаданных
Наконец, добавьте keydirectory=/metadata/vold/metadata_encryption
в столбец fs_mgr_flags записи fstab
для userdata
. Например, полная строка fstab может выглядеть так:
/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
По умолчанию алгоритм шифрования метаданных во внутреннем хранилище — AES-256-XTS. Это можно переопределить, установив параметр metadata_encryption
, также в столбце fs_mgr_flags :
- На устройствах, где отсутствует ускорение AES, шифрование Adiantum можно включить, установив
metadata_encryption=adiantum
. - На устройствах, которые поддерживают аппаратно упакованные ключи , ключ шифрования метаданных можно сделать аппаратно упакованным, установив
metadata_encryption=aes-256-xts:wrappedkey_v0
(или, что эквивалентно,metadata_encryption=:wrappedkey_v0
, посколькуaes-256-xts
является алгоритмом по умолчанию).
Поскольку интерфейс ядра для dm-default-key
изменился в Android 11, вам также необходимо убедиться, что вы установили правильное значение для PRODUCT_SHIPPING_API_LEVEL
в device.mk
. Например, если ваше устройство запускается с Android 11 (уровень API 30), device.mk
должен содержать:
PRODUCT_SHIPPING_API_LEVEL := 30
Вы также можете установить следующее системное свойство, чтобы принудительно использовать новый API dm-default-key
независимо от уровня API доставки:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Валидация
Чтобы убедиться, что шифрование метаданных включено и работает правильно, запустите тесты, описанные ниже. Также помните о распространенных проблемах, описанных ниже.
Тесты
Начните с выполнения следующей команды, чтобы убедиться, что шифрование метаданных включено во внутренней памяти:
adb root
adb shell dmctl table userdata
Вывод должен быть похож на:
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
Если вы отменили настройки шифрования по умолчанию, установив параметр metadata_encryption
в fstab
устройства, то выходные данные немного будут отличаться от приведенных выше. Например, если вы включили шифрование Adiantum , то третье поле — xchacha12,aes-adiantum-plain64
вместо aes-xts-plain64
.
Далее запустите vts_kernel_encryption_test , чтобы проверить корректность шифрования метаданных и FBE:
atest vts_kernel_encryption_test
или:
vts-tradefed run vts -m vts_kernel_encryption_test
Общие проблемы
Во время вызова mount_all
, который монтирует зашифрованный метаданными раздел /data
, init
запускает инструмент vdc. Инструмент vdc подключается к vold
через binder
для настройки устройства с шифрованием метаданных и монтирования раздела. На время этого вызова init
блокируется и пытается либо прочитать, либо установить блокировку свойств init
до тех пор, пока не завершится mount_all
. Если на этом этапе какая-либо часть работы vold
прямо или косвенно блокируется при чтении или установке свойства, возникает взаимоблокировка. Важно гарантировать, что vold
сможет завершить работу по чтению ключей, взаимодействию с Keymaster и монтированию каталога данных без дальнейшего взаимодействия с init
.
Если Keymaster не запускается полностью при запуске mount_all
, он не отвечает на vold
до тех пор, пока не прочитает определенные свойства из init
, что приводит к точно описанной взаимоблокировке. Размещение exec_start wait_for_keymaster
над соответствующим вызовом mount_all
, как указано, гарантирует, что Keymaster полностью запущен заранее, и, таким образом, позволяет избежать этой тупиковой ситуации.
Конфигурация на приемлемом хранилище
Начиная с Android 9, форма шифрования метаданных всегда включена во внешнем хранилище , когда включен FBE, даже если шифрование метаданных не включено во внутреннем хранилище.
В AOSP существует две реализации шифрования метаданных в доступном хранилище: устаревшая, основанная на dm-crypt
, и новая, основанная на dm-default-key
. Чтобы убедиться, что для вашего устройства выбрана правильная реализация, убедитесь, что вы установили правильное значение для PRODUCT_SHIPPING_API_LEVEL
в device.mk
. Например, если ваше устройство запускается с Android 11 (уровень API 30), device.mk
должен содержать:
PRODUCT_SHIPPING_API_LEVEL := 30
Вы также можете установить следующие системные свойства, чтобы принудительно использовать новый метод шифрования метаданных тома (и новую версию политики FBE по умолчанию) независимо от уровня 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
Текущий метод
На устройствах с Android 11 или более поздней версии шифрование метаданных во внешнем хранилище использует модуль ядра dm-default-key
, как и во внутреннем хранилище. См. предварительные условия выше, чтобы определить, какие параметры конфигурации ядра включить. Обратите внимание, что аппаратное обеспечение встроенного шифрования, работающее во внутренней памяти устройства, может быть недоступно в подключаемом хранилище, поэтому может потребоваться CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
По умолчанию метод шифрования метаданных тома dm-default-key
использует алгоритм шифрования AES-256-XTS с криптографическими секторами размером 4096 байт. Алгоритм можно переопределить, установив системное свойство ro.crypto.volume.metadata.encryption
. Значение этого свойства имеет тот же синтаксис, что и параметр fstab metadata_encryption
описанный выше. Например, на устройствах, где отсутствует ускорение AES, шифрование Adiantum можно включить, установив ro.crypto.volume.metadata.encryption=adiantum
.
Устаревший метод
На устройствах с Android 10 или более ранней версии шифрование метаданных в подключаемом хранилище использует модуль ядра dm-crypt
а не dm-default-key
:
CONFIG_DM_CRYPT=y
В отличие от метода dm-default-key
, метод dm-crypt
вызывает двойное шифрование содержимого файла: один раз с помощью ключа FBE и один раз с помощью ключа шифрования метаданных. Такое двойное шифрование снижает производительность и не требуется для достижения целей безопасности шифрования метаданных, поскольку Android гарантирует, что ключи FBE как минимум так же сложно взломать, как и ключ шифрования метаданных. Поставщики могут настраивать ядро, чтобы избежать двойного шифрования, в частности, реализуя allow_encrypt_override
, который Android передает dm-crypt
, когда для системного свойства ro.crypto.allow_encrypt_override
установлено значение true
. Эти настройки не поддерживаются общим ядром Android.
По умолчанию метод шифрования метаданных тома dm-crypt
использует алгоритм шифрования AES-128-CBC с ESSIV и 512-байтовыми криптографическими секторами. Это можно переопределить, установив следующие системные свойства (которые также используются для FDE):
-
ro.crypto.fde_algorithm
выбирает алгоритм шифрования метаданных. Выбор:aes-128-cbc
иadiantum
. Адиантум можно использовать только в том случае, если в устройстве отсутствует ускорение AES. -
ro.crypto.fde_sector_size
выбирает размер криптосектора. Возможные значения: 512, 1024, 2048 и 4096. Для шифрования Adiantum используйте 4096.