Файловое шифрование

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

В этой статье описывается, как включить шифрование файлов на новых устройствах и как системные приложения могут использовать API Direct Boot для обеспечения пользователям максимально безопасной работы.

Для всех устройств, выпущенных с Android 10 и выше, требуется использовать шифрование на основе файлов.

Прямая загрузка

Шифрование на основе файлов обеспечивает работу новой функции, представленной в Android 7.0, под названием Direct Boot . Direct Boot позволяет зашифрованным устройствам загружаться непосредственно на экран блокировки. Ранее на зашифрованных устройствах с использованием полного шифрования диска (FDE) пользователям требовалось ввести учетные данные для доступа к каким-либо данным, что препятствовало выполнению телефоном всех операций, кроме самых основных. Например, не могли работать будильники, были недоступны службы специальных возможностей, а телефоны не могли принимать звонки, а были ограничены только базовыми операциями экстренного вызова.

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

На устройстве с поддержкой FBE каждому пользователю устройства доступны два места хранения данных для приложений:

  • Хранилище с зашифрованными учетными данными (CE) — это место хранения по умолчанию, доступное только после разблокировки устройства пользователем.
  • Зашифрованное хранилище устройства (DE) — это место хранения, доступное как в режиме прямой загрузки, так и после разблокировки устройства пользователем.

Такое разделение повышает безопасность рабочих профилей, поскольку позволяет защитить более одного пользователя одновременно, так как шифрование больше не основано исключительно на пароле, вводимом при загрузке системы.

API Direct Boot позволяет приложениям, использующим шифрование, получать доступ к каждой из этих областей. В жизненный цикл приложения внесены изменения, чтобы обеспечить уведомление приложений о разблокировке памяти CE в ответ на первый ввод учетных данных на экране блокировки или, в случае рабочего профиля, при запросе подтверждения доступа . Устройства под управлением Android 7.0 должны поддерживать эти новые API и жизненные циклы независимо от того, реализуют ли они FBE. Однако без FBE память DE и CE всегда находится в разблокированном состоянии.

Полная реализация шифрования на основе файлов для файловых систем Ext4 и F2FS предоставляется в проекте Android Open Source Project (AOSP) и требует включения только на устройствах, отвечающих требованиям. Производители, решившие использовать шифрование на основе файлов, могут изучить способы оптимизации этой функции в зависимости от используемой системы на кристалле (SoC).

Все необходимые пакеты в AOSP были обновлены для поддержки прямой загрузки. Однако, если производители устройств используют модифицированные версии этих приложений, они хотят убедиться, что как минимум имеются пакеты, поддерживающие прямую загрузку и предоставляющие следующие услуги:

  • Телефонные услуги и дозвон
  • Способ ввода паролей на экране блокировки

Примеры и источник

Android предоставляет эталонную реализацию шифрования на основе файлов, в которой vold ( system/vold ) обеспечивает функциональность для управления устройствами хранения и томами на Android. Добавление FBE предоставляет vold несколько новых команд для поддержки управления ключами CE и DE для нескольких пользователей. В дополнение к основным изменениям, направленным на использование возможностей шифрования на основе файлов в ядре , многие системные пакеты, включая экран блокировки и SystemUI, были модифицированы для поддержки функций FBE и Direct Boot. К ним относятся:

  • AOSP Dialer (packages/apps/Dialer)
  • Настольные часы (пакеты/приложения/DeskClock)
  • LatinIME (packages/inputmethods/LatinIME)*
  • Приложение «Настройки» (пакеты/приложения/Настройки)*
  • SystemUI (фреймворки/база/пакеты/SystemUI)*

* Системные приложения, использующие атрибут манифеста defaultToDeviceProtectedStorage

Дополнительные примеры приложений и сервисов, поддерживающих шифрование, можно найти, выполнив команду mangrep directBootAware в каталоге `frameworks` или `packages` исходного кода AOSP.

