Технология SMT позволяет украсть криптографические ключи

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

13 мая на конференции BSDCan в Оттаве выступил с сообщением Колин Персиваль, продемонстрировавший, как непривилегированный пользователь сервера, работающего с AES-ключами, может эти ключи украсть. Это оказывается возможным, если в качестве процессора в сервере используется Pentium 4/Xeon с включенной поддержкой HyperThreading. И возможность эта появляется именно из-за наличия HT, не зависит от используемой операционной системы и не связана с ошибками в ПО.

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

Собственно, угрозы данного типа не новы. Они носят более общий характер и связаны с некоторыми особенностями современных компьютерных архитектур. Просто для Pentium 4/Xeon с поддержкой HT были написаны конкретные коды, демонстрирующие, как при работе с OpenSSL в многопользовательской среде можно украсть криптографический ключ, а соответствующая информация стала доступной в Internet. Вообще же данный тип криптографических атак, основанных на тонких замерах времени выполнения, изучался достаточно давно (насколько известно, с середины 90-х годов), однако «широкая компьютерная общественность» про это слышала мало. В ноябре 2004 года появилась работа Даниэля Бернштейна из Чикаг?ского университета, посвященная атакам на AES, которые использовали замеры времени, связанного с обращением в кэш-память. В качестве иллюстрации Бернштейн показал, как «незаконно» получить AES-ключ при работе с OpenSSL на платформе Pentium III, отметив, что аналогичную процедуру можно проделать и с другими процессорами, например AMD Athlon, IBM PowerPC RS64 IV и Sun UltraSPARC III. Источником проблемы в этом случае являются изменяющиеся (неодинаковые) времена выполнения отдельных функций, применяемых для быстрой работы с AES.

Схожая проблема, вероятно, возникнет на любом современном микропроцессоре, и, чтобы от нее избавить?ся, желательно иметь высокопроизводительный программ?ный инструментарий для AES с постоянным временем выполнения. Однако разработка такого инструментария очень сложна: постоянные времена выполнения сегодня достигаются только при работе на относительно медленных алгоритмах. В качестве возможного выхода Бернштейн, как и ряд других специалистов, предложил разработчикам процессоров включать в набор команд специальную команду для работы с AES, что способно дать практически постоянное время выполнения.

Что же касается проблем с HT, то группа норвежских специалистов еще в марте сообщила, что они в течение одной минуты смогли установить 45 из 128 разрядов AES-ключа, но детали их атаки, насколько известно, не раскрывались. Норвежцы предложили попросту отключать HT.

Но вернемся к нашумевшему сообщению Персиваля. Предложенная им атака обращена на микропроцессоры, поддерживающие симметричную многонитевую обработку (Symmetrical MultiThreading, SMT) и использующие общую для нитей кэш-память. Разработкой подобных микроархитектур занималась не только Intel — поддержка SMT имеется, например, в Power5. Так или иначе, Персиваль разработал конкретные коды и испытал их на процессоре Pentium 4 с поддержкой HT в среде FreeBSD. По его мнению, разделяемый между нитями кэш более уязвим с точки зрения криптографических атак, использующих замеры времени, связанного с обращением в кэш-память.

Итак, Персивалю удалось решить задачу RSA-факторизации. Что же делать? Сам Персиваль предлагает разработчикам микропроцессоров с SMT запретить совместное использование кэша, разбив его на части, либо модифицировать стратегию вытеснения из кэша. Разработчики операционных систем могут запретить SMT или определенным образом модифицировать в ядре планировщик процессов. Возможны также модификации криптографических библиотек.

Общим методом борьбы с атаками, основанными на измерении времени доступа в кэш, может стать запрещение использования в непривилегированном режиме команд замера числа тактов наподобие RDTSC для х86, которые нужны для точного замера интервалов времени. Однако это нехорошо, в частности, потому, что эти команды широко используются при профилировании программ.

В практическом плане очень большой опасности эта проблема не создает, поскольку для атаки требуется сначала войти на сервер в качестве пользователя. Можно организовать работу так, чтобы не иметь пользователей на SSL- и Web-серверах, кроме root, nobody, apache и т. п. Впрочем, простейший выход на ближайшее время — вообще отключить HT (например, в BIOS). Это, как правило, не страшно — выигрыш за счет HT на большинстве приложений невелик. Выигрыш от HT может быть, например, при работе с базами данных. Некоторые приложения в многопользовательской среде даже проигрывают от использования HT, и этот режим могли уже отключить.


Каналы Персиваля

Объяснение того, как организована атака Персиваля, предполагает доскональное знакомство с алгоритмами реализации стандарта AES. Опустив рассмотрение этих деталей, остановимся на кратком описании предложенного им способа коммуникаций между двумя независимыми нитями, которые, казалось бы, вообще никак не могут обмениваться между собой информацией.

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

Если каждый из процессов требует больше половины оперативной памяти сервера, а операционная система использует LRU-стратегию вытеснения страниц, то, чтобы передать бит «1», «троянский» процесс читает все свое адресное пространство, вытесняя чужие страницы на диск, а чтобы передать «0» — проводит то же время за доступом в одну и ту же страницу памяти. «Шпионский» же процесс периодически замеряет время, необходимое на считывание всего своего адресного пространства, и, если «троянский» процесс посылал «1», то время считывания будет больше за счет обращения к страницам на диске.

Хотя пропускная способность такого канала очень низка, это показывает, как общий «кэш» (для файла подкачки им является оперативная память) можно использовать для коммуникаций между процессами. В случае кэша данных первого уровня, разделяемого нитями в 2,8-гигагерцевом процессоре Pentium 4/HT, можно образовать канал с пропускной способностью 400 Кбайт/с.

Для этого можно использовать вытеснение из кэша одним процессом данных другого процесса (напомним, что нити не имеют общих данных). Нужно учесть, что кэш данных первого уровня состоит из 128 строк длиной по 64 байт, организованных в 32 четырехканальных ассоциативных набора, и каждый из этих наборов становится аналогичным описанной выше схемы. Персиваль подробно описал, как заставить вытеснять из кэша данных первого уровня строки чужого процесса, и использовал это в своих кодах.

С использованием кэша второго уровня, хотя и более сложным путем, можно организовать канал с пропускной способностью 100 Кбайт/с. Несмотря на более низкую пропускную способность, для процессоров без поддержки SMT это представляет определенное значение: при смене контекста в более емком кэше второго уровня могут остаться интересные для «шпионского» процесса данные.