Google стремится продвигать расовую справедливость для черных сообществ. Смотри как.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Полнодисковое шифрование

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

Полнодисковое шифрование было введено в Android в 4.4, но Android 5.0 представила следующие новые функции:

  • Создано быстрое шифрование, которое шифрует только используемые блоки на разделе данных, чтобы избежать первой загрузки, которая занимает много времени. Только файловые системы ext4 и f2fs в настоящее время поддерживают быстрое шифрование.
  • Добавлен флаг forceencrypt fstab для шифрования при первой загрузке.
  • Добавлена ​​поддержка шаблонов и шифрования без пароля.
  • Добавлено аппаратное хранилище ключа шифрования с использованием возможности подписи Trusted Execution Environment (TEE) (например, в TrustZone). См. Хранение зашифрованного ключа для более подробной информации.

Внимание: устройства, обновленные до Android 5.0 и затем зашифрованные, могут быть возвращены в незашифрованное состояние путем сброса заводских данных. Новые устройства Android 5.0, зашифрованные при первой загрузке, не могут быть возвращены в незашифрованное состояние.

Как работает полнодисковое шифрование Android

Полнодисковое шифрование Android основано на dm-crypt , функции ядра, которая работает на уровне блочных устройств. Из-за этого шифрование работает с Embedded MultiMediaCard ( eMMC) и аналогичными флэш-устройствами, которые представляются ядру как блочные устройства. Шифрование невозможно с YAFFS, которая напрямую взаимодействует с необработанным NAND-чипом.

Алгоритм шифрования - 128 Advanced Encryption Standard (AES) с цепочкой блоков шифрования (CBC) и ESSIV: SHA256. Главный ключ шифруется 128-битным AES через вызовы библиотеки OpenSSL. Вы должны использовать 128 или более бит для ключа (с 256 является необязательным).

Примечание: OEM-производители могут использовать 128-разрядную или более позднюю версию для шифрования главного ключа

В выпуске Android 5.0 существует четыре вида состояний шифрования:

  • дефолт
  • ШТЫРЬ
  • пароль
  • шаблон

При первой загрузке устройство создает случайно сгенерированный 128-битный мастер-ключ, а затем хэширует его с паролем по умолчанию и сохраненной солью. Пароль по умолчанию: «default_password». Однако полученный хеш также подписывается через TEE (например, TrustZone), который использует хэш подписи для шифрования главного ключа.

Вы можете найти пароль по умолчанию, определенный в файле cryptfs.cpp проекта Android с открытым исходным кодом .

Когда пользователь устанавливает PIN-код / ​​пароль или пароль на устройстве, только 128-битный ключ повторно шифруется и сохраняется. (т. е. изменения ПИН-кода / пароля / шаблона пользователя НЕ вызывают повторное шифрование пользовательских данных.) Обратите внимание, что на управляемое устройство могут распространяться ограничения ПИН-кода, шаблона или пароля.

Шифрование управляется init и vold . init вызывает vold , а vold устанавливает свойства для запуска событий в init. Другие части системы также обращают внимание на свойства для выполнения таких задач, как состояние отчета, запрос пароля или запрос сброса к заводским настройкам в случае фатальной ошибки. Для вызова функции шифрования в vold , система использует инструмент командной строки vdc «s cryptfs команда: checkpw , restart , enablecrypto , changepw , cryptocomplete , verifypw , setfield , getfield , mountdefaultencrypted , getpwtype , getpw и clearpw .

Чтобы зашифровать, расшифровать или стереть /data , /data не должны быть подключены. Однако для того, чтобы показать какой-либо пользовательский интерфейс (UI), должна быть запущена платформа, и для работы требуется /data . Для решения этой проблемы временная файловая система монтируется в /data . Это позволяет Android запрашивать пароли, показывать прогресс или предлагать стирание данных по мере необходимости. Это накладывает ограничение на то, что для переключения с временной файловой системы на файловую систему true /data система должна остановить каждый процесс с открытыми файлами во временной файловой системе и перезапустить эти процессы в файловой системе real /data . Для этого все сервисы должны быть в одной из трех групп: core , main и late_start .

  • core : никогда не выключаться после запуска.
  • main : выключите и перезапустите после ввода пароля диска.
  • late_start : не запускается до тех пор, пока /data не будут расшифрованы и смонтированы.