Зависимости

Для безопасного использования реализации FBE в AOSP устройство должно соответствовать следующим зависимостям:

  • Поддержка ядром шифрования Ext4 или шифрования F2FS.
  • Поддержка KeyMint (или Keymaster 1.0 или выше) . Поддержка Keymaster 0.3 отсутствует, поскольку эта версия не предоставляет необходимых возможностей и не гарантирует достаточной защиты ключей шифрования.
  • Для защиты ключей DE необходимо использовать KeyMint/Keymaster и Gatekeeper в доверенной среде выполнения (TEE), чтобы неавторизованная ОС (пользовательская ОС, установленная на устройстве) не могла просто запросить ключи DE.
  • Для обеспечения недоступности ключей DE для неавторизованной операционной системы требуется привязка аппаратного корня доверия и проверенной загрузки к инициализации KeyMint.

Выполнение

В первую очередь, согласно документации для разработчиков Direct Boot, такие приложения, как будильники, телефон и функции специальных возможностей, должны быть адаптированы под Android:directBootAware.

Поддержка ядра

Поддержка шифрования Ext4 и F2FS в ядре Android доступна в стандартных ядрах Android версии 3.18 и выше. Чтобы включить её в ядре версии 5.1 или выше, используйте:

CONFIG_FS_ENCRYPTION=y

Для более старых версий ядра используйте CONFIG_EXT4_ENCRYPTION=y , если файловая система userdata вашего устройства — Ext4, или CONFIG_F2FS_FS_ENCRYPTION=y если файловая система userdata вашего устройства — F2FS.

Если ваше устройство поддерживает расширяемое хранилище или использует шифрование метаданных во внутренней памяти, также включите параметры конфигурации ядра, необходимые для шифрования метаданных, как описано в документации по шифрованию метаданных .

Помимо функциональной поддержки шифрования Ext4 или F2FS, производители устройств также должны включать криптографическое ускорение для ускорения шифрования файлов и улучшения пользовательского опыта. Например, на устройствах на базе ARM64 ускорение ARMv8 CE (Cryptography Extensions) можно включить, установив следующие параметры конфигурации ядра:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

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

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Если ваше устройство использует хранилище на основе UFS, также включите следующие параметры:

CONFIG_SCSI_UFS_CRYPTO=y

Если ваше устройство использует память на основе eMMC, также включите следующие параметры:

CONFIG_MMC_CRYPTO=y

Включить шифрование на основе файлов

Для включения FBE на устройстве необходимо включить его во внутренней памяти ( userdata ). Это также автоматически включает FBE на подключаемой памяти; однако формат шифрования на подключаемой памяти можно изменить при необходимости.

Внутреннее хранилище

