ARM TrustZone: как сделать Linux безопаснее
Меня зовут Андрей Лукин, я Senior Linux Kernel Developer в GlobalLogic. Тема, которую затрону сегодня, довольно обширная, и здесь хочу лишь описать основную идею технологии; те базовые кирпичики, на которых строится техника защиты. А за более подробным рассказом приходите на Root Linux Conference 18 марта в КВЦ «Парковый».
Говорят, что уровень секьюрности системы — это уровень паранойи разработчика. Или, если по-научному, система защищена настолько, насколько защищено самое слабое её звено.
Согласно статистике, доля Linux на персональных компьютерах и ноутбуках в мире едва ли достигает 6%. Но сталкиваемся мы с этой операционной системой, на самом деле, намного чаще. Linux повсеместно используется в серверах, мобильных устройствах, разнообразных embedded-решениях от промышленных агрегатов до бытовой электроники и автомобилей. При этом, не секрет, что Linux не является защищенной операционной системой, в частности, по требованиям американской Orange book (она же The Common Criteria for Information Technology Security Evaluation). То же наличие в системе суперюзера, которому позволено всё, является серьёзным недочётом. Некоторые попытки структурировать защитные механизмы предпринимаются постоянно, например SELinux (Security Enhanced Linux). Но это чисто программный подход, со всеми достоинствами и недостатками. По-хорошему, необходимо комплексное решение. В этой статье я решил сосредоточиться на технологии защиты для ARM-процессоров, поскольку невозможно объять необъятное ещё и в рамках одной публикации.
ARM-платформа стала очень популярной с распространением мобильных устройств; в то же время возросла и стоимость данных для защиты. С повсеместным переводом всего и вся в онлайн — платежей, банкинга, продаж контента — хакеры стали готовы тратить всё большие и большие деньги на подготовку и проведение атак. Никто не гнушается реверс-инжиниринга прошивок, загрузчиков и даже вмешательств в железо. Лакомый кусочек — найти так называемую атаку на целое поколение или даже класс устройств (например, рутование айфонов или взлом игровых приставок Sony PlayStation 4). И если сам процесс взлома может потребовать относительно много времени на исследование, большого опыта и, возможно, дорогостоящих инструментов, включая даже электронный микроскоп, то эксплуатация найденной уязвимости, как правило, не требует серьёзных усилий. Вспомнить тот же Pegasus, который по клику на ссылку, по сути, удалённо рутовал айфон и делал, что хотел на устройстве.
В попытке защититься или хотя бы создать изолированный от всей остальной системы доверенный островок была спроектирована технология — набор компонентов и подход к построению системы — под общим названием ARM TrustZone®.
Разделение миров
В основе концепции ARM TrustZone лежит разделение на уровне аппаратуры среды выполнения на защищенную и незащищенную, далее Secure World (trusted, доверенный мир) и Normal World (non-trusted, недоверенный мир). Причём Normal World (NWd) не имеет доступа к Secure World (SWd), тогда как последний может достучаться куда угодно. Этот подход затрагивает не только процессор, но и память, транзакции на шинах, прерывания, периферийные устройства в рамках System-on-a-Chip (SoC) и, в том числе, программное обеспечение.
Для удобства введем терминологию: Rich OS — полнофункциональная операционная система работающая в Normal World, Secure OS — доверенная операционная система работающая в Secure World и ограниченная в функционале ради безопасности, Trustlet — приложение запущенное в Secure OS, которое может быть предоставлено сторонними разработчиками. TEE — это Trusted Execution Environments, совокупность аппаратных (TrustZone) и программных (Secure OS + приложения) средств обеспечения безопасности критически важных компонентов.
Так что же из себя представляют эти миры?
По большому счету, разницы особой нет. В обоих есть все возможные режимы процессоров (supervisor, user, data abort и т.д.) исключая monitor mode, который всегда secure. Оба могут использовать все регистры, аппаратные блоки SoC. Но SWd может в runtime закрыть от NWd устройства на шине с помощью контроллера TZPC, или куски памяти с помощью контроллера TZASC. Соответственно, если мы обеспечиваем загрузку нашего доверенного кода в Secure World, то он там может выполняться независимо и защищенно от NWd.
Разделение миров
Процедура загрузки и разделения миров обычно выглядит так:
Процессор стартует в режиме монитора, то есть находится в Secure World, и инициирует загрузку так называемой Secure OS, которая будет основой нашего Trusted Execution Environment. Она делает всю необходимую секьюрную конфигурацию системы. Например, она закрывает сканер отпечатков пальцев и часть оперативной памяти от доступа из Normal World. После этого инициируется переход в Normal World, где уже другой загрузчик, например GRUB, запускает Rich OS (Linux/Android) как обычно. Теперь, если Linux захочет проверить отпечаток пальца, он обязан будет отправлять запрос в SWd с помощью команды процессора SMC (Secure Monitor Call) и TEE сможет проверить легитимность этого запроса.
Таким образом, построение Secure World все равно ложится на плечи программиста. Если ничего специально не предпринимать и загрузить Linux «как есть», он будет выполняться в SWd как ни в чём ни бывало, так как никто не производил процедуру «разделения миров» на старте системы.
ARM TrustZone — замена TPM?
Так что же мы можем сделать, находясь в TEE? Как минимум всё то, что обычно возлагается на Trusted Platform Module (TPM). Речь идет о защищённом хранении данных в зашифрованном виде, генерации ключей на основе базового и проверке подписей. Но в любом случае, это не полноценная замена, так как в ARM TrustZone не используются такие специальные аппаратные средства противодействия как «хитрая» топология слоёв микросхемы, шифрование данных на шинах и т.д. Защита здесь лишь та, что получается автоматически, так как аппаратные модули встроены в SoC. Но это же является и преимуществом, поскольку они могут работать на полной скорости системы и защищать каждый компонент SoC.
Тогда зачем это всё нужно?
Классические примеры использования — это защита электронных платежей, проприетарного видео/аудио контента, аутентификация всевозможных данных.
Посмотрим, например, последовательность проверки отпечатка пальца пользователя:
- Android Lockscreen обратится в демон keystore;
- Тот, в свою очередь, вызовет keymaster HAL, и при наличии TrustZone обращение пойдёт именно туда;
- Библиотека обратится к драйверу доступа в TrustZone через соответствующий демон; Вызов TrustZone
- Драйвер же имеет возможность сделать SMC вызов, в отличие от кода, работающего в user mode процессора;
- Процессор перейдёт в режим Monitor и передаст управление Secure OS;
- Та, в свою очередь, запустит соответствующий Trustlet, который будет работать со сканером напрямую, может запросить эталоны отпечатков пальцев из защищённого хранилища и т.д. А в конце концов аутентифицирует пользователя (или нет) для Rish OS. При этом Normal world не может вмешиваться в процесс, так как все необходимые ресурсы (модуль сканера, память) аппаратно закрыты от него.
Новые возможности
Как следствие работы аппаратных компонентов TrustZone на высокой скорости, появляется возможность постоянного runtime-контроля целостности ядра Linux. Грубо говоря, можно регулярно вычислять хэш кода ядра и сверять его с эталонным. Это становится применимым в продакшне, поскольку может быть выполнено очень быстро и незаметно для пользователя.
Более того, мы можем верифицировать не только статический код, но и загружаемые библиотеки, таблицы виртуальных указателей, указатели возврата в стеке и т.д. Есть даже свеженький white paper от Qualcomm с подробностями аппаратной поддержки верификации указателей.
Будущее рядом?
Так что, нужно срочно переводить критический к безопасности код в Trustlets и запускать в TrustZone? Хорошо бы, но пока ещё наличествует огромный зоопарк реализаций Secure OS и всей инфраструктуры для неё. Samsung предлагает своё решение, Qualcomm своё, Renesas опирается на открытые коды OP-TEE, консорциум GlobalPlatform пытается как-то всё систематизировать и выдать спецификацию на API, есть сторонние разработчики вроде Trustonic Mobicore. В итоге, сделать универсальное решение, например, для множества телефонов, не представляется возможным, если ты не сам вендор. Да и корпорациям приходится учитывать разнообразие своих же платформ. Поэтому старый добрый white box ещё пригодится до тех пор, пока Global Platform не отшлифует свою спецификацию или открытый код OP-TEE не станет стандартом де факто.
Но в любом случае радостно, что подходы к обеспечению безопасности становятся комплексными и охватывают всю большую часть системы, в том числе и аппаратные модули. Причем мы получаем недостижимую ранее гибкость программного подхода с надежной защитой со стороны «железа». Можно не ограничиваться предустановленным на устройство набором функций, а программно и безопасно обновлять систему со временем. А проблемы совместимости так или иначе со временем будут решены, надеюсь, не без помощи open-source.