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

Полнодисковое шифрование - это процесс кодирования всех пользовательских данных на устройстве 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), который использует хэш подписи для шифрования главного ключа.

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

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

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

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

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

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

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

Потоки

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

  • Зашифруйте ранее незашифрованное устройство:
    • Шифровать новое устройство с 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 prepepares в TMPFS /data для загрузки зашифрованной системы и устанавливает свойство vold.decrypt в: trigger_restart_min_framework

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

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

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

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

  6. Mount /data

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

  7. Начать фреймворк

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

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

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

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

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

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

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

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

    UI вызывает 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, то появляется строка прогресса UI, который запрашивает , что собственность каждые пять секунд и обновляет индикатор выполнения. Обновления цикла шифрования 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 службы. trigger_default_encryption проверяет тип шифрования , чтобы увидеть , если /data шифруются с или без пароля.

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

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

  3. Крепление / данные

    vold затем монтирует расшифрованы реальные /data раздела , а затем готовит новый раздел. Он устанавливает свойство vold.post_fs_data_done к 0 , а затем устанавливает 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 , и система готова к использованию.

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

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

  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 (ASCII - 8-значное шестнадцатеричное число предшествует 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 успешно, каркасные отображает пользовательский интерфейс с запросом пароля диска. Чеки UI пароль, отправив команду cryptfs checkpw в vold . Если пароль правильный (который определяется успешно монтаж расшифрованных /data во временном месте, то размонтирования), vold сохраняет имя расшифрованного блока устройства в свойстве ro.crypto.fs_crypto_blkdev и возвращает статус 0 в пользовательский интерфейс . Если пароль неверен, он возвращает -1 в пользовательский интерфейс.

  5. Остановить фреймворк

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

  6. Mount /data

    vold затем монтирует расшифрован реальные /data раздела и готовит новый раздел (который может никогда не был подготовлен , если он был зашифрован с салфеткой варианта, который не поддерживается на первом выпуске). Он устанавливает свойство vold.post_fs_data_done к 0 , а затем устанавливает 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 . Пользовательский интерфейс предлагает пользователю перезагрузиться и предупреждает о том, что процесс шифрования никогда не запускался. Если ошибка возникает после того , как структура была снесена, но до того , как бар UI прогресса вверх, 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 для приготовительных /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 .

свойства инициализации

Имущество Описание
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 с параметрами инициализации следует использовать при монтаже 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