Включение FBE осуществляется путем добавления параметра fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] в столбец fs_mgr_flags строки fstab для userdata . Этот параметр определяет формат шифрования во внутренней памяти. Он содержит до трех параметров, разделенных двоеточиями:

  • Параметр contents_encryption_mode определяет, какой криптографический алгоритм используется для шифрования содержимого файла. Это может быть либо aes-256-xts , либо adiantum . Начиная с Android 11, его также можно оставить пустым, чтобы указать алгоритм по умолчанию, которым является aes-256-xts .
  • Параметр filenames_encryption_mode определяет, какой криптографический алгоритм используется для шифрования имен файлов. Он может быть aes-256-cts , aes-256-heh , adiantum или aes-256-hctr2 . Если не указан, по умолчанию используется aes-256-cts , если contents_encryption_mode равно aes-256-xts , или adiantum , если contents_encryption_mode равно adiantum .
  • Параметр flags , появившийся в Android 11, представляет собой список флагов, разделенных знаком " + . Поддерживаются следующие флаги:
    • Флаг v1 выбирает политики шифрования версии 1; флаг v2 выбирает политики шифрования версии 2. Политики шифрования версии 2 используют более безопасную и гибкую функцию генерации ключа . По умолчанию используется версия v2, если устройство запущено на Android 11 или выше (определяется параметром ro.product.first_api_level ), или v1, если устройство запущено на Android 10 или ниже.
    • Флаг inlinecrypt_optimized выбирает формат шифрования, оптимизированный для аппаратного обеспечения встроенного шифрования, которое неэффективно обрабатывает большое количество ключей. Это достигается за счет генерации только одного ключа шифрования содержимого файла для каждого ключа CE или DE, а не по одному ключу для каждого файла. Генерация векторов инициализации (IV) корректируется соответствующим образом.
    • Флаг emmc_optimized аналогичен флагу inlinecrypt_optimized , но также выбирает метод генерации IV, ограничивающий IV 32 битами. Этот флаг следует использовать только на оборудовании для встроенного шифрования, соответствующем спецификации JEDEC eMMC v5.2 и, следовательно, поддерживающем только 32-битные IV. На другом оборудовании для встроенного шифрования используйте вместо него inlinecrypt_optimized . Этот флаг никогда не следует использовать на хранилищах на основе UFS; спецификация UFS допускает использование 64-битных IV.
    • На устройствах, поддерживающих аппаратно упакованные ключи , флаг wrappedkey_v0 включает использование аппаратно упакованных ключей для FBE. Это можно использовать только в сочетании с опцией монтирования inlinecrypt и флагом inlinecrypt_optimized или emmc_optimized .
    • Флаг dusize_4k принудительно устанавливает размер блока данных шифрования равным 4096 байтам, даже если размер блока файловой системы не равен 4096 байтам. Размер блока данных шифрования — это степень детализации шифрования содержимого файла. Этот флаг доступен начиная с Android 15. Использовать его следует только для включения аппаратного шифрования в режиме реального времени, не поддерживающего блоки данных размером более 4096 байт, на устройстве, использующем размер страницы более 4096 байт и файловую систему f2fs.

Если вы не используете аппаратное шифрование в режиме реального времени, рекомендуемая настройка для большинства устройств — fileencryption=aes-256-xts . Если вы используете аппаратное шифрование в режиме реального времени, рекомендуемая настройка для большинства устройств — fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (или эквивалентно fileencryption=::inlinecrypt_optimized ). На устройствах без какой-либо формы ускорения AES вместо AES можно использовать Adiantum , установив параметр fileencryption=adiantum .

Начиная с Android 14, AES-HCTR2 является предпочтительным режимом шифрования имен файлов для устройств с ускоренными криптографическими инструкциями. Однако AES-HCTR2 поддерживается только более новыми ядрами Android. В будущих версиях Android планируется сделать его режимом шифрования имен файлов по умолчанию. Если ваше ядро ​​поддерживает AES-HCTR2, его можно включить для шифрования имен файлов, установив параметр filenames_encryption_mode в значение aes-256-hctr2 . В простейшем случае это делается с помощью fileencryption=aes-256-xts:aes-256-hctr2 .

На устройствах, выпущенных с Android 10 и ниже, fileencryption=ice также позволяет указать режим шифрования содержимого файла FSCRYPT_MODE_PRIVATE . Этот режим не реализован в стандартных ядрах Android, но может быть реализован производителями с помощью пользовательских патчей ядра. Формат данных на диске, создаваемый в этом режиме, зависит от производителя. На устройствах, выпущенных с Android 11 и выше, этот режим больше не разрешен, и вместо него необходимо использовать стандартный формат шифрования.

По умолчанию шифрование содержимого файлов выполняется с использованием криптографического API ядра Linux. Если вы хотите использовать аппаратное шифрование в режиме реального времени, добавьте также параметр монтирования inlinecrypt . Например, полная строка fstab может выглядеть так:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Адаптируемое хранилище

Начиная с Android 9, FBE и расширяемое хранилище можно использовать одновременно.

