Шифрование метаданных

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 .

Настроить файловую систему метаданных

Поскольку ничто в разделе пользовательских данных не может быть прочитано до тех пор, пока не появится ключ шифрования метаданных, в таблице разделов должен быть выделен отдельный раздел, называемый «разделом метаданных», для хранения больших двоичных объектов мастера ключей, которые защищают этот ключ. Раздел метаданных должен быть 16MB.

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

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 userdata столбец fs_mgr_flags записи fstab для пользовательских данных. Например, полная строка 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.