Чтобы инициировать эти действия, свойство vold.decrypt устанавливается в различные строки . Чтобы убить и перезапустить службы, команды init :

  • class_reset : останавливает службу, но позволяет перезапустить ее с помощью class_start.
  • class_start : class_start службу.
  • class_stop : останавливает службу и добавляет флаг SVC_DISABLED . Остановленные службы не отвечают на class_start .

Потоки

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

  • Зашифруйте ранее незашифрованное устройство:
    • forceencrypt новое устройство с помощью forceencrypt : обязательное шифрование при первой загрузке (начиная с Android L).
    • Шифрование существующего устройства: пользовательское шифрование (Android K и более ранние версии).
  • Загрузите зашифрованное устройство:
    • Запуск зашифрованного устройства без пароля: загрузка зашифрованного устройства без установленного пароля (актуально для устройств под управлением Android 5.0 и более поздних версий).
    • Запуск зашифрованного устройства с паролем: загрузка зашифрованного устройства с установленным паролем.

В дополнение к этим потокам устройство также может не шифровать /data . Каждый из потоков подробно объясняется ниже.

Зашифруйте новое устройство с помощью forceencrypt

Это нормальная первая загрузка для устройства Android 5.0.

  1. Обнаружение незашифрованной файловой системы с флагом forceencrypt

    /data не зашифрованы, но должны быть, потому что forceencrypt требует их. Размонтировать /data .

  2. Начать шифрование /data

    vold.decrypt = "trigger_encryption" запускает init.rc , что приводит к шифрованию vold /data без пароля. (Ни один не установлен, потому что это должно быть новое устройство.)

  3. Гора tmpfs

    vold монтирует tmpfs /data (используя параметры tmpfs из ro.crypto.tmpfs_options ) и устанавливает для свойства vold.encrypt_progress значение 0. vold готовит tmpfs /data для загрузки зашифрованной системы и устанавливает свойство vold.decrypt для: trigger_restart_min_framework

  4. Поднимите рамки, чтобы показать прогресс

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

  5. Когда /data зашифрованы, снять структуру

    vold устанавливает для vold.decrypt значение trigger_default_encryption которое запускает службу defaultcrypto по defaultcrypto . (Это запускает поток ниже для монтирования зашифрованных пользовательских данных по умолчанию.) trigger_default_encryption проверяет тип шифрования, чтобы увидеть, зашифрованы ли /data с паролем или без него. Поскольку устройства Android 5.0 зашифровываются при первой загрузке, пароль не должен быть установлен; поэтому мы расшифровываем и монтируем /data .

  6. Mount /data

    Затем init монтирует /data на RAMDisk tmpfs, используя параметры, которые он берет из ro.crypto.tmpfs_options , который установлен в init.rc

  7. Начать рамки

    Установите vold в значение trigger_restart_framework , которое продолжает обычный процесс загрузки.

Шифровать существующее устройство

Это то, что происходит, когда вы шифруете незашифрованное Android K или более раннее устройство, которое было перенесено в L.

Этот процесс инициируется пользователем и называется «шифрованием на месте» в коде. Когда пользователь выбирает шифрование устройства, пользовательский интерфейс гарантирует, что батарея полностью заряжена, и адаптер переменного тока подключен, поэтому для завершения процесса шифрования достаточно энергии.

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

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