Указание параметра fileencryption fstab для userdata также автоматически включает шифрование файловой системы (FBE) и метаданных на адаптируемом хранилище. Однако вы можете переопределить форматы шифрования файловой системы (FBE) или метаданных на адаптируемом хранилище, задав свойства в параметре PRODUCT_PROPERTY_OVERRIDES .

На устройствах, выпущенных с Android 11 или более поздней версией, используйте следующие свойства:

  • ro.crypto.volume.options (новый в Android 11) выбирает формат шифрования FBE для подключаемого хранилища. Он имеет тот же синтаксис, что и аргумент параметра fileencryption в файле fstab, и использует те же значения по умолчанию. См. рекомендации по fileencryption выше, чтобы узнать, что следует использовать в данном случае.
  • ro.crypto.volume.metadata.encryption выбирает формат шифрования метаданных для загружаемого хранилища. См. документацию по шифрованию метаданных .

На устройствах, выпущенных с Android 10 и более ранними версиями, используйте следующие параметры:

  • ro.crypto.volume.contents_mode выбирает режим шифрования содержимого. Это эквивалентно первому полю, разделённому двоеточием, параметра ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode выбирает режим шифрования имен файлов. Это эквивалентно второму полю ro.crypto.volume.options , разделенному двоеточием, за исключением того, что по умолчанию на устройствах, выпущенных с Android 10 и ниже, используется aes-256-heh . На большинстве устройств его необходимо явно изменить на aes-256-cts .
  • ro.crypto.fde_algorithm и ro.crypto.fde_sector_size определяют формат шифрования метаданных на адаптируемом хранилище. См. документацию по шифрованию метаданных .

Интеграция с KeyMint

HAL KeyMint следует запускать в рамках класса early_hal . Это связано с тем, что FBE требует, чтобы KeyMint был готов к обработке запросов на этапе загрузки post-fs-data , когда vold устанавливает начальные ключи.

Исключить каталоги

init применяет системный ключ DE ко всем каталогам верхнего уровня /data , за исключением каталогов, которые должны быть незашифрованными, таких как каталог, содержащий сам системный ключ DE, и каталоги, содержащие пользовательские каталоги CE или DE. Ключи шифрования применяются рекурсивно и не могут быть переопределены подкаталогами.

В Android 11 и более поздних версиях ключ, применяемый init к каталогам, можно контролировать с помощью аргумента encryption=<action> команды mkdir в скриптах инициализации. Возможные значения <action> описаны в файле README для языка инициализации Android .

В Android 10 init действий шифрования была жестко закодирована в следующем месте:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

В Android 9 и более ранних версиях местоположение было следующим:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Можно добавить исключения, чтобы полностью предотвратить шифрование определенных каталогов. Если вносятся подобные изменения, производитель устройства должен включить политики SELinux , предоставляющие доступ только тем приложениям, которым необходимо использовать незашифрованный каталог. Это должно исключать все ненадежные приложения.

Единственный известный допустимый вариант использования этого решения — поддержка устаревших функций OTA.

Поддержка прямой загрузки в системных приложениях

Обеспечьте поддержку прямой загрузки приложений.

Для ускорения миграции системных приложений появились два новых атрибута, которые можно установить на уровне приложения. Атрибут defaultToDeviceProtectedStorage доступен только для системных приложений. Атрибут directBootAware доступен для всех приложений.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

Атрибут directBootAware на уровне приложения — это сокращенное обозначение для всех компонентов приложения, поддерживающих шифрование.

Атрибут defaultToDeviceProtectedStorage перенаправляет местоположение хранилища приложений по умолчанию на хранилище DE вместо хранилища CE. Системные приложения, использующие этот флаг, должны тщательно проверять все данные, хранящиеся в местоположении по умолчанию, и изменять пути к конфиденциальным данным, чтобы использовать хранилище CE. Производители устройств, использующие эту опцию, должны тщательно проверять хранимые данные, чтобы убедиться, что они не содержат личной информации.

