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

Android 7.0 и выше поддерживает шифрование на основе файлов (FBE). FBE позволяет шифровать разные файлы с помощью разных ключей, которые можно разблокировать независимо. Эти ключи используются для шифрования как содержимого файлов, так и имен файлов. При использовании FBE другая информация, такая как макеты каталогов, размеры файлов, разрешения и время создания/изменения, не шифруется. В совокупности эта другая информация известна как метаданные файловой системы.

В Android 9 появилась поддержка шифрования метаданных. При шифровании метаданных один ключ, присутствующий во время загрузки, шифрует любой контент, не зашифрованный FBE. Этот ключ защищен 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 была задачей поставщиков.

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

Поскольку ничего в разделе пользовательских данных не может быть прочитано до тех пор, пока не будет представлен ключ шифрования метаданных, таблица разделов должна выделить отдельный раздел, называемый разделом метаданных, для хранения BLOB-объектов Keymaster, которые защищают этот ключ. Раздел метаданных должен быть размером 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

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 . Adiantum можно использовать только в том случае, если на устройстве отсутствует ускорение AES.
  • ro.crypto.fde_sector_size выбирает размер криптосектора. Возможные варианты: 512, 1024, 2048 и 4096. Для шифрования Adiantum используйте 4096.