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

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

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

Все устройства, работающие под управлением Android 10 и выше, должны использовать файловое шифрование.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Зависимости

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

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

Выполнение

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

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

Поддержка ядра для шифрования Ext4 и F2FS доступна в общих ядрах 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 (расширения шифрования) можно включить, установив следующие параметры конфигурации ядра:

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 (экспериментальная версия AOSP). Этот флаг следует использовать только для включения использования встроенного оборудования шифрования, которое не поддерживает блоки данных размером более 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 является предпочтительным режимом шифрования имен файлов для устройств с инструкциями ускоренного шифрования. Однако только новые ядра Android поддерживают AES-HCTR2. В будущей версии 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 и съемное хранилище можно использовать вместе.

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

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

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

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

Keymaster HAL следует запускать как часть класса early_hal . Это связано с тем, что FBE требует, чтобы Keymaster был готов обрабатывать запросы на этапе загрузки 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. Когда рабочее задание выполнено, пользователь профиля разблокируется, и мастер ключей (в 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 основного пользователя. Если устройство использует режим пользователя безголовой системы (большинство автомобильных устройств), основным пользователем является пользователь 10, поэтому запустите:

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

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

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

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

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

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

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

шифрование fscrypt

Реализация AOSP использует шифрование «fscrypt» (поддерживается ext4 и f2fs) в ядре и обычно настроена для:

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

Также поддерживается шифрование Adiantum . Когда шифрование 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 сам по себе не использует ключ.
Система ДЭ Данные, зашифрованные устройством, не привязанные к конкретному пользователю
  • /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 (внутренние) /data/misc/vold/user_keys/de/${user_id} Система ДЭ
Пользовательские ключи 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 не могут быть разблокированы до тех пор, пока не будет загружена доверенная операционная система, как это предусмотрено проверенной загрузкой . Для ключа хранилища ключей также запрашивается сопротивление откату , что позволяет безопасно удалять ключи FBE на устройствах, где Keymaster поддерживает сопротивление откату. В качестве запасного варианта на случай, если сопротивление откату невозможно, в качестве тега идентификатора приложения ключа хранилища ключей используется хэш SHA-512 из 16384 случайных байтов, хранящийся в файле secdiscardable , хранящемся вместе с ключом. Все эти байты необходимо восстановить, чтобы восстановить ключ FBE.

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

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

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

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

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

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