При работе в этом режиме доступны следующие системные API для явного управления контекстом, поддерживаемым хранилищем CE, при необходимости, которые эквивалентны их аналогам в режиме защиты устройства.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Поддержка нескольких пользователей

В многопользовательской среде каждый пользователь получает отдельный ключ шифрования. Каждый пользователь получает два ключа: ключ DE и ключ CE. Пользователь 0 должен сначала войти в систему устройства, поскольку он является особым пользователем. Это важно для целей администрирования устройств .

Приложения, поддерживающие криптографию, взаимодействуют между пользователями следующим образом: INTERACT_ACROSS_USERS и INTERACT_ACROSS_USERS_FULL позволяют приложению работать со всеми пользователями на устройстве. Однако эти приложения могут получить доступ только к зашифрованным с помощью CE каталогам пользователей, которые уже разблокированы.

Приложение может свободно взаимодействовать со всеми зонами DE, но разблокировка одного пользователя не означает, что разблокированы все пользователи на устройстве. Приложение должно проверять этот статус, прежде чем пытаться получить доступ к этим зонам.

Каждый идентификатор пользователя рабочего профиля также получает два ключа: DE и CE. После выполнения задания пользователь профиля разблокируется, и KeyMint (в формате TEE) может предоставить ключ TEE для этого профиля.

Обработка обновлений

Раздел восстановления не может получить доступ к защищенному DE-модулем хранилищу в разделе пользовательских данных. Настоятельно рекомендуется, чтобы устройства, поддерживающие FBE, поддерживали OTA-обновления с использованием A/B-обновлений системы . Поскольку OTA-обновление может быть выполнено во время обычной работы, нет необходимости в разделе восстановления для доступа к данным на зашифрованном диске.

При использовании устаревшего решения OTA, требующего восстановления для доступа к файлу OTA на разделе userdata :

  1. Создайте корневой каталог (например, misc_ne ) в разделе userdata .
  2. Настройте этот каталог верхнего уровня так, чтобы он не был зашифрован (см. раздел «Исключение каталогов »).
  3. Создайте каталог внутри корневого каталога для хранения OTA-пакетов.
  4. Добавьте правило SELinux и контексты файлов для управления доступом к этому каталогу и его содержимому. Только процессы или приложения, получающие обновления по воздуху (OTA), должны иметь возможность читать и записывать в этот каталог. Никакие другие приложения или процессы не должны иметь доступа к этому каталогу.

Проверка

Чтобы убедиться, что реализованная версия функции работает должным образом, сначала запустите многочисленные тесты шифрования CTS, такие как DirectBootHostTest и EncryptionTest .

Если на устройстве установлена ​​Android 11 или более поздняя версия, также запустите vts_kernel_encryption_test :

atest vts_kernel_encryption_test

или:

vts-tradefed run vts -m vts_kernel_encryption_test

Кроме того, производители устройств могут выполнить следующие ручные тесты. На устройстве с включенной функцией FBE:

  • Убедитесь, что ro.crypto.state существует.
    • Убедитесь, что ro.crypto.state зашифрован.
  • Убедитесь, что существует ro.crypto.type
    • Убедитесь, что ro.crypto.type установлен в file

Кроме того, тестировщики могут убедиться в блокировке хранилища CE до первой разблокировки устройства после загрузки. Для этого используйте сборку userdebug или eng , установите PIN-код, графический ключ или пароль для основного пользователя и перезагрузите устройство. Перед разблокировкой устройства выполните следующую команду, чтобы проверить хранилище CE основного пользователя. Если устройство использует режим Headless System User Mode (большинство автомобильных устройств), основным пользователем является пользователь 10, поэтому выполните:

adb root; adb shell ls /data/user/10

На других устройствах (большинстве устройств, не относящихся к автомобильной отрасли) основным пользователем является пользователь 0, поэтому выполните следующую команду:

