Как технически работает шифрование Marshmallow?

14

Я только что установил Marshmallow на Nexus 5 через push-обновление. Я не совсем понимаю, как работает шифрование. У меня есть хорошие технические знания о шифровании на компьютерах. Я хотел бы получить аналогичные знания об Android 6.

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

Вопросов:

  • Откуда взялся ключ дешифрования в случае шифрования без PIN-кода? Я предполагаю, что он хранится на чипе, похожем на TPM, это правильно? Если так, что мешает хакеру запросить этот ключ у чипа? Проверяет ли хэш прошивки? Что-нибудь еще? Технические детали будут высоко оценены.
  • В случае шифрования с помощью PIN-кода, используется ли PIN-код в качестве дополнительного токена для доступа к ключу дешифрования? Или процесс расшифровки работает точно так, как если бы не было PIN-кода.

TL; DL ответ:

Ключ расшифровки разблокирован со всеми следующими:

  • PIN-код (или пароль и т. Д.) Или пароль по умолчанию, если его нет
  • TEE (генератор подписи с аппаратной поддержкой, который использует ключи, которые не могут быть извлечены)
  • Соль (легкодоступная, но предотвращающая атаки радужных таблиц)
marcv81
источник
Благодарю. Хотя это относится к Lollipop, это правильный ответ, насколько я знаю. Я думал, что есть разница между M и L, потому что я не помню, чтобы я мог установить шифрование без пароля на L или был в состоянии удалить мой PIN после шифрования.
marcv81

Ответы:

15

Я цитирую руководство по Android здесь , но:

НОТА:

Источник, который я использовал, не имеет прямого отношения к Зефиру, но имеет отношение к Леденцу и выше.

TL: DR

Я просто сейчас отвечу на вопросы ОП. Технические детали будут следовать.

  1. Ключ шифрования по умолчанию исходит от аппаратного источника (микросхема, похожая на TPM) и пароля AOSP по умолчанию, определенного как default_passwordв cryptfs.cисходном файле, см. Ниже.

  2. Да, не только по умолчанию, но любой пароль превращается в ключ и хранится в микросхеме типа TPM, называемой TEE (сокращение от «Trusted Execution Environment», дополнительную информацию см. Ниже).

  3. Хакер с UART / JTAG-доступом к микросхемам на SoC устройства может технически получить доступ к ключу TEE, или пользовательское ядро ​​может передать эту информацию хакеру. Некоторые трехбуквенные агентства в теориях заговора могут, возможно, вступить в партнерские отношения с ОЕМ, чтобы эти небезопасные ядра использовались в производственных устройствах, но я бы не стал прилагать к этому много усилий. Снова, посмотрите последний раздел этого ответа для получения дополнительной информации.

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

  1. Проверка хеша (контрольной суммы) микропрограммы (называемой Google «Verified Boot» ) фактически выполняется на Lollipop и выше по умолчанию (и доступна из JellyBean 4.3 и далее) с помощью модуля ядра, который называется dm-verity. Однако это не зависит от состояния шифрования.

Источник: руководство по безопасности AOSP здесь .

  1. О процессе расшифровки системы с помощью пользовательского пароля см. Ниже. Я просто скажу вам, что пароль пользователя участвует как в создании, так и в использовании ключа шифрования.

обзор

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

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

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

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

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

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

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

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

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

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

  1. Mount / data

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

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

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

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

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

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

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

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

  1. Гора tmpfs

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

ro.crypto.fs_type

ro.crypto.fs_real_blkdev

ro.crypto.fs_mnt_point

ro.crypto.fs_options

ro.crypto.fs_flags (8-значный шестнадцатеричный номер ASCII, которому предшествует 0x)

  1. Запустите фреймворк, чтобы запросить пароль

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

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

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

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

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

  1. Стоп рамки

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

  1. Mount / data

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

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

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

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

Зашифрованный ключ хранится в крипто-метаданных. Аппаратное обеспечение реализовано с использованием возможности подписи 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.
Тамогна Чоудхури
источник
А как насчет Android N? Коллеги сделали предположение, что шифрование Android 7 слабее, потому что запуск устройства не защищен, как раньше, и, следовательно, злоумышленнику может быть проще, чем раньше, как вы думаете, это правда?
Дэвид
@ Давид, который выходит за рамки этого вопроса, пожалуйста, задайте другой вопрос об Android Nougat.
Тамогна Чоудхури
Как я могу расшифровать раздел DATA в режиме восстановления? через init.recovery. <ro.hardware> .rc
Бенни
@ Бенни, пожалуйста, задай правильный вопрос об этом
Тамогна Чоудхури