Состояние устройства : установите ro.crypto.state = "unencrypted" и выполните on nonencrypted init для продолжения загрузки.

  1. Проверьте пароль

    Пользовательский интерфейс вызывает vold с помощью команды cryptfs enablecrypto inplace где passwd - пароль пользователя на экране блокировки.

  2. Снести рамки

    vold проверяет ошибки, возвращает -1, если не может зашифровать, и печатает причину в журнале. Если он может шифровать, он устанавливает для свойства vold.decrypt значение trigger_shutdown_framework . Это приводит к тому, что init.rc останавливает службы в классах late_start и main .

  3. Создать криптографический колонтитул
  4. Создать файл крошки
  5. перезагрузка
  6. Обнаружить файл крошки
  7. Начать шифрование /data

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

  8. Пока он шифруется, монтируем tmpfs

    vold монтирует tmpfs /data (используя параметры tmpfs из ro.crypto.tmpfs_options ) и устанавливает для свойства vold.encrypt_progress значение 0. vold подготавливает tmpfs /data для загрузки зашифрованной системы и устанавливает для свойства vold.decrypt значение: trigger_restart_min_framework

  9. Поднимите рамки, чтобы показать прогресс

    trigger_restart_min_framework заставляет init.rc запустить main класс сервисов. Когда платформа видит, что vold.encrypt_progress установлен в 0, она вызывает пользовательский интерфейс индикатора выполнения, который запрашивает это свойство каждые пять секунд и обновляет индикатор выполнения. Цикл шифрования обновляет vold.encrypt_progress каждый раз, когда шифрует еще один процент раздела.

  10. Когда /data зашифрованы, обновите крипто нижний колонтитул

    Когда /data успешно зашифрованы, vold сбрасывает флаг ENCRYPTION_IN_PROGRESS в метаданных.

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

    Если по какой-либо причине перезагрузка не удалась, vold устанавливает для свойства vold.encrypt_progress значение error_reboot_failed и пользовательский интерфейс должен отобразить сообщение, в котором пользователь должен нажать кнопку для перезагрузки. Этого не ожидается.

Запуск зашифрованного устройства с шифрованием по умолчанию

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

  1. Обнаружение зашифрованных /data без пароля

    Определите, что устройство Android зашифровано, потому что /data не могут быть смонтированы, и установлен один из флагов encryptable или forceencrypt .

    vold устанавливает для vold.decrypt значение trigger_default_encryption , которое запускает службу defaultcrypto по defaultcrypto . trigger_default_encryption проверяет тип шифрования, чтобы увидеть, зашифрованы ли /data с паролем или без него.

  2. Расшифровать / данные

    Создает устройство dm-crypt на блочном устройстве, чтобы оно было готово к использованию.

  3. Mount / data

    vold монтирует дешифрованный раздел real /data и затем готовит новый раздел. Он устанавливает для свойства vold.post_fs_data_done значение 0, а затем для vold.decrypt устанавливается vold.decrypt trigger_post_fs_data . Это заставляет init.rc запускать свои команды post-fs-data . Они создадут все необходимые каталоги или ссылки, а затем vold.post_fs_data_done в 1.

    Когда vold видит 1 в этом свойстве, он устанавливает для свойства vold.decrypt значение: trigger_restart_framework. Это заставляет init.rc снова запускать службы в классе main а также запускать службы в классе late_start впервые после загрузки.

  4. Начать рамки

    Теперь фреймворк загружает все свои сервисы, используя расшифрованные /data , и система готова к использованию.