adb root; adb shell ls /data/user/0

Убедитесь, что указанные имена файлов закодированы в формате Base64, что означает, что имена файлов зашифрованы и ключ для их расшифровки еще недоступен. Если имена файлов указаны в открытом виде, значит, что-то не так.

Производителям устройств также рекомендуется рассмотреть возможность запуска тестов fscrypt из основного репозитория Linux на своих устройствах или ядрах. Эти тесты являются частью набора тестов файловой системы xfstests. Однако эти тесты из основного репозитория официально не поддерживаются Android.

Детали реализации AOSP

В этом разделе подробно описана реализация AOSP и принцип работы файлового шифрования. Производителям устройств не потребуется вносить какие-либо изменения для использования файлового шифрования и прямой загрузки на своих устройствах.

шифрование fscrypt

В реализации AOSP используется шифрование "fscrypt" (поддерживаемое ext4 и f2fs) в ядре, и обычно она настроена следующим образом:

  • Шифрование содержимого файла с помощью AES-256 в режиме XTS.
  • Шифрование имен файлов с помощью AES-256 в режиме CBC-CTS

Также поддерживается шифрование Adiantum . При включении шифрования Adiantum шифруются как содержимое файлов, так и имена файлов.

fscrypt поддерживает две версии политик шифрования: версию 1 и версию 2. Версия 1 устарела, и требования CDD для устройств, запускаемых с Android 11 и выше, совместимы только с версией 2. Политики шифрования версии 2 используют HKDF-SHA512 для получения фактических ключей шифрования из ключей, предоставляемых пользовательским пространством.

Для получения дополнительной информации о fscrypt см. документацию ядра, являющуюся частью исходного кода .

Классы хранения

В таблице ниже более подробно перечислены ключи FBE и каталоги, которые они защищают:

