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

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

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

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

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

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

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

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

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

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

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

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

  • Услуги телефонии и номеронабиратель
  • Метод ввода для ввода паролей на экран блокировки

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

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

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

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

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

Зависимости

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

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

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

Выполнение

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

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

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

CONFIG_FS_ENCRYPTION=y

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

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

В дополнение к функциональной поддержке шифрования 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 . Этот параметр определяет формат шифрования во внутренней памяти. Он содержит до трех параметров, разделенных двоеточием:

  • Параметр content_encryption_mode определяет, какой криптографический алгоритм используется для шифрования contents_encryption_mode файла. Это может быть как aes-256-xts adiantum адиантум. Начиная с Android 11 его также можно оставить пустым, чтобы указать алгоритм по умолчанию, то есть aes-256-xts .
  • Параметр filenames_encryption_mode определяет, какой криптографический алгоритм используется для шифрования имен файлов. Это может быть как aes-256-cts , aes-256-heh , так и adiantum . Если не указано, по умолчанию используется 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 ), или 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 .

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

На устройствах, запущенных с 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 выбирают формат шифрования метаданных в приемлемом хранилище. См. документацию по шифрованию метаданных .

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

Генерация ключей и управление связкой ключей ядра осуществляется vold . Реализация AOSP FBE требует, чтобы устройство поддерживало Keymaster HAL версии 1.0 или более поздней. Более ранние версии Keymaster HAL не поддерживаются.

При первой загрузке ключи пользователя 0 генерируются и устанавливаются в начале процесса загрузки. К моменту завершения фазы init on-post-fs Keymaster должен быть готов к обработке запросов. На устройствах Pixel это решается блоком скрипта, гарантирующим запуск Keymaster до монтирования /data .

Политика шифрования

Шифрование на основе файлов применяет политику шифрования на уровне каталога. При первом создании раздела пользовательских данных устройства userdata init применяют базовые структуры и политики. Эти сценарии инициируют создание ключей CE и DE первого пользователя (пользователя 0), а также определяют, какие каталоги должны быть зашифрованы с помощью этих ключей. При создании дополнительных пользователей и профилей необходимые дополнительные ключи генерируются и сохраняются в хранилище ключей; создаются места хранения их учетных данных и устройств, и политика шифрования связывает эти ключи с этими каталогами.

В Android 11 и более поздних версиях политика шифрования больше не жестко запрограммирована в централизованном расположении, а определяется аргументами команд mkdir в сценариях инициализации. Для каталогов, зашифрованных системным ключом DE, используется encryption=Require , а для незашифрованных каталогов (или каталогов, подкаталоги которых зашифрованы ключами для каждого пользователя) используется encryption=None .

В Android 10 политика шифрования была жестко закодирована в этом месте:

/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, которое требует восстановления для доступа к файлу 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

Кроме того, тестировщики могут загружать экземпляр userdebug с экраном блокировки, установленным для основного пользователя. Затем adb shell к устройству и используйте su , чтобы стать пользователем root. Убедитесь, что /data/data содержит зашифрованные имена файлов; если это не так, что-то не так.

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

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

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

шифрование fscrypt

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

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

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

Дополнительные сведения о fscrypt см. в документации ядра основной ветки разработки.

Вывод ключа

Ключи шифрования на основе файлов, которые представляют собой 512-битные ключи, хранятся в зашифрованном виде с помощью другого ключа (256-битного ключа AES-GCM), хранящегося в TEE. Чтобы использовать этот ключ TEE, необходимо выполнить три требования:

  • Токен авторизации
  • Растянутые учетные данные
  • «Секундный хэш»

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

Растянутые учетные данные — это учетные данные пользователя после добавления соли и растяжения с помощью алгоритма scrypt . Учетные данные на самом деле один раз хэшируются в службе настроек блокировки, прежде чем они будут переданы в vold для передачи в scrypt . Это криптографически связано с ключом в TEE со всеми гарантиями, применимыми к KM_TAG_APPLICATION_ID . Если у пользователя нет учетных данных, то расширенные учетные данные не используются и не требуются.

secdiscardable hash — это 512-битный хэш случайного файла размером 16 КБ, хранящийся вместе с другой информацией, используемой для восстановления ключа, например начальным числом. Этот файл надежно удаляется при удалении ключа, либо шифруется по-новому; эта дополнительная защита гарантирует, что злоумышленник должен восстановить каждый бит этого безопасно удаленного файла, чтобы восстановить ключ. Это криптографически связано с ключом в TEE со всеми гарантиями, применимыми к KM_TAG_APPLICATION_ID .

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