Запуск зашифрованного устройства без шифрования по умолчанию

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

  1. Обнаружение зашифрованного устройства с помощью пароля

    Определите, что устройство Android зашифровано, потому что флаг ro.crypto.state = "encrypted"

    vold устанавливает vold.decrypt в trigger_restart_min_framework потому что /data шифруется паролем.

  2. Гора tmpfs

    init устанавливает пять свойств для сохранения начальных параметров монтирования, заданных для /data с параметрами, переданными из init.rc vold использует эти свойства для настройки криптографического отображения:

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (8-значный шестнадцатеричный номер ASCII, которому предшествует 0x)
  3. Запустите фреймворк, чтобы запросить пароль

    Фреймворк запускается и видит, что vold.decrypt установлен в trigger_restart_min_framework . Это говорит фреймворку, что он загружается на диск tmpfs /data и ему нужно получить пароль пользователя.

    Однако сначала нужно убедиться, что диск был правильно зашифрован. Он отправляет команду cryptfs cryptocomplete в vold . vold возвращает 0, если шифрование было успешно завершено, -1 при внутренней ошибке или -2, если шифрование не было успешно завершено. vold определяет это путем поиска в крипто-метаданных флага CRYPTO_ENCRYPTION_IN_PROGRESS . Если он установлен, процесс шифрования был прерван, и на устройстве нет доступных данных. Если vold возвращает ошибку, пользовательский интерфейс должен отобразить пользователю сообщение о перезагрузке и сбросе устройства к заводским настройкам, а также дать пользователю кнопку, чтобы сделать это.

  4. Расшифровать данные с помощью пароля

    После cryptfs cryptocomplete инфраструктура отображает пользовательский интерфейс, запрашивающий пароль диска. Пользовательский интерфейс проверяет пароль, отправляя команду cryptfs checkpw vold . Если пароль правильный (который определяется путем успешного монтирования дешифрованного /data во временном местоположении, а затем его размонтирования), vold сохраняет имя дешифрованного блочного устройства в свойстве ro.crypto.fs_crypto_blkdev и возвращает статус 0 в пользовательский интерфейс , Если пароль неверный, он возвращает -1 в пользовательский интерфейс.

  5. Стоп рамки

    Пользовательский интерфейс создает криптографическую загрузку и затем вызывает vold с помощью команды cryptfs restart . vold устанавливает для свойства vold.decrypt значение trigger_reset_main , в результате чего init.rc выполняет class_reset main . Это останавливает все службы в основном классе, что позволяет размонтировать tmpfs /data .

  6. Mount /data

    vold монтирует дешифрованный раздел real /data и подготавливает новый раздел (который, возможно, никогда не был подготовлен, если он был зашифрован с помощью опции очистки, которая не поддерживается в первом выпуске). Он устанавливает для свойства vold.post_fs_data_done значение 0, а затем для vold.decrypt устанавливается vold.decrypt trigger_post_fs_data . Это заставляет init.rc запускать свои команды post-fs-data . Они создадут все необходимые каталоги или ссылки, а затем vold.post_fs_data_done в 1. Как только vold увидит 1 в этом свойстве, он устанавливает для свойства vold.decrypt значение trigger_restart_framework . Это заставляет init.rc снова запускать службы в классе main а также запускать службы в классе late_start впервые после загрузки.

  7. Начать полный каркас

    Теперь фреймворк загружает все свои сервисы с использованием расшифрованной файловой системы /data , и система готова к использованию.

недостаточность

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

  1. Обнаружение зашифрованного устройства с помощью пароля
  2. Гора tmpfs
  3. Запустите фреймворк, чтобы запросить пароль

Но после открытия платформы устройство может столкнуться с некоторыми ошибками:

  • Пароль совпадает, но не может расшифровать данные
  • Пользователь вводит неверный пароль 30 раз

Если эти ошибки не устранены, предложите пользователю выполнить заводскую очистку :

Если vold обнаруживает ошибку во время процесса шифрования, и если данные еще не были уничтожены и инфраструктура работает, vold устанавливает для свойства vold.encrypt_progress значение error_not_encrypted . Пользовательский интерфейс предлагает пользователю перезагрузиться и предупреждает его, что процесс шифрования никогда не запускается. Если ошибка возникает после того, как структура была разрушена, но до того, как пользовательский интерфейс индикатора выполнения vold , vold перезагрузит систему. Если перезагрузка не удалась, она устанавливает vold.encrypt_progress в error_shutting_down и возвращает -1; но не будет ничего, чтобы поймать ошибку. Этого не ожидается.

Если vold обнаруживает ошибку в процессе шифрования, он устанавливает vold.encrypt_progress в error_partially_encrypted и возвращает -1. Пользовательский интерфейс должен отобразить сообщение о том, что шифрование не удалось, и предоставить пользователю кнопку сброса устройства к заводским настройкам.

Хранение зашифрованного ключа

