В Android 7.0 и более поздних версиях поддерживается шифрование на уровне файлов. Шифрование на уровне файлов позволяет шифровать разные файлы разными ключами, которые можно разблокировать независимо друг от друга.
В этой статье рассказывается, как включить шифрование на уровне файлов на новых устройствах и как системные приложения могут использовать API прямого запуска, чтобы обеспечить пользователям максимальное удобство и безопасность.
Все устройства с Android 10 и более поздних версий должны использовать шифрование на основе файлов.
Direct Boot
Шифрование на основе файлов позволяет использовать новую функцию, представленную в Android 7.0, – прямую загрузку. Прямая загрузка позволяет зашифрованным устройствам загружаться сразу на экран блокировки. Ранее на зашифрованных устройствах с полным шифрованием дисков (FDE) пользователям нужно было вводить учетные данные, прежде чем они могли получить доступ к каким-либо данным. Это не позволяло телефону выполнять все операции, кроме самых основных. Например, не работали будильники и специальные возможности, а также нельзя было принимать звонки, кроме экстренных.
Благодаря шифрованию на уровне файлов и новым API, которые позволяют приложениям распознавать шифрование, эти приложения могут работать в ограниченном контексте. Это может произойти до того, как пользователи предоставят свои учетные данные, при этом конфиденциальная информация пользователей будет защищена.
На устройстве с поддержкой FBE каждому пользователю доступно два хранилища:
- Хранилище с шифрованием учетных данных (CE) – хранилище по умолчанию, доступное только после разблокировки устройства пользователем.
- Хранилище с шифрованием устройства (DE) – хранилище, доступное как в режиме прямой загрузки, так и после разблокировки устройства пользователем.
Такое разделение повышает безопасность рабочих профилей, поскольку позволяет защитить сразу несколько пользователей, так как шифрование больше не зависит исключительно от пароля, вводимого при загрузке.
API прямого запуска позволяет приложениям, поддерживающим шифрование, получать доступ к каждому из этих разделов. В жизненном цикле приложений произошли изменения, связанные с необходимостью уведомлять приложения, когда хранилище с шифрованием на основе учетных данных пользователя разблокируется после первого ввода учетных данных на заблокированном экране или в случае рабочего профиля после запроса на разблокировку рабочего профиля. Устройства с Android 7.0 должны поддерживать эти новые API и жизненные циклы независимо от того, реализовано ли на них шифрование на основе файлов. Без FBE хранилища DE и CE всегда разблокированы.
Полная реализация шифрования на уровне файлов в файловых системах Ext4 и F2FS доступна в Android Open Source Project (AOSP). Ее нужно включить только на устройствах, соответствующих требованиям. Производители, решившие использовать FBE, могут изучить способы оптимизации этой функции на основе используемого процессора.
Все необходимые пакеты в AOSP были обновлены для поддержки режима прямого запуска. Однако производители устройств, использующие собственные версии этих приложений, хотят быть уверены, что в пакетах, поддерживающих прямой запуск, предоставляются следующие сервисы:
- Сервисы телефонии и номеронабиратель
- Способ ввода паролей на заблокированном экране
Примеры и источник
В Android есть эталонная реализация шифрования на уровне файлов, в которой vold (system/vold) предоставляет функции для управления устройствами хранения данных и томами. Добавление FBE предоставляет vold несколько новых команд для поддержки управления ключами CE и DE нескольких пользователей. Помимо основных изменений, связанных с использованием возможностей шифрования на основе файлов в ядре, многие системные пакеты, в том числе экран блокировки и SystemUI, были изменены для поддержки функций FBE и прямого запуска. Вот некоторые из них:
- AOSP Dialer (packages/apps/Dialer)
- Desk Clock (packages/apps/DeskClock)
- LatinIME (packages/inputmethods/LatinIME)*
- Приложение "Настройки" (packages/apps/Settings)*
- SystemUI (frameworks/base/packages/SystemUI)*
* Системные приложения, использующие атрибут манифеста defaultToDeviceProtectedStorage.
Чтобы найти другие примеры приложений и сервисов, поддерживающих шифрование, выполните команду mangrep directBootAware в каталоге frameworks или packages дерева исходного кода AOSP.
Связанные запросы
Чтобы безопасно использовать реализацию FBE в AOSP, устройство должно соответствовать следующим требованиям:
- Поддержка ядра для шифрования Ext4 или F2FS.
- KeyMint (или Keymaster 1.0 или более поздней версии) Поддержка. Keymaster 0.3 не поддерживается, поскольку не предоставляет необходимых возможностей и не обеспечивает достаточную защиту ключей шифрования.
- KeyMint/Keymaster и Gatekeeper должны быть реализованы в доверенной среде выполнения (TEE), чтобы защитить ключи DE от несанкционированного доступа со стороны ОС, например кастомной прошивки.
- Чтобы ключи DE были недоступны для неавторизованной операционной системы, требуется аппаратный корень доверия и проверка при запуске, связанные с инициализацией KeyMint.
Реализация
В первую очередь атрибут 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 (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
Включить шифрование на уровне файлов
Чтобы включить шифрование на основе файлов на устройстве, необходимо включить его на внутреннем хранилище (userdata). При этом шифрование на основе файлов автоматически включается и на переносимом хранилище, но при необходимости формат шифрования на переносимом хранилище можно переопределить.
Внутренняя память
Чтобы включить 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 используется более безопасная и гибкая функция формирования ключа. По умолчанию используется версия 2, если устройство было выпущено с Android 11 или более поздней версией (определяется по значениюro.product.first_api_level), или версия 1, если устройство было выпущено с Android 10 или более ранней версией. - Флаг
inlinecrypt_optimizedвыбирает формат шифрования, оптимизированный для аппаратного обеспечения, которое не может эффективно обрабатывать большое количество ключей. Для этого он получает только один ключ шифрования содержимого файла на каждый ключ CE или DE, а не на каждый файл. Генерация векторов инициализации (IV) корректируется соответствующим образом. - Флаг
emmc_optimizedпохож наinlinecrypt_optimized, но он также выбирает метод генерации IV, который ограничивает IV до 32 бит. Этот флаг следует использовать только на оборудовании для встроенного шифрования, которое соответствует спецификации JEDEC eMMC v5.2 и поэтому поддерживает только 32-битные векторы инициализации. На другом оборудовании для встроенного шифрования используйтеinlinecrypt_optimized. Этот флаг никогда не следует использовать для хранилища на основе UFS, поскольку спецификация UFS допускает использование 64-битных векторов инициализации. - На устройствах, поддерживающих аппаратные встроенные ключи шифрования, ключи FBE можно сделать аппаратными, добавив флаг
wrappedkeyилиwrappedkey_v0.wrappedkey– это современная версия, аwrappedkey_v0следует использовать только на устройствах, которые не поддерживаютwrappedkeyили уже запущены сwrappedkey_v0. Подробнее о том, как включить ключи, обернутые в контейнер… - Флаг
dusize_4kпринудительно устанавливает размер блока данных шифрования равным 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 на внедряемом накопителе, задав свойства в файле PRODUCT_PROPERTY_OVERRIDES.
На устройствах с Android 11 или более поздней версии используйте следующие свойства:
ro.crypto.volume.options(новое в Android 11) выбирает формат шифрования FBE на внедряемом накопителе. Синтаксис и значения по умолчанию такие же, как у аргумента параметра fstabfileencryption. Рекомендации по использованию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.
Это связано с тем, что для шифрования на основе файлов требуется, чтобы KeyMint был готов обрабатывать запросы на этапе загрузки post-fs-data, когда vold настраивает начальные ключи.
Exclude directories (Исключить каталоги)
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, которые позволяют при необходимости управлять контекстом, поддерживаемым хранилищем с шифрованием на основе учетных данных. Эти API эквивалентны API, защищенным на уровне устройства.
Context.createCredentialProtectedStorageContext()Context.isCredentialProtectedStorage()
Поддержка нескольких пользователей
В многопользовательской среде каждый пользователь получает отдельный ключ шифрования. Каждый пользователь получает два ключа: DE и CE. Пользователь 0 должен войти на устройство первым, так как это особый пользователь. Это важно для администрирования устройств.
Приложения, работающие с криптографией, взаимодействуют с аккаунтами пользователей следующим образом:
INTERACT_ACROSS_USERS и INTERACT_ACROSS_USERS_FULL
позволяют приложению выполнять действия в аккаунтах всех пользователей на устройстве. Однако такие приложения могут получить доступ только к каталогам, зашифрованным с помощью CE, для пользователей, которые уже разблокированы.
Приложение может свободно взаимодействовать с областями DE, но разблокировка одного пользователя не означает, что разблокированы все пользователи на устройстве. Приложение должно проверять этот статус перед попыткой доступа к этим областям.
Каждому идентификатору пользователя рабочего профиля также назначаются два ключа: DE и CE. Когда пользователь проходит проверку, профиль разблокируется, а KeyMint (в TEE) может предоставить ключ TEE профиля.
Как обрабатывать обновления
Раздел восстановления не может получить доступ к защищенному шифрованием хранилищу в разделе userdata. Устройствам с шифрованием на основе файлов настоятельно рекомендуется поддерживать OTA с помощью обновлений системы A/B. Поскольку обновление по беспроводной сети можно применить в обычном режиме, для доступа к данным на зашифрованном диске не требуется восстановление.
При использовании устаревшего решения для беспроводного обновления, которое требует восстановления для доступа к файлу обновления в разделе userdata:
- Создайте каталог верхнего уровня (например,
misc_ne) в разделеuserdata. - Настройте этот каталог верхнего уровня так, чтобы он не шифровался (см. раздел Исключение каталогов).
- Создайте каталог в каталоге верхнего уровня для хранения пакетов OTA.
- Добавьте правило SELinux и контексты файлов, чтобы контролировать доступ к этому каталогу и его содержимому. Доступ на чтение и запись в этом каталоге должен быть только у процессов и приложений, получающих беспроводные обновления. Никакое другое приложение или процесс не должны иметь доступа к этому каталогу.
Проверка
Чтобы убедиться, что реализованная версия функции работает правильно, сначала запустите многочисленные тесты шифрования CTS, такие как DirectBootHostTest и EncryptionTest.
Если на устройстве установлена ОС Android 11 или более поздней версии, также запустите тест vts_kernel_encryption_test:
atest vts_kernel_encryption_test
или:
vts-tradefed run vts -m vts_kernel_encryption_test
Кроме того, производители устройств могут выполнять следующие тесты вручную. На устройстве с шифрованием на основе файлов:
- Убедитесь, что
ro.crypto.stateсуществует.- Убедитесь, что
ro.crypto.stateзашифровано
- Убедитесь, что
- Проверьте, существует ли устройство
ro.crypto.type.- Убедитесь, что для параметра
ro.crypto.typeзадано значениеfile.
- Убедитесь, что для параметра
Кроме того, тестировщики могут проверить, заблокировано ли хранилище с шифрованием на уровне пользователя до первой разблокировки устройства после загрузки. Для этого используйте сборку userdebug или eng, установите PIN-код, графический ключ или пароль для основного пользователя и перезагрузите устройство. Прежде чем разблокировать устройство, выполните следующую команду, чтобы проверить хранилище CE основного пользователя. Если на устройстве используется режим консольного системного пользователя (как на большинстве устройств Android Automotive), основным пользователем является пользователь 10. Выполните следующую команду:
adb root; adb shell ls /data/user/10
На других устройствах (большинство устройств, не относящихся к Automotive) основным пользователем является пользователь 0, поэтому выполните следующую команду:
adb root; adb shell ls /data/user/0
Убедитесь, что перечисленные имена файлов закодированы в Base64. Это означает, что имена файлов зашифрованы и ключ для их расшифровки пока недоступен. Если названия файлов указаны в виде обычного текста, значит что-то не так.
Производителям устройств также рекомендуется запустить тесты Linux для fscrypt на своих устройствах или ядрах. Эти тесты входят в набор тестов файловой системы xfstests. Однако эти тесты официально не поддерживаются Android.
Сведения о реализации в AOSP
В этом разделе рассказывается о реализации AOSP и о том, как работает шифрование на основе файлов. Производителям устройств не нужно вносить изменения в этот код, чтобы использовать шифрование на основе файлов и прямую загрузку.
Шифрование 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. |
|
| Системный DE | Зашифрованные на устройстве данные, не связанные с определенным пользователем |
|
| При каждой загрузке | Временные системные файлы, которые не нужно сохранять после перезагрузки. | /data/per_boot |
| Пользователь CE (внутренний) | Данные, зашифрованные с помощью учетных данных пользователя, во внутреннем хранилище |
|
| Пользователь DE (внутренний) | Зашифрованные данные на внутреннем хранилище для каждого пользователя |
|
| Пользовательское расширение (адаптируемое) | Данные, зашифрованные с помощью учетных данных пользователя, на внедряемом накопителе |
|
| Пользователь из Германии (переносимое хранилище) | Зашифрованные данные на переносимом накопителе для каждого пользователя |
|
Хранение и защита ключей
Все ключи FBE управляются vold и хранятся на диске в зашифрованном виде, за исключением ключа, который создается при каждой загрузке и не сохраняется. В таблице ниже указано, где хранятся различные ключи FBE.
| Тип ключа | Местоположение ключа | Класс хранилища местоположения ключа |
|---|---|---|
| Системный ключ шифрования данных | /data/unencrypted |
Не зашифровано |
| Ключи шифрования на стороне клиента для пользователей (внутренние) | /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 (внутренний) |
| Ключи шифрования данных пользователя (адаптируемые) | /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} |
Пользователь DE (внутренний) |
Как показано в таблице выше, большинство ключей FBE хранятся в каталогах, зашифрованных другим ключом FBE. Ключи нельзя разблокировать, пока не будет разблокирован класс хранилища, в котором они находятся.
vold также применяет уровень шифрования ко всем ключам FBE. Все ключи, кроме ключей CE для внутренней памяти, шифруются с помощью AES-256-GCM и собственного ключа Keystore, который не передается за пределы TEE. Это гарантирует, что ключи FBE нельзя разблокировать, пока не будет загружена доверенная операционная система, как это предусмотрено проверкой при запуске. Для ключа Keystore также запрашивается защита от отката, что позволяет безопасно удалять ключи FBE на устройствах, где KeyMint поддерживает защиту от отката. Если защита от отката недоступна, в качестве Tag::APPLICATION_ID ключа Keystore используется хеш SHA-512, состоящий из 16 384 случайных байтов, которые хранятся в файле secdiscardable вместе с ключом. Чтобы восстановить ключ FBE, нужно восстановить все эти байты.
Ключи CE для внутренней памяти получают более высокий уровень защиты, который гарантирует, что их нельзя разблокировать, не зная фактора знания заблокированного экрана (LSKF) пользователя (PIN-кода, графического ключа или пароля), токена безопасного сброса пароля или ключей на стороне клиента и сервера для операции возобновления работы после перезагрузки. Токены сброса кода доступа можно создавать только для рабочих профилей и полностью управляемых устройств.
Для этого vold шифрует каждый ключ CE для внутренней памяти, используя ключ AES-256-GCM, полученный из синтетического пароля пользователя.
Синтетический пароль – это неизменяемый криптографический секрет с высокой энтропией, который генерируется случайным образом для каждого пользователя. LockSettingsService в system_server управляет синтетическим паролем и способами его защиты.
Чтобы защитить синтетический пароль с помощью LSKF,
LockSettingsService сначала растягивает LSKF, пропуская его через
scrypt, чтобы время выполнения составило примерно 25 мс, а объем используемой памяти – около 2 МБ. Поскольку ключи блокировки экрана обычно короткие, этот шаг не обеспечивает высокую безопасность. Основной уровень безопасности – это элемент безопасности (SE) или ограничение частоты запросов, применяемое доверенной средой выполнения (TEE), как описано ниже.
Если на устройстве реализован Weaver HAL, то LockSettingsService сопоставляет растянутый LSKF с высокоэнтропийным случайным секретом, хранящимся в SE или TEE, с помощью Weaver.
LockSettingsService дважды шифрует синтетический пароль:
сначала с помощью программного ключа, полученного из растянутого LSKF и секрета Weaver, а затем с помощью ключа Keystore, не связанного с аутентификацией. Это позволяет SE или TEE ограничивать количество попыток угадать LSKF.
Если устройство не поддерживает Weaver, LockSettingsService использует растянутый LSKF в качестве пароля Gatekeeper. Затем LockSettingsService дважды шифрует синтетический пароль: сначала с помощью программного ключа, полученного из растянутого LSKF и хеша файла secdiscardable, а затем с помощью ключа Keystore, который привязан к регистрации Gatekeeper. Это позволяет ограничить частоту попыток угадать ключ блокировки экрана, применяя доверенную среду выполнения.
При изменении LSKF LockSettingsService удаляет всю информацию, связанную с привязкой синтетического пароля к старому LSKF. На устройствах, поддерживающих Weaver или ключи Keystore, устойчивые к откату, это гарантирует безопасное удаление старой привязки. Поэтому описанные здесь меры защиты применяются, даже если у пользователя нет LSKF.