Содержание статьи
WARNING
Экосистема Android — это зоопарк аппаратных платформ, прошивок и версий, в каждой из которых есть свои существенные отличия. Статья описывает лишь общие принципы шифрования, реализованные Google в самой ОС.
Полнодисковое шифрование (FDE)
Впервые полнодисковое шифрование (full disk encryption — FDE) пытались внедрить еще в планшетной версии Android 3.0 Honeycomb. Тогда вместе с ядром Linux 2.6.36 в ней появился модуль dm-crypt, обеспечивающий возможность шифрования на любом блочном устройстве хранения данных (включая NAND Flash). В универсальной четвертой версии Android шифрование также было доступно, однако для большинства оно оставалось невостребованной опцией. Из-за отсутствия программных оптимизаций и низкой скорости встраиваемых процессоров того времени включение шифрования приводило к падению производительности ввода-вывода в 6–8 раз на топовых моделях и до 20 раз на бюджетных.
Исправить ситуацию удалось только с появлением 64-битных процессоров, имеющих отдельный набор инструкций для ускорения криптографических вычислений. Поэтому обязательным шифрование в Android стало только с версии 5.0, предустанавливаемой на устройства с современными однокристальными системами.
Именно в пятой версии Андроида появился флаг forceencrypt fstab, указывающий на необходимость активации шифрования при первом включении устройства. Обрати внимание: есть принципиальная разница между тем, было ли устройство обновлено до Android 5.x или новее либо сразу выпускалось с такой версией. Во втором случае шифрование данных будет выполняться всегда. В первом варианте (при обновлении) оно останется опциональным и может быть отключено сбросом до заводских настроек (factory reset).
В общем случае для полнодискового шифрования в Android используются три битовые последовательности: мастер-ключ, соль и пользовательский пин-код. Мастер-ключ и соль генерируются автоматически, а пин-код вводится владельцем устройства. Роль пин-кода может также выполнять пароль, графический ключ или любой другой «секрет» — для процессора это все равно битовая последовательность, причем довольно короткая.
Стойкий пароль шифрования
Большинство пользователей задает короткий пароль на смартфоне или планшете, поскольку им часто приходится его вводить. Проблема в том, что в Android используется один пароль для всех операций, включая разблокировку экрана и расшифровку данных. Приложение EncPassChanger позволяет установить раздельные пароли и повысить криптостойкость схемы хранения мастер-ключа, которым шифруются данные пользователя. Приложение работает на Android 4.0.3 и выше (требуется root).
Пользовательские данные шифруются мастер-ключом, а соль и пин-код служат только для того, чтобы хранить сам мастер-ключ в зашифрованном виде. Поэтому смена пароля не приводит к перешифровке всех данных. Ключ всегда остается один и тот же (сгенерированный изначально), а новый пароль лишь меняет его криптографическую оболочку. Разберем эту схему подробнее.
При первом включении устройство с предустановленной ОС Android 5.0 и выше генерирует псевдослучайный 128-разрядный ключ. Его называют мастер-ключом, или DEK (device encryption key). Помимо DEK, также генерируется еще одно псевдослучайное 128-битное число (соль), а пользователя просят ввести пароль.
Именно с помощью DEK в конечном счете шифруются все данные на пользовательском разделе /data. Как именно выглядит этот ключ, владелец устройства не знает. Он никогда не вводит его и даже не может считать штатными средствами.
В ранних версиях Android (до 5.0) мастер-ключ и настройки шифрования хранились в отдельной незашифрованной структуре crypto footer (упрощенный аналог LUKS) в начале зашифрованного раздела data. Сам DEX шифровался другим ключом, вычисляемым на основе пользовательского пароля и соли.
Такой способ не обеспечивал защиту от брутфорса мастер-ключа на внешних вычислительных системах, поэтому в Android 5.0 и выше появилось новое требование к производителям устройств: предоставлять на аппаратном уровне защищенное хранилище ключей. Дополнительно DEK стал подписываться с использованием еще одного ключа (HBK — hardware-bound private key), специфичного для данного устройства. Он захардкожен на этапе производства и не доступен ни одному пользовательскому процессу.
Как работает FDE
Поэтапно схема создания ключей для шифрования пользовательских данных в Android 5.0 и выше выглядит так:
- Гаджет при первом включении генерирует два числа длиной 128 бит. В дальнейшем они используются как мастер-ключ и соль.
- Пользователя просят задать пароль.
- На основе введенного пароля функция scrypt запускает формирование первого промежуточного ключа (IK1) длиной 256 бит.
- IK1 дополняется нулями так, чтобы соответствовать по длине аппаратному ключу HBK.
- Модифицированный ключ IK1 подписывается ключом HBK.
- Подписанный ключ IK1 используется как второй промежуточный ключ (IK2).
- Функция scrypt запускает формирование третьего промежуточного ключа (IK3), используя для его генерации IK2 и соль как входные аргументы.
- Первые 128 бит IK3 используются как KEK (key encryption key — ключ шифрования мастер-ключа).
- Мастер-ключ шифруется ключом KEK по алгоритму AES в режиме сцепления блоков шифртекста (CBC). Поскольку в данном режиме одинаковые исходные блоки дают одинаковый шифртекст, для затруднения атаки на основе подобранного шифртекста в качестве данных первого блока используется случайная последовательность (вектор инициализации).
- Зашифрованный мастер-ключ сохраняется в аппаратно изолированной области.
Мастер-ключ используется для шифрования всего содержимого пользовательского раздела во встроенной памяти устройства. Для каждого сектора генерируется свой вектор инициализации с солью и указанием номера сектора (ESSIV). При вводе пользовательского пароля мастер-ключ расшифровывается, и далее пользовательские данные автоматически расшифровываются в фоне.
Недоступность всех ключей для прямого считывания (например, запущенным на устройстве скриптом) обеспечивается их обработкой только внутри изолированной доверенной среды исполнения (trusted execution environment — TEE). В процессорах архитектуры ARM роль TEE выполняет TrustZone, которая обеспечивает контроль целостности данных, их защищенное хранение и изолированное выполнение кода. В ней же хранятся и промежуточные значения, вычисляемые функцией формирования ключа.
Как хранение ключа, так и все ключевые криптографические процедуры в современных версиях Android должны выполняться в изолированной среде, недоступной пользователю и приложениям. На практике же это условие соблюдается не всегда, поскольку Android работает на совершенно разных платформах. Концептуально их три: ARM, Intel x86 и MIPS. В каждой из них есть свои архитектурные ветвления, которые добавляют путаницы. Более того, на базе одних и тех же ядер (например, ARM Cortex-A53) каждый производитель, обладающий лицензией на архитектуру (architectural license), может сделать свою версию однокристальной системы с любыми нестандартными свойствами.
Именно из-за такого разнообразия платформ Google до сих пор не может обеспечить единый фундамент для шифрования, как это сделала Apple еще в 2013 году (см. Secure Enclave). Сегодня в устройствах под управлением Android либо защищенного хранилища ключей нет вовсе, либо оно не имеет надежной реализации.
Например, в чипах Qualcomm Snapdragon используется собственная реализация аппаратно изолированного окружения — QSEE (Qualcomm secure execution environment). В нем запускаются доверенные обработчики (trustlets), включая модуль обработки ключей (KeyMaster). Как показал этим летом Гэл Беньямини (Gal Beniamini), в QSEE по факту нет полной аппаратной изоляции. Атакующий может запустить свой код в пространстве QSEE. При этом он станет доверенным и автоматически повысит привилегии, после чего сможет считать через KeyMaster как зашифрованный мастер-ключ, так и захардкоженный ключ HBK.
Беньямини опубликовал скрипт для извлечения ключей с устройств на базе Qualcomm Snapdragon и дальнейшие инструкции по подбору пользовательского пароля перебором. Брутфорс не представляет сложности, так как у основной массы пользователей короткие пароли. Поскольку атака перебором выполняется не на смартфоне, а на любом компьютере с помощью скрипта, встроенные средства защиты от брутфорса оказываются бессильны. При внешнем брутфорсе не возникает ни проблем с принудительными задержками, ни риска стирания данных после N неудачных попыток.
Использовать же длинный комплексный пароль на практике слишком неудобно. Можно придумать сколь угодно сложный, но представь, что при каждой разблокировке экрана придется вводить эту абракадабру. Аутентификация по отпечатку или распознаванию лица мало меняет ситуацию, поскольку это лишь дополнительные способы авторизации, созданные для удобства. В любом случае ключ DEK будет зашифрован каким-то коротким битовым набором.
Сказанное выше не означает, что калифорнийский разработчик однокристалок так уж плох. Просто продукция Qualcomm чаще подвергается стороннему аудиту. В устройствах с другими SoC дела обстоят не лучше. В частности, уязвимость доверенной среды исполнения (TEE) в однокристалках HiSilicon подробно разбиралась на прошлогодней конференции Black Hat.
Недостатки полнодискового шифрования известны давно. Применительно к Android и dm-crypt я бы выделил следующие принципиальные моменты:
- FDE работает на уровне секторов, а значит, совместимо только с дисковыми файловыми системами. JFFS2, YAFFS и другие работающие напрямую с чипами NAND ФС остаются в стороне.
- Посекторное шифрование сводит на нет все оптимизации, реализованные на уровне драйверов файловых систем. Множество приложений постоянно пишут логи и считывают свои данные. Это приводит к тому, что устройство практически непрерывно расшифровывает секторы и зашифровывает их вновь, модифицируя содержимое раздела. Поэтому FDE всегда приводит к заметному падению производительности и сокращению времени автономной работы устройства.
- FDE не поддерживает проверку подлинности содержимого секторов. Их слишком много, и среди них время от времени появляются сбойные, переназначаемые контроллером в резервную область.
- Криптографическая схема AES-CBC-ESSIV считается уязвимой к утечке данных, так как допускает определение точки их изменения. Она позволяет выполнять атаки по типу подмены и перемещения.
- FDE окажется совершенно бесполезно, если ты лишишься устройства в тот момент, когда оно будет разблокировано.
К счастью, полнодисковое шифрование не единственный вариант защиты данных в Android.
Пофайловое шифрование (FBE)
В Android 7.0 появилась принципиально новая функция — пофайловое шифрование (file based encryption — FBE), которое выполняется с использованием возможностей файловой системы ext4. Новая реализация шифрования требует наличия аппаратно изолированной среды (trusted execution environment) с поддержкой API Keymaster 1.0 (старые версии 0.xx не годятся). Выполнение алгоритма AES процессором должно обеспечивать расшифровку данных со скоростью не менее 50 Мбайт/с. Это довольно жесткие требования, поэтому поддержку Android 7.x пока имеют единичные устройства.
Аппаратная поддержка шифрования
С задачей фонового шифрования в Android гарантированно справляются только новые однокристалки с TrustZone и 64-разрядными процессорами архитектуры ARMv8-A. Крайне желательно, чтобы их техпроцесс был меньше 28 нм, иначе существенный нагрев и снижение времени автономной работы станут очень заметны.
Если не останавливаться на специфических однокристалках вроде Nvidia Tegra Parker (четыре ядра Cortex-A57) и процессорах 2014–2015 года от Intel (Atom Z3560, Z3570, Z3580, Z3590, архитектура x86-64), то в сухом остатке имеем следующие чипы:
- Qualcomm Snapdragon 625 (MSM8953), 820 (MSM8996) и 821 (MSM8996 Pro);
- Samsung Exynos 7420, 7570, 7870 и 8890;
- MediaTek Helio X20(MT6797), X25 (MT6797T) и X30;
- HiSilicon Kirin 650, 950, 955 и 960.
Все они построены на базе 4–8 ядер ARM Cortex-A53 с опциональным дополнением в виде 2–4 более мощных ядер Cortex-A57/A72/A73 или их фирменных модификаций (Qualcomm Kyro, Samsung Mongoose).
Последние версии Android могут работать и на некоторых других процессорах, однако в таком случае придется сильно жертвовать либо скоростью, либо продолжительностью работы от одной зарядки. Большинство же других старых однокристалок в принципе не удовлетворяют минимальным системным требованиям ОС Android 5.1 и выше. Поэтому смартфоны и планшеты с ними больше не получат обновлений — это не только маркетинговое решение.
При использовании FBE каждый файл может быть зашифрован своим ключом и расшифрован независимо от остальных. Эта функция работает вместе с другой новинкой седьмого «Андроида» — прямой загрузкой (Direct Boot).
Direct Boot API обеспечивает более деликатное отделение приватных данных от прочих файлов. Он предоставляет ту функциональность, которая была недоступна при использовании полнодискового шифрования.
До появления Android 7.0 при активации FDE все данные хранились зашифрованными общим паролем, поэтому смартфоном невозможно было пользоваться до ввода пароля. Теперь же отдельные приложения (например, будильник) можно сделать доступными прямо на экране блокировки. Они будут работать без авторизации со своими заранее заданными ограничениями, а все пользовательские данные тем временем останутся зашифрованными.
На устройстве с активным пофайловым шифрованием у пользователя появляется две области хранения данных приложений: зашифрованная отдельным паролем (Credential Encrypted — CE) и зашифрованная общим ключом устройства (Device Encrypted — DE). При отключении FBE обе области (CE и DE) остаются открытыми для любого приложения. При активном шифровании файлы области CE расшифровываются только после ввода пользовательского пароля. Файлы DE могут быть расшифрованы сразу после загрузки. Заодно раздельные пароли на каждый аккаунт позволяют создавать на одном устройстве несколько изолированных пользовательских учеток — например, для детей и ведущих себя подобно детям сотрудников.
Шифрование области CE происходит по алгоритму AES, но уже в другом режиме — XTS. Он разрабатывался специально для шифрования на блочных устройствах и не имеет типичных для режима CBC уязвимостей. В частности, XTS не позволяет определить точку изменения данных, не подвержен утечке данных, устойчив к атакам подмены и перемещения.
С другой стороны, FBE уязвим к side channel атакам, так как, несмотря на шифрование файлов и их имен, он оставляет открытыми метаданные, что можно использовать для выяснения типа хранимой информации и идентификации пользователя устройства.
Выводы
У встроенных в Android систем шифрования есть существенные недостатки. Они уязвимы к классическим видам атак и приводят к заметному снижению производительности на многих устройствах. Однако лучше использовать их, чем хранить приватные данные в открытом виде или доверять сторонним приложениям, не прошедшим аудит. В следующей статье мы поговорим о том, как сберечь свои данные на карте памяти, и о тех приложениях, которые хорошо справляются с этой задачей.