Зашифрованный ключ хранится в крипто-метаданных. Аппаратное обеспечение реализуется с помощью возможности подписи Trusted Execution Environment (TEE). Ранее мы шифровали мастер-ключ ключом, сгенерированным путем применения scrypt к паролю пользователя и сохраненной соли. Чтобы сделать ключ устойчивым к внешним атакам, мы расширяем этот алгоритм, подписывая полученный ключ хранимым ключом TEE. Результирующая подпись затем превращается в ключ соответствующей длины еще одним приложением scrypt. Этот ключ затем используется для шифрования и дешифрования главного ключа. Чтобы сохранить этот ключ:

  1. Генерация случайного 16-байтового ключа шифрования диска (DEK) и 16-байтовой соли.
  2. Примените scrypt к паролю пользователя и соли для получения 32-байтового промежуточного ключа 1 (IK1).
  3. Дополните IK1 нулевым байтом до размера аппаратно-привязанного закрытого ключа (HBK). В частности, мы добавляем как: 00 || IK1 || 00..00; один нулевой байт, 32 байта IK1, 223 нулевых байта.
  4. Знак дополнен IK1 с HBK для получения 256-байтового IK2.
  5. Примените scrypt к IK2 и соли (та же соль, что и на шаге 2), чтобы получить 32-байтовый IK3.
  6. Используйте первые 16 байтов IK3 в качестве KEK и последние 16 байтов в качестве IV.
  7. Зашифруйте DEK с помощью AES_CBC, с ключом KEK и вектором инициализации IV.

Смена пароля

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

Свойства шифрования

vold и init общаются друг с другом, устанавливая свойства. Вот список доступных свойств для шифрования.

Vold свойства

Свойство Описание
vold.decrypt trigger_encryption Зашифруйте диск без пароля.
vold.decrypt trigger_default_encryption Проверьте диск, чтобы увидеть, если он зашифрован без пароля. Если это так, расшифруйте и смонтируйте его, иначе установите vold.decrypt в trigger_restart_min_framework.
vold.decrypt trigger_reset_main Установите vold для отключения пользовательского интерфейса, запрашивающего пароль диска.
vold.decrypt trigger_post_fs_data Установить vold для prep /data с необходимыми каталогами и др.
vold.decrypt trigger_restart_framework Установите vold для запуска реальной структуры и всех услуг.
vold.decrypt trigger_shutdown_framework Установите vold, чтобы отключить всю платформу, чтобы начать шифрование.
vold.decrypt trigger_restart_min_framework Установите vold для запуска пользовательского интерфейса индикатора выполнения для шифрования или запроса пароля, в зависимости от значения ro.crypto.state .
vold.encrypt_progress Когда платформа запускается, если это свойство установлено, войдите в режим пользовательского интерфейса индикатора выполнения.
vold.encrypt_progress 0 to 100 Пользовательский интерфейс индикатора выполнения должен отображать установленное процентное значение.
vold.encrypt_progress error_partially_encrypted Пользовательский интерфейс индикатора выполнения должен отображать сообщение о том, что шифрование не удалось, и дать пользователю возможность восстановить заводские настройки устройства.
vold.encrypt_progress error_reboot_failed Пользовательский интерфейс индикатора выполнения должен отображать сообщение о том, что шифрование завершено, и дать пользователю кнопку для перезагрузки устройства. Эта ошибка не ожидается.
vold.encrypt_progress error_not_encrypted Пользовательский интерфейс индикатора выполнения должен отображать сообщение о том, что произошла ошибка, данные не были зашифрованы или потеряны, и дать пользователю кнопку для перезагрузки системы.
vold.encrypt_progress error_shutting_down Пользовательский интерфейс индикатора выполнения не работает, поэтому неясно, кто ответит на эту ошибку. И это никогда не должно случиться.
vold.post_fs_data_done 0 Устанавливается vold непосредственно перед установкой vold.decrypt в значение trigger_post_fs_data .
vold.post_fs_data_done 1 Устанавливается init.rc или init.rc сразу после завершения задачи post-fs-data .

свойства init

Свойство Описание
ro.crypto.fs_crypto_blkdev Устанавливается командой vold checkpw для последующего использования командой vold restart .
ro.crypto.state unencrypted Установите init чтобы сказать, что эта система работает с незашифрованным /data ro.crypto.state encrypted . Установите init чтобы сказать, что эта система работает с зашифрованными /data .

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

Эти пять свойств устанавливаются init когда он пытается смонтировать /data с параметрами, переданными из init.rc vold использует их для настройки криптографического отображения.
ro.crypto.tmpfs_options Устанавливается init.rc с параметрами, которые init должен использовать при монтировании файловой системы tmpfs /data .

Начальные действия

on post-fs-data
on nonencrypted
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:vold.decrypt=trigger_encryption
on property:vold.decrypt=trigger_default_encryption