Android 7.0 и более поздние версии поддерживают шифрование на уровне файлов (FBE). FBE позволяет шифровать различные файлы с помощью разных ключей, которые можно разблокировать независимо. Эти ключи используются для шифрования как содержимого, так и имён файлов. При использовании FBE другая информация, такая как структура каталогов, размеры файлов, разрешения и время создания/изменения, не шифруется. В совокупности эта информация называется метаданными файловой системы.
В Android 9 появилась поддержка шифрования метаданных. Шифрование метаданных подразумевает наличие одного ключа, присутствующего во время загрузки, который шифрует всё содержимое, не зашифрованное FBE. Этот ключ защищён KeyMint (ранее Keymaster), который, в свою очередь, защищён Verified Boot.
Шифрование метаданных всегда включено на адаптивном хранилище при включении 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
самостоятельно.
Настроить файловую систему метаданных
Поскольку данные в разделе пользовательских данных не могут быть прочитаны без ключа шифрования метаданных, в таблице разделов необходимо выделить отдельный раздел, называемый разделом метаданных, для хранения двоичных объектов KeyMint, защищающих этот ключ. Размер раздела метаданных должен составлять 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
Изменения в последовательности инициализации
При использовании шифрования метаданных vold
должен быть запущен до монтирования /data
. Чтобы обеспечить его ранний запуск, добавьте следующую строку в init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
KeyMint должен быть запущен и готов к работе, прежде чем 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
сможет завершить чтение ключей, взаимодействие с KeyMint и монтирование каталога данных без дальнейшего взаимодействия с init
.
Если KeyMint не полностью запущен при запуске mount_all
, он не отвечает на vold
, пока не прочитает определённые свойства из init
, что приводит к описанной взаимоблокировке. Размещение exec_start wait_for_keymaster
перед соответствующим вызовом mount_all
, как указано, гарантирует, что KeyMint будет полностью запущен заранее, и таким образом избежит этой взаимоблокировки.
Конфигурация на адаптивном хранилище
Начиная с 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
. Adiantum можно использовать только если устройство не поддерживает ускорение AES. -
ro.crypto.fde_sector_size
выбирает размер криптографического сектора. Возможные варианты: 512, 1024, 2048 и 4096. Для шифрования Adiantum используйте 4096.