Класс хранения Описание Справочники
Незашифрованный Каталоги в /data , которые не могут быть или не нуждаются в защите с помощью FBE. На устройствах, использующих шифрование метаданных , эти каталоги на самом деле не являются незашифрованными, а защищены ключом шифрования метаданных, эквивалентным System DE.
  • /data/apex , за исключением /data/apex/decompressed и /data/apex/ota_reserved , которые являются системными DE.
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Все каталоги, подкаталоги которых используют разные ключи FBE. Например, поскольку каждый каталог /data/user/${user_id} использует ключ для каждого пользователя, /data/user сам по себе не использует никакого ключа.
Система DE Данные, зашифрованные устройством и не привязанные к конкретному пользователю.
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Все остальные подкаталоги /data , которые в этой таблице не указаны как имеющие другой класс.
По одной загрузке Временные системные файлы, которые не должны сохраняться после перезагрузки. /data/per_boot
Пользователь CE (внутренний) Данные, зашифрованные с помощью учетных данных каждого пользователя, хранятся во внутренней памяти.
  • /data/data (псевдоним /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
Пользователь DE (внутренний) Данные, зашифрованные для каждого пользователя на устройстве, хранятся во внутренней памяти.
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Пользовательский CE (пригодный для использования) Данные, зашифрованные с помощью учетных данных каждого пользователя, хранятся на подключаемом накопителе.
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
Пользователь DE (принимаемый) Данные, зашифрованные для каждого пользователя на устройстве, хранятся в подключаемом хранилище.
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Хранение и защита ключей

Все ключи FBE управляются vold и хранятся в зашифрованном виде на диске, за исключением ключа для каждой загрузки, который вообще не хранится. В следующей таблице перечислены места хранения различных ключей FBE:

Тип ключа Ключевое местоположение Класс хранения ключевого местоположения
Ключ системы DE /data/unencrypted Незашифрованный
Внутренние ключи пользователя CE /data/misc/vold/user_keys/ce/${user_id} Система DE
Внутренние ключи пользователя DE /data/misc/vold/user_keys/de/${user_id} Система DE
Пользовательские ключи CE (принимаемые) /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Пользователь CE (внутренний)
Пользовательские DE (принимаемые) ключи /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Пользователь DE (внутренний)

Как показано в предыдущей таблице, большинство ключей FBE хранятся в каталогах, зашифрованных другим ключом FBE. Ключи нельзя разблокировать, пока не будет разблокирован класс хранения, в котором они находятся.

vold также применяет уровень шифрования ко всем ключам FBE. Каждый ключ, кроме ключей CE для внутреннего хранилища, шифруется с помощью AES-256-GCM, используя собственный ключ хранилища ключей , который не раскрывается за пределами TEE. Это гарантирует, что ключи FBE не могут быть разблокированы, если не загружена доверенная операционная система, что обеспечивается функцией Verified Boot . Также запрашивается защита от отката для ключа хранилища ключей, что позволяет безопасно удалять ключи FBE на устройствах, где KeyMint поддерживает защиту от отката. В качестве резервного варианта на случай, если защита от отката недоступна, в качестве Tag::APPLICATION_ID ключа хранилища ключей используется хеш SHA-512 из 16384 случайных байтов, хранящийся в файле secdiscardable , расположенном рядом с ключом. Все эти байты необходимо восстановить для восстановления ключа FBE.

Ключи CE для внутренней памяти получают более высокий уровень защиты, гарантирующий невозможность их разблокировки без знания либо фактора знаний экрана блокировки пользователя (LSKF) (PIN-код, графический ключ или пароль), либо защищенного токена сброса пароля , либо ключей на стороне клиента и сервера для операции возобновления работы после перезагрузки . Токены сброса пароля разрешено создавать только для рабочих профилей и полностью управляемых устройств .

Для достижения этой цели vold шифрует каждый ключ CE для внутреннего хранения, используя ключ AES-256-GCM, полученный из синтетического пароля пользователя. Синтетический пароль представляет собой неизменяемый криптографический секрет с высокой энтропией, который генерируется случайным образом для каждого пользователя. LockSettingsService в system_server управляет синтетическим паролем и способами его защиты.

Для защиты синтетического пароля с помощью LSKF, LockSettingsService сначала удлиняет LSKF, пропуская его через scrypt , целевое время выполнения составляет около 25 мс, а объем используемой памяти — около 2 МиБ. Поскольку LSKF обычно короткие, этот шаг, как правило, не обеспечивает достаточной безопасности. Основной уровень безопасности — это ограничение скорости, обеспечиваемое защищенным элементом (SE) или TEE, описанное ниже.

Если устройство использует Weaver HAL , то LockSettingsService сопоставляет растянутый LSKF с высокоэнтропийным случайным секретом, хранящимся в SE или TEE, с помощью Weaver. Затем LockSettingsService дважды шифрует синтетический пароль: сначала программным ключом, полученным из растянутого LSKF и секрета Weaver, а затем ключом хранилища ключей, не привязанным к аутентификации. Это обеспечивает ограничение скорости попыток ввода LSKF, контролируемое SE или TEE.

Если устройство не использует Weaver, то LockSettingsService вместо этого использует растянутый LSKF в качестве пароля Gatekeeper . Затем LockSettingsService дважды шифрует синтетический пароль: сначала программным ключом, полученным из растянутого LSKF и хеша файла, допускающего отмену секций, а затем ключом хранилища ключей, привязанным к регистрации Gatekeeper. Это обеспечивает ограничение скорости попыток ввода LSKF с помощью TEE.

При изменении LSKF LockSettingsService удаляет всю информацию, связанную с привязкой синтетического пароля к старому LSKF. На устройствах, поддерживающих ключи Weaver или ключи Keystore с защитой от отката, это гарантирует безопасное удаление старой привязки. По этой причине описанные здесь меры защиты применяются даже в том случае, если у пользователя